@coldsmirk/ledger-mantine 0.1.0 → 0.2.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":"index.cjs","names":["createSafeContext","ActionIcon","useRef","useCallback","PointerActivationConstraints","PointerSensor","AutoScroller","Cursor","PreventSelection","useState","useRef","useMemo","DragDropProvider","Portal","VisuallyHidden","useDraggable","Tooltip","ActionIcon","Checkbox","Radio","useProps","Popover","move","DragDropProvider","Group","Text","Button","useSortable","Tooltip","ActionIcon","Checkbox","NumberInput","SegmentedControl","Center","VisuallyHidden","useId","Group","Text","Select","Pagination","useProps","useProps","useState","useDebouncedCallback","TextInput","CloseButton","useProps","Group","Text","Button","useReducer","Loader","useRef","useMemo","useState","useRef","useState","useRef","useCallback","ActionIcon","flexRender","useReducer","Loader","MantineTable","memo","Skeleton","Button","useMemo","useCallback","useVirtualizer","MantineTable","flexRender","Popover","ActionIcon","Stack","Group","CloseButton","MultiSelect","Select","useState","useDebouncedCallback","TextInput","NumberInput","DatePicker","Button","useState","useRef","useState","useRef","MantineTable","flexRender","Tooltip","useState","useCallback","useMemo","filterFn_arrHas","filterFn_arrIncludes","filterFn_arrIncludesAll","filterFn_arrIncludesSome","filterFn_between","filterFn_betweenInclusive","filterFn_empty","filterFn_endsWith","filterFn_equals","filterFn_equalsString","filterFn_equalsStringSensitive","filterFn_greaterThan","filterFn_greaterThanOrEqualTo","filterFn_inDateRange","filterFn_inNumberRange","filterFn_includesString","filterFn_includesStringSensitive","filterFn_lessThan","filterFn_lessThanOrEqualTo","filterFn_notEmpty","filterFn_startsWith","filterFn_weakEquals","tableFeatures","createExpandedRowModel","createFacetedMinMaxValues","createFacetedRowModel","createFacetedUniqueValues","createFilteredRowModel","createGroupedRowModel","createPaginatedRowModel","createSortedRowModel","aggregationFn_count","aggregationFn_extent","aggregationFn_first","aggregationFn_last","aggregationFn_max","aggregationFn_mean","aggregationFn_median","aggregationFn_min","aggregationFn_sum","aggregationFn_unique","aggregationFn_uniqueCount","sortFn_alphanumeric","sortFn_alphanumericCaseSensitive","sortFn_basic","sortFn_datetime","sortFn_text","sortFn_textCaseSensitive","tanStackCreateColumnHelper","useRef","useRef","useState","useCallback","useMemo","EMPTY","useRef","useCallback","useMemo","useRef","useCallback","useMemo","useMemo","useState","useRef","useCallback","useMemo","useRef","useState","useCallback","useMemo","useUncontrolled","useRef","useCallback","functionalUpdate","useState","useRef","useCallback","functionalUpdate","useMemo","useTable","useMantineTheme","useMantineClassNamesPrefix","useMantineWithStaticClasses","useMantineIsHeadless","useMantineStylesTransform","useRef","createVarsResolver","getThemeColor","useProps","genericFactory","useStyles","useMemo","useRef","useState","useCallback","useId","Box","VisuallyHidden","MantineTable","ScrollArea","EmptyState","Button","LoadingOverlay","TextInput","NumberInput","Select","Checkbox"],"sources":["../src/context.ts","../src/expander.tsx","../src/filter-fns.ts","../src/utils.ts","../src/row-reorder.tsx","../src/selection.tsx","../src/build-columns.tsx","../src/column-order.ts","../src/icons.tsx","../src/labels.ts","../src/columns-panel.tsx","../src/csv.ts","../src/element-props.ts","../src/env.ts","../src/ledger-commands.ts","../src/pagination-bar.tsx","../src/search.tsx","../src/selection-bar.tsx","../src/edit-meta.ts","../src/cell-editor.tsx","../src/pinning.ts","../src/truncate.ts","../src/use-column-window.ts","../src/use-pinned-row-offsets.ts","../src/table-body.tsx","../src/table-footer.tsx","../src/autosize-column.ts","../src/filter-popover.tsx","../src/use-column-reorder.ts","../src/use-column-resize.ts","../src/table-header.tsx","../src/use-column-widths.ts","../src/ledger-features.ts","../src/persist.ts","../src/toggle-fns.ts","../src/use-cell-editing.ts","../src/use-committed-table.ts","../src/use-instant-editing.ts","../src/use-responsive-columns.ts","../src/use-row-commands.ts","../src/use-row-editing.ts","../src/use-slice.ts","../src/use-data-table.ts","../src/use-styles-revision.ts","../src/data-table.tsx","../src/editors.tsx"],"sourcesContent":["import type { GetStylesApi, TableTrProps } from \"@mantine/core\";\nimport type { ColumnFiltersState } from \"@tanstack/react-table\";\nimport type { KeyboardEvent, MouseEvent } from \"react\";\n\nimport type { DataTableFactory } from \"./data-table\";\nimport type { DataTableElementProps } from \"./element-props\";\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { RowReorderKeyboard } from \"./row-reorder\";\nimport type { HeaderGroup, Row } from \"./types\";\nimport type { LedgerExpansionController, LedgerSelectionController } from \"./use-row-commands\";\n\n/**\n * Internal context for everything rendered inside the <DataTable> tree. The data generic is\n * erased at this boundary — the single deliberate erasure in the package, mirroring the family\n * convention (one documented boundary instead of casts scattered through the tree). Cells and\n * filter popovers receive their strongly-typed TanStack objects (`Row<TData>`, `Column<TData>`)\n * directly as props; the context only carries table-wide plumbing.\n *\n * The table instance itself is deliberately NOT here. Anything below that rendered without the\n * root rendering with it — a filter popover redrawing from its own state, a row the virtualizer\n * put back — would read whatever pass wrote the instance last, and v9 writes the shared core\n * during render, a pass React discarded included. So the few table-wide facts the tree needs\n * arrive as their own fields, each stable enough to keep the context value itself stable\n * (docs/architecture.md).\n */\nimport { createSafeContext } from \"@mantine/core\";\n\nexport interface DataTableContextValue {\n /**\n * Stable per-instance id — what the single-select radios group themselves by.\n */\n instanceId: string;\n getStyles: GetStylesApi<DataTableFactory>;\n labels: DataTableLabels;\n icons: DataTableIcons;\n filterMode: \"client\" | \"server\";\n /**\n * Row virtualization active — rows must then carry aria-rowindex (header rows included).\n */\n virtualizedRows: boolean;\n /**\n * The header region renders — so header rows count toward every `aria-rowindex`.\n */\n withColumnHeaders: boolean;\n /**\n * The active-row slice, as its own two facts: the switch, and the stable setter that moves it.\n * Rows are memoized, so both have to reach them through the context — a prop that only\n * TableBody knows about would leave a row that did not re-render answering with the switch as\n * it stood when it last did.\n */\n activeRowEnabled: boolean;\n setActiveRow?: (rowId: string) => void;\n /**\n * The row-ordering keyboard session (docs/rows.md#row-ordering) — the handle cells drive it,\n * `DataTable` owns it. The handlers are stable; only presence changes with the gate.\n */\n rowReorderKeyboard?: RowReorderKeyboard;\n /**\n * The row-state toggles the injected columns drive. Stable for the life of the instance, so a\n * cell reaches one without the route deciding anything (`use-row-commands.ts`).\n */\n selection?: LedgerSelectionController;\n expansion?: LedgerExpansionController;\n /**\n * Notification of every `columnFilters` set attempt, no-ops included — what a debounced filter\n * control listens to so an external reset reaches its own local value. Stable per instance.\n */\n subscribeColumnFilters?: (listener: (value: ColumnFiltersState) => void) => () => void;\n onRowClick?: (row: Row<any>, event: MouseEvent) => void;\n onRowActivate?: (row: Row<any>, event: MouseEvent | KeyboardEvent) => void;\n onRowDoubleClick?: (row: Row<any>, event: MouseEvent) => void;\n onRowContextMenu?: (row: Row<any>, event: MouseEvent) => void;\n rowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, Row<any>>;\n headerRowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, HeaderGroup<any>>;\n footerRowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, HeaderGroup<any>>;\n}\n\nexport const [DataTableProvider, useDataTableContext] = createSafeContext<DataTableContextValue>(\n \"DataTable parts must be rendered inside <DataTable>\"\n);\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Row, TableInstance } from \"./types\";\n\n/**\n * The injected expander column: a per-row chevron (detail panels and sub-row trees share it)\n * and an expand-all header affordance for trees. Clicks never reach `onRowClick`.\n */\nimport { ActionIcon } from \"@mantine/core\";\n\nimport { useDataTableContext } from \"./context\";\n\nexport function ExpanderHeaderCell<TData extends RowData>({ table }: { table: TableInstance<TData> }) {\n const {\n labels,\n icons,\n expansion\n } = useDataTableContext();\n\n // Expand-all only makes sense over a tree; a master–detail table opens panels one at a time.\n if (!table.options.getSubRows) {\n return null;\n }\n\n const allExpanded = table.getIsAllRowsExpanded();\n const canSomeExpand = table.getCanSomeRowsExpand();\n\n return (\n <ActionIcon\n aria-label={allExpanded ? labels.collapseAll : labels.expandAll}\n data-expanded={allExpanded || undefined}\n size=\"sm\"\n variant=\"subtle\"\n onClick={event => {\n event.stopPropagation();\n expansion?.toggleAll(!allExpanded, canSomeExpand);\n }}\n >\n <icons.expandRow />\n </ActionIcon>\n );\n}\n\nexport function ExpanderCell<TData extends RowData>({ row }: { row: Row<TData> }) {\n const {\n labels,\n icons,\n expansion\n } = useDataTableContext();\n const canExpand = row.getCanExpand();\n\n if (!canExpand) {\n return null;\n }\n\n const expanded = row.getIsExpanded();\n\n return (\n <ActionIcon\n aria-expanded={expanded}\n aria-label={expanded ? labels.collapseRow : labels.expandRow}\n data-expanded={expanded || undefined}\n size=\"sm\"\n variant=\"subtle\"\n onClick={event => {\n event.stopPropagation();\n expansion?.toggle(row.id, expanded, canExpand);\n }}\n >\n <icons.expandRow />\n </ActionIcon>\n );\n}\n","/**\n * The mapping from `meta.filter` variants to TanStack filter functions, plus the one custom\n * function the built-ins lack. A column keeps any `filterFn` it declares itself — the variant\n * mapping only fills the gap (docs/filtering.md).\n *\n * The functions are registered on the canonical feature set (`ledger-features.ts`), which is\n * what makes their ids valid `filterFn` strings for consumers — v9 registry slots replace v8's\n * `FilterFns` declaration merging.\n */\nimport type { FilterFn } from \"@tanstack/react-table\";\n\nimport type { DataTableFilterVariant } from \"./types\";\n\nexport type DateRangeFilterValue = [string | null, string | null];\n\nconst DATE_ONLY = /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})$/;\n\nfunction localDayStart(value: string): number | undefined {\n const match = DATE_ONLY.exec(value);\n\n if (!match) {\n return undefined;\n }\n\n const year = Number(match.groups?.year);\n const month = Number(match.groups?.month) - 1;\n const day = Number(match.groups?.day);\n const date = new Date(year, month, day);\n\n if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {\n return undefined;\n }\n\n return date.getTime();\n}\n\nfunction dateValueTime(value: string | number | Date): number {\n if (typeof value === \"string\") {\n const localTime = localDayStart(value);\n\n if (localTime !== undefined) {\n return localTime;\n }\n }\n\n return new Date(value).getTime();\n}\n\nfunction parsedTime(value: string): number | undefined {\n const time = new Date(value).getTime();\n\n return Number.isNaN(time) ? undefined : time;\n}\n\n/**\n * Inclusive [from, to] match over anything `new Date()` can parse. Date-only values and bounds\n * use local calendar days; their upper bound is the next local midnight so DST days stay exact.\n * Full timestamp bounds retain their exact instant.\n */\nconst dateRange: FilterFn<any, any> = (row, columnId, filterValue: DateRangeFilterValue) => {\n const raw = row.getValue(columnId);\n\n if (raw === null || raw === undefined || raw === \"\") {\n return false;\n }\n\n if (!Array.isArray(filterValue)) {\n return false;\n }\n\n const time = dateValueTime(raw as string | number | Date);\n\n if (Number.isNaN(time)) {\n return false;\n }\n\n const [from, to] = filterValue;\n\n if (from) {\n const fromTime = localDayStart(from) ?? parsedTime(from);\n\n if (fromTime !== undefined && time < fromTime) {\n return false;\n }\n }\n\n if (to) {\n const localToTime = localDayStart(to);\n\n if (localToTime === undefined) {\n const toTime = parsedTime(to);\n\n if (toTime !== undefined && time > toTime) {\n return false;\n }\n } else {\n const nextDay = new Date(localToTime);\n nextDay.setDate(nextDay.getDate() + 1);\n\n if (time >= nextDay.getTime()) {\n return false;\n }\n }\n }\n\n return true;\n};\n\ndateRange.autoRemove = (value: DateRangeFilterValue | undefined) => !value || (!value[0] && !value[1]);\n\n/**\n * Strict set membership for the multi-select variant. TanStack's `arrIncludesSome` expects an\n * array row value and degrades to substring matching on scalars (\"active\" would match\n * \"inactive\") — the variant's semantics are exact membership for scalar and array cells.\n */\nconst oneOf: FilterFn<any, any> = (row, columnId, filterValue: string[]) => {\n const raw = row.getValue(columnId);\n\n if (raw === null || raw === undefined || !Array.isArray(filterValue)) {\n return false;\n }\n\n const values = Array.isArray(raw) ? raw : [raw];\n\n return values.some(value => value !== null && value !== undefined && filterValue.includes(String(value)));\n};\n\noneOf.autoRemove = (value: string[] | undefined) => !value || value.length === 0;\n\nexport const ledgerFilterFns = {\n \"ledger-date-range\": dateRange,\n \"ledger-one-of\": oneOf\n};\n\nexport type LedgerFilterFnId\n = | \"includesString\"\n | \"equalsString\"\n | \"inNumberRange\"\n | \"ledger-one-of\"\n | \"ledger-date-range\";\n\n/**\n * TanStack built-in (or ledger-registered) filter function id per filter variant.\n */\nexport const filterFnByVariant: Record<DataTableFilterVariant, LedgerFilterFnId> = {\n text: \"includesString\",\n select: \"equalsString\",\n \"multi-select\": \"ledger-one-of\",\n range: \"inNumberRange\",\n \"date-range\": \"ledger-date-range\"\n};\n","import { useCallback, useInsertionEffect, useRef } from \"react\";\n\nconst CSS_SAFE_CHARACTER = /^[a-z0-9-]$/i;\n\n/**\n * Column ids are consumer-supplied; CSS custom property names must stay ident-safe.\n */\nfunction cssSafeColumnId(columnId: string): string {\n let encoded = \"\";\n\n for (const character of columnId) {\n encoded += CSS_SAFE_CHARACTER.test(character)\n ? character\n : `_${character.codePointAt(0)!.toString(16)}_`;\n }\n\n // TanStack column ids are normally non-empty, but keeping the encoder total avoids emitting an\n // invalid custom-property suffix if a custom feature supplies an empty id.\n return encoded || \"_empty_\";\n}\n\nexport function columnWidthVar(columnId: string): string {\n return `--ledger-col-width-${cssSafeColumnId(columnId)}`;\n}\n\n/**\n * Pinned offset variables — written table-level with the width vars, referenced by cells.\n */\nexport function columnStartVar(columnId: string): string {\n return `--ledger-col-start-${cssSafeColumnId(columnId)}`;\n}\n\nexport function columnAfterVar(columnId: string): string {\n return `--ledger-col-after-${cssSafeColumnId(columnId)}`;\n}\n\nexport function toPx(value: number | string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\n/**\n * Whether a commit handler answered with a promise. Editing commits are `boolean | Promise<boolean>`\n * throughout, and both the session and the editors have to tell the two apart.\n */\nexport function isPromiseLike<T>(value: T | PromiseLike<T>): value is PromiseLike<T> {\n return typeof value === \"object\" && value !== null && \"then\" in value && typeof value.then === \"function\";\n}\n\n/**\n * Stable-identity event callback (the classic useEvent shape) for handlers stored in table meta.\n *\n * Two shapes, because most call sites wrap a handler that always exists: those keep the result\n * type they wrote, while wrapping a consumer's optional prop widens it with the `undefined` a\n * missing handler answers with. One overload each, so a caller never has to assert the widening\n * away — the assertions that used to do it were the only thing standing between an internal\n * session's `boolean | Promise<boolean>` contract and the type system agreeing with it.\n */\nexport function useEventCallback<Args extends unknown[], Result>(\n handler: (...args: Args) => Result\n): (...args: Args) => Result;\nexport function useEventCallback<Args extends unknown[], Result>(\n handler: ((...args: Args) => Result) | undefined\n): (...args: Args) => Result | undefined;\n\nexport function useEventCallback<Args extends unknown[], Result>(\n handler: ((...args: Args) => Result) | undefined\n): (...args: Args) => Result | undefined {\n const handlerRef = useRef(handler);\n\n useInsertionEffect(() => {\n handlerRef.current = handler;\n });\n\n return useCallback((...args: Args) => handlerRef.current?.(...args), []);\n}\n","import type { PointerSensorOptions } from \"@dnd-kit/dom\";\nimport type { DragEndEvent, DragMoveEvent, DragStartEvent } from \"@dnd-kit/react\";\n/**\n * Row drag reordering (docs/rows.md#row-ordering). Row order IS data order — there is no order\n * state — so ledger owns the interaction (the handle column, the session, the drop indicator,\n * the announcements) and hands the completed move to `onRowReorder`; the application reorders\n * `data`.\n *\n * Two input channels feed one session:\n *\n * - Pointer drags ride dnd-kit — the columns panel's dependency — for what is expensive to\n * hand-roll: activation constraints, edge auto-scrolling, cursor and selection suppression.\n * The drop target is ledger's own math over the rendered rows, not droppables: per-row\n * droppables would re-register on every virtualizer round-trip, and the sortable plugin's\n * optimistic DOM moves would break the one-`<tr>`-per-virtual-item invariant. The Feedback\n * and Accessibility plugins stay out for the same reason — the row ghost and the live\n * region are ledger's, fed from `labels`.\n * - The keyboard steps the insertion index directly (Space lifts, ↑/↓ move, Home/End jump,\n * Space drops, Escape cancels; blur abandons) — exact positions, not synthetic pixels.\n *\n * Session state lives up in `DataTable`, so the affected rows re-render through their own\n * memoized props; the row ghost and the live region are written imperatively — a pointer\n * move never re-renders the table.\n */\nimport type { RowData } from \"@tanstack/react-table\";\nimport type { KeyboardEvent, ReactNode, RefObject } from \"react\";\n\nimport type { DataTableRowReorder, Row, TableInstance } from \"./types\";\n\nimport { AutoScroller, Cursor, PointerActivationConstraints, PreventSelection } from \"@dnd-kit/dom\";\nimport {\n DragDropProvider,\n PointerSensor,\n useDraggable\n\n} from \"@dnd-kit/react\";\nimport { ActionIcon, Portal, Tooltip, VisuallyHidden } from \"@mantine/core\";\nimport { useMemo, useRef, useState } from \"react\";\n\nimport { useDataTableContext } from \"./context\";\nimport { useEventCallback } from \"./utils\";\n\n/**\n * The 5px house threshold (use-column-reorder.ts) keeps a plain click from lifting the row —\n * a lift is announced, and a click should say nothing. Touch keeps the press-and-hold delay\n * that separates dragging from scrolling.\n */\nconst activationConstraints: PointerSensorOptions[\"activationConstraints\"] = event => event.pointerType === \"touch\"\n ? [new PointerActivationConstraints.Delay({ value: 250, tolerance: 5 })]\n : [new PointerActivationConstraints.Distance({ value: 5 })];\n\nexport const ROW_REORDER_SENSORS = [PointerSensor.configure({ activationConstraints })];\nexport const ROW_REORDER_PLUGINS = [AutoScroller, Cursor, PreventSelection];\n\nexport interface RowReorderTarget {\n rowId: string;\n side: \"before\" | \"after\";\n}\n\n/**\n * The keyboard half of the session, handed to the handle cells through the render context. The\n * handlers are stable event callbacks; `active` reads the live session, so a handle can answer\n * \"do the keys belong to me\" in the render that draws it.\n */\nexport interface RowReorderKeyboard {\n lift: (rowId: string) => void;\n move: (delta: 1 | -1) => void;\n moveToEdge: (edge: \"start\" | \"end\") => void;\n drop: () => void;\n cancel: () => void;\n active: (rowId: string) => boolean;\n}\n\nexport interface RowReorderSession {\n /**\n * The row a live drag lifted, either channel. Rows render `data-dragging` from it.\n */\n sourceId: string | null;\n /**\n * Where the lifted row would land — `null` while the drop would change nothing. The target\n * row renders the indicator (`data-drop-side`).\n */\n target: RowReorderTarget | null;\n providerProps: {\n onDragStart: (event: DragStartEvent) => void;\n onDragMove: (event: DragMoveEvent) => void;\n onDragEnd: (event: DragEndEvent) => void;\n };\n keyboard: RowReorderKeyboard;\n /**\n * True once a pointer drag has actually moved — the overlay mounts the ghost from it, and\n * its late start is also what keeps a bare click silent.\n */\n ghostActive: boolean;\n attachGhost: (element: HTMLDivElement | null) => void;\n announcerRef: RefObject<HTMLSpanElement | null>;\n}\n\nexport interface RowReorderInput<TData extends RowData> {\n onRowReorder: ((reorder: DataTableRowReorder<TData>) => void) | undefined;\n labels: {\n rowReorderLifted: (row: string) => string;\n rowReorderTarget: (row: string, side: \"before\" | \"after\") => string;\n rowReorderDropped: (row: string) => string;\n rowReorderCanceled: string;\n };\n /**\n * The body scroll viewport — the element whose rendered `<tr>`s the pointer math reads.\n */\n viewportRef: RefObject<HTMLElement | null>;\n /**\n * The center rows of the committed display, in display order (pinned rows are not part of a\n * data-order move). Read once per lift into the session snapshot.\n */\n getCenterRows: () => Array<Row<TData>>;\n /**\n * Names a row the way the active-row announcements do — its leading visible cell.\n */\n nameRow: (row: Row<TData>) => string;\n /**\n * Keeps the keyboard target on screen, virtualized included.\n */\n scrollToRow: (rowId: string) => void;\n}\n\ninterface DragSnapshot<TData extends RowData> {\n via: \"pointer\" | \"keyboard\";\n sourceId: string;\n sourceName: string;\n fromIndex: number;\n /**\n * Keyboard stepping position in `toIndex` space; `fromIndex` means \"at rest\".\n */\n toIndex: number;\n rows: Array<Row<TData>>;\n rowsById: Map<string, Row<TData>>;\n}\n\nexport function useRowReorder<TData extends RowData>({\n onRowReorder,\n labels,\n viewportRef,\n getCenterRows,\n nameRow,\n scrollToRow\n}: RowReorderInput<TData>): RowReorderSession {\n const [sourceId, setSourceId] = useState<string | null>(null);\n const [target, setTargetState] = useState<RowReorderTarget | null>(null);\n const [ghostActive, setGhostActive] = useState(false);\n\n const snapshot = useRef<DragSnapshot<TData> | null>(null);\n const targetRef = useRef<RowReorderTarget | null>(null);\n const ghostRef = useRef<HTMLDivElement | null>(null);\n const ghostPosition = useRef({ x: 0, y: 0 });\n const ghostOrigin = useRef({ x: 0, y: 0 });\n const announcerRef = useRef<HTMLSpanElement | null>(null);\n\n const announce = useEventCallback((message: string) => {\n if (announcerRef.current) {\n announcerRef.current.textContent = message;\n }\n });\n\n /**\n * `arrayMove` semantics: the final index of the moved row once the drop lands `side` of the\n * target. `null` when the move would change nothing.\n */\n const resolveToIndex = (targetRow: Row<TData>, side: \"before\" | \"after\"): number | null => {\n const session = snapshot.current;\n\n if (!session) {\n return null;\n }\n\n const raw = targetRow.index + (side === \"after\" ? 1 : 0);\n const toIndex = raw > session.fromIndex ? raw - 1 : raw;\n\n return toIndex === session.fromIndex ? null : toIndex;\n };\n\n const setTarget = (next: RowReorderTarget | null) => {\n const { current } = targetRef;\n\n if (current?.rowId === next?.rowId && current?.side === next?.side) {\n return;\n }\n\n targetRef.current = next;\n setTargetState(next);\n\n if (next) {\n const row = snapshot.current?.rowsById.get(next.rowId);\n\n if (row) {\n announce(labels.rowReorderTarget(nameRow(row), next.side));\n }\n }\n };\n\n const begin = (via: \"pointer\" | \"keyboard\", rowId: string): DragSnapshot<TData> | null => {\n const rows = getCenterRows();\n const row = rows.find(candidate => candidate.id === rowId);\n\n if (!row) {\n return null;\n }\n\n const session: DragSnapshot<TData> = {\n via,\n sourceId: rowId,\n sourceName: nameRow(row),\n fromIndex: row.index,\n toIndex: row.index,\n rows,\n rowsById: new Map(rows.map(candidate => [candidate.id, candidate]))\n };\n snapshot.current = session;\n setSourceId(rowId);\n\n return session;\n };\n\n const finish = (canceled: boolean) => {\n const session = snapshot.current;\n const finalTarget = targetRef.current;\n\n if (session && !canceled) {\n if (finalTarget) {\n const row = session.rowsById.get(session.sourceId);\n const targetRow = session.rowsById.get(finalTarget.rowId);\n const toIndex = targetRow ? resolveToIndex(targetRow, finalTarget.side) : null;\n\n if (row && toIndex !== null) {\n onRowReorder?.({\n row,\n fromIndex: session.fromIndex,\n toIndex\n });\n }\n }\n\n announce(labels.rowReorderDropped(session.sourceName));\n } else if (session) {\n announce(labels.rowReorderCanceled);\n }\n\n snapshot.current = null;\n targetRef.current = null;\n setSourceId(null);\n setTargetState(null);\n setGhostActive(false);\n };\n\n /* ---- pointer channel (dnd-kit) ---- */\n\n const onDragStart = useEventCallback((event: DragStartEvent) => {\n const id = event.operation.source?.id;\n\n if (typeof id !== \"string\" || snapshot.current) {\n return;\n }\n\n begin(\"pointer\", id);\n });\n\n /**\n * The rendered center rows, read where they are drawn: virtualization renders a window, and\n * the rows that exist are exactly the ones a pointer can be over. Pinned rows are sticky\n * overlays of the same scroller, so a pointer inside their bands must not read as \"over the\n * row beneath\" — they bound the scan instead of joining it.\n */\n const pointerTarget = (y: number): RowReorderTarget | null => {\n const viewport = viewportRef.current;\n const session = snapshot.current;\n\n if (!viewport || !session) {\n return null;\n }\n\n const rows = viewport.querySelectorAll<HTMLTableRowElement>(\"tr[data-row-id]:not([data-pinned-row])\");\n const nearest = pointerDropEdge(rows, element => element.getBoundingClientRect(), y);\n\n if (!nearest) {\n return null;\n }\n\n const { rowId } = nearest.row.dataset;\n const row = rowId === undefined ? undefined : session.rowsById.get(rowId);\n\n if (rowId === undefined || !row || resolveToIndex(row, nearest.side) === null) {\n return null;\n }\n\n return { rowId, side: nearest.side };\n };\n\n const onDragMove = useEventCallback((event: DragMoveEvent) => {\n const session = snapshot.current;\n\n if (session?.via !== \"pointer\") {\n return;\n }\n\n const position = event.operation.position.current;\n ghostPosition.current = position;\n\n if (ghostRef.current) {\n ghostRef.current.style.transform = ghostTransform(position, ghostOrigin.current);\n }\n\n // The lift is announced here, on the first real move, so a plain click stays silent.\n if (!ghostActive) {\n setGhostActive(true);\n announce(labels.rowReorderLifted(session.sourceName));\n }\n\n setTarget(pointerTarget(position.y));\n });\n\n const onDragEnd = useEventCallback((event: DragEndEvent) => {\n if (snapshot.current?.via !== \"pointer\") {\n return;\n }\n\n finish(event.canceled);\n });\n\n /* ---- keyboard channel (index stepping) ---- */\n\n const step = (session: DragSnapshot<TData>, candidate: number) => {\n const last = session.rows.length - 1;\n const toIndex = Math.max(0, Math.min(last, candidate));\n\n if (toIndex === session.fromIndex || toIndex === session.toIndex) {\n return;\n }\n\n // Map the landing index back to the row that shows the indicator: landing below the source\n // means \"after that row\" (every row in between has shifted one up), above means \"before\".\n const row = session.rows[toIndex];\n\n if (!row) {\n return;\n }\n\n session.toIndex = toIndex;\n setTarget({ rowId: row.id, side: toIndex > session.fromIndex ? \"after\" : \"before\" });\n scrollToRow(row.id);\n };\n\n const lift = useEventCallback((rowId: string) => {\n if (snapshot.current) {\n return;\n }\n\n const session = begin(\"keyboard\", rowId);\n\n if (session) {\n announce(labels.rowReorderLifted(session.sourceName));\n }\n });\n\n const move = useEventCallback((delta: 1 | -1) => {\n const session = snapshot.current;\n\n if (session?.via !== \"keyboard\") {\n return;\n }\n\n // Skip over the at-rest position — stepping back onto it would show nothing; Escape is how\n // a lift returns home.\n let candidate = session.toIndex + delta;\n\n if (candidate === session.fromIndex) {\n candidate += delta;\n }\n\n step(session, candidate);\n });\n\n const moveToEdge = useEventCallback((edge: \"start\" | \"end\") => {\n const session = snapshot.current;\n\n if (session?.via !== \"keyboard\") {\n return;\n }\n\n step(session, edge === \"start\" ? 0 : session.rows.length - 1);\n });\n\n const drop = useEventCallback(() => {\n if (snapshot.current?.via === \"keyboard\") {\n finish(false);\n }\n });\n\n const cancel = useEventCallback(() => {\n if (snapshot.current?.via === \"keyboard\") {\n finish(true);\n }\n });\n\n const keyboardActive = useEventCallback(\n (rowId: string) => snapshot.current?.via === \"keyboard\" && snapshot.current.sourceId === rowId\n );\n\n const attachGhost = useEventCallback((element: HTMLDivElement | null) => {\n ghostRef.current = element;\n\n if (!element) {\n return;\n }\n\n // Built once per lift: the ghost is a DOM snapshot of the whole source row — the source\n // table's shell around the cloned `<tr>`, under per-column pixel widths read from the live\n // cells (the width variables live on the ledger root and cannot reach the portal) — so a\n // pointer move stays a pure transform write and no live cell ever renders twice.\n const session = snapshot.current;\n const source = session\n ? viewportRef.current?.querySelector<HTMLTableRowElement>(\n `tr[data-row-id=\"${CSS.escape(session.sourceId)}\"]`\n )\n : null;\n const sourceTable = source?.closest(\"table\");\n\n if (source && sourceTable) {\n const ghostTable = sourceTable.cloneNode(false) as HTMLTableElement;\n ghostTable.style.width = `${sourceTable.getBoundingClientRect().width}px`;\n\n const colgroup = document.createElement(\"colgroup\");\n\n for (const cell of source.cells) {\n const col = document.createElement(\"col\");\n col.style.width = `${cell.getBoundingClientRect().width}px`;\n colgroup.append(col);\n }\n\n const body = document.createElement(\"tbody\");\n const rowClone = source.cloneNode(true) as HTMLTableRowElement;\n delete rowClone.dataset.dragging;\n body.append(rowClone);\n ghostTable.append(colgroup, body);\n element.replaceChildren(ghostTable);\n\n // Anchored to where the row was lifted from, so the ghost reads as the row itself\n // coming off the table under the pointer's grab point.\n const rowRect = source.getBoundingClientRect();\n ghostOrigin.current = {\n x: rowRect.left - ghostPosition.current.x,\n y: rowRect.top - ghostPosition.current.y\n };\n }\n\n // Positioned before its first paint — a ghost that mounts at the portal origin and then\n // jumps to the pointer is exactly the drift the imperative transform exists to avoid.\n element.style.transform = ghostTransform(ghostPosition.current, ghostOrigin.current);\n });\n\n // Stable — every handler is an event callback — so the render context carrying it holds.\n const keyboard = useMemo<RowReorderKeyboard>(\n () => {\n return {\n active: keyboardActive,\n cancel,\n drop,\n lift,\n move,\n moveToEdge\n };\n },\n [keyboardActive, cancel, drop, lift, move, moveToEdge]\n );\n\n return {\n sourceId,\n target,\n providerProps: {\n onDragEnd,\n onDragMove,\n onDragStart\n },\n keyboard,\n ghostActive,\n attachGhost,\n announcerRef\n };\n}\n\n/**\n * The drop edge a pointer at `y` indicates, scanned top to bottom over the rendered rows: above\n * every row reads \"before\" the first, inside a row splits at its midline, the gap between two\n * rows belongs to the row above, and below every row reads \"after\" the last. Zero-height rows\n * never claim the pointer. Pure over `measure` — the session feeds it live rects, and reads\n * lazily so the scan still stops at the row under the pointer.\n */\nexport function pointerDropEdge<T>(\n rows: Iterable<T>,\n measure: (row: T) => { top: number; bottom: number },\n y: number\n): { row: T; side: \"before\" | \"after\" } | null {\n let nearest: { row: T; side: \"before\" | \"after\" } | null = null;\n\n for (const row of rows) {\n const { top, bottom } = measure(row);\n\n if (bottom <= top) {\n continue;\n }\n\n if (y < top) {\n nearest ??= { row, side: \"before\" };\n\n break;\n }\n\n nearest = { row, side: y < (top + bottom) / 2 ? \"before\" : \"after\" };\n\n if (y <= bottom) {\n break;\n }\n }\n\n return nearest;\n}\n\nfunction ghostTransform(\n { x, y }: { x: number; y: number },\n origin: { x: number; y: number }\n): string {\n return `translate(${Math.round(x + origin.x)}px, ${Math.round(y + origin.y)}px)`;\n}\n\n/**\n * Mounts the pointer channel around the table when the gate is on: dnd-kit's provider (context\n * for the handles' draggables), the session's handlers, and the overlay. Renders no DOM of its\n * own, so the table markup is byte-identical either way.\n */\nexport function RowReorderScope({ session, children }: { session: RowReorderSession | null; children: ReactNode }) {\n if (!session) {\n return children;\n }\n\n return (\n <DragDropProvider plugins={ROW_REORDER_PLUGINS} sensors={ROW_REORDER_SENSORS} {...session.providerProps}>\n {children}\n <RowReorderOverlay session={session} />\n </DragDropProvider>\n );\n}\n\n/**\n * The pointer ghost and the live region, portaled out of the ARIA table (a `role=\"table\"` may\n * only own rows; a fixed-position ghost inside the scroller would clip and shear under sticky\n * transforms). The ghost's content is the row snapshot `attachGhost` clones in, and it is\n * `aria-hidden`: the live region already narrates the drag.\n */\nfunction RowReorderOverlay({ session }: { session: RowReorderSession }) {\n const { getStyles } = useDataTableContext();\n\n return (\n <Portal>\n <VisuallyHidden ref={session.announcerRef} aria-live=\"polite\" role=\"status\" />\n {session.ghostActive && <div ref={session.attachGhost} aria-hidden {...getStyles(\"rowDragOverlay\")} />}\n </Portal>\n );\n}\n\n/**\n * The injected handle cell. The pointer half hands the button to dnd-kit as the draggable;\n * the keyboard half drives the session's index stepping directly. Disabled — visually and for\n * both channels — while something else controls the visible order, with the tooltip saying\n * why (docs/rows.md#row-ordering).\n */\nexport function RowDragCell<TData extends RowData>({ row, table }: { row: Row<TData>; table: TableInstance<TData> }) {\n const {\n labels,\n icons,\n rowReorderKeyboard\n } = useDataTableContext();\n const orderable = table.options.meta?.ledger?.rowOrdering.orderable === true;\n\n // No Feedback plugin runs (ROW_REORDER_PLUGINS): the handle stays put and the session's own\n // row ghost is the drag's visual.\n const { ref, isDragSource } = useDraggable({\n id: row.id,\n disabled: !orderable\n });\n\n const lifted = rowReorderKeyboard?.active(row.id) === true;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const keyboard = rowReorderKeyboard;\n\n if (!keyboard || !orderable) {\n return;\n }\n\n const { key } = event;\n\n if (key === \" \" || key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n\n if (lifted) {\n keyboard.drop();\n } else {\n keyboard.lift(row.id);\n }\n\n return;\n }\n\n // The remaining keys belong to a live lift alone — an idle handle leaves them to the page.\n if (!lifted) {\n return;\n }\n\n switch (key) {\n case \"ArrowUp\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.move(-1);\n\n break;\n }\n\n case \"ArrowDown\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.move(1);\n\n break;\n }\n\n case \"Home\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.moveToEdge(\"start\");\n\n break;\n }\n\n case \"End\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.moveToEdge(\"end\");\n\n break;\n }\n\n case \"Escape\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.cancel();\n\n break;\n }\n // No default\n }\n };\n\n return (\n <Tooltip disabled={isDragSource || lifted} label={orderable ? labels.reorderRow : labels.rowOrderingUnavailable} openDelay={500}>\n <ActionIcon\n ref={ref}\n aria-disabled={!orderable || undefined}\n aria-label={labels.reorderRow}\n aria-pressed={lifted || undefined}\n color=\"gray\"\n size=\"sm\"\n variant=\"subtle\"\n onBlur={() => {\n // A keyboard lift is bound to the handle that owns the keys — focus leaving it would\n // strand a session nothing can reach.\n if (lifted) {\n rowReorderKeyboard?.cancel();\n }\n }}\n onKeyDown={handleKeyDown}\n >\n <icons.reorderRow size={14} />\n </ActionIcon>\n </Tooltip>\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { MouseEvent } from \"react\";\n\nimport type { Row, TableInstance } from \"./types\";\n\n/**\n * The injected selection column's header and body cells. Both stop propagation so selection\n * never triggers `onRowClick` (docs/rows.md). Shift-range selection keeps TanStack v9's\n * semantics (`enableRowRangeSelection`, on by default): an ordinary click sets the anchor, a\n * Shift-click applies the display-order range, non-selectable rows excluded. What it never keeps\n * is v9's route to them — `getToggleSelectedHandler()` resolves the gate, the anchor and the\n * display order from the shared core when the click arrives, which is whatever render pass ran\n * last. The controller answers from the commit instead (`use-row-commands.ts`).\n */\nimport { Checkbox, Radio } from \"@mantine/core\";\n\nimport { useDataTableContext } from \"./context\";\n\nfunction noop() {\n // Selection is applied in onClick (where shiftKey exists); the controlled checkbox still\n // needs an onChange to satisfy React's controlled-input contract.\n}\n\nexport function SelectionHeaderCell<TData extends RowData>({ table }: { table: TableInstance<TData> }) {\n const { labels, selection } = useDataTableContext();\n\n if (table.options.enableMultiRowSelection === false) {\n return null;\n }\n\n const scope = table.options.meta?.ledger?.selectAllScope ?? \"all\";\n const allSelected = scope === \"page\" ? table.getIsAllPageRowsSelected() : table.getIsAllRowsSelected();\n // v9 semantics: \"some\" means \"at least one\" and stays true at full selection — the\n // indeterminate glyph must therefore be gated on the matching all-selected check.\n const someSelected = scope === \"page\" ? table.getIsSomePageRowsSelected() : table.getIsSomeRowsSelected();\n\n return (\n <Checkbox\n aria-label={labels.selectAllRows}\n checked={allSelected}\n indeterminate={!allSelected && someSelected}\n size=\"xs\"\n onChange={noop}\n onClick={(event: MouseEvent<HTMLInputElement>) => {\n event.stopPropagation();\n // What the box shows is what clicking it departs from — resolved by this render, never\n // asked of the table again when the click lands.\n selection?.toggleAll(scope, !allSelected);\n }}\n />\n );\n}\n\nexport function SelectionCell<TData extends RowData>({ row }: { row: Row<TData> }) {\n const {\n labels,\n instanceId,\n selection\n } = useDataTableContext();\n const selected = row.getIsSelected();\n\n const select = (event: MouseEvent<HTMLInputElement>) => {\n event.stopPropagation();\n selection?.toggle(\n row as Row<any>,\n event.currentTarget.checked,\n event.shiftKey || event.nativeEvent.shiftKey\n );\n };\n\n // Single-select is a radio group, not a lone checkbox: one choice at a time is what a radio\n // means, and the shared name makes the rendered rows one group for the platform. (Under\n // virtualization only the mounted window is in that group — the same boundary as autosize.)\n if (row.getCanMultiSelect() === false) {\n return (\n <Radio\n aria-label={labels.selectRow}\n checked={selected}\n disabled={!row.getCanSelect()}\n name={`${instanceId}-selection`}\n size=\"xs\"\n onChange={noop}\n onClick={select}\n />\n );\n }\n\n return (\n <Checkbox\n aria-label={labels.selectRow}\n checked={selected}\n disabled={!row.getCanSelect()}\n // Sub-row selection (escape hatch `enableSubRowSelection`): a parent with a partly\n // selected subtree reads as indeterminate.\n indeterminate={!selected && row.getIsSomeSelected()}\n size=\"xs\"\n onChange={noop}\n onClick={select}\n />\n );\n}\n","/**\n * Column preprocessing for `useDataTable`: inject the selection and expander columns (pinned\n * left, fixed width, excluded from every data feature) and derive `filterFn`s from\n * `meta.filter` variants for columns that declare none themselves.\n */\nimport type { RowData } from \"@tanstack/react-table\";\n\nimport type { Column, ColumnDef, TableInstance } from \"./types\";\n\nimport { ExpanderCell, ExpanderHeaderCell } from \"./expander\";\nimport { filterFnByVariant } from \"./filter-fns\";\nimport { RowDragCell } from \"./row-reorder\";\nimport { SelectionCell, SelectionHeaderCell } from \"./selection\";\n\nexport const ROW_DRAG_COLUMN_ID = \"ledger:row-drag\";\nexport const SELECTION_COLUMN_ID = \"ledger:select\";\nexport const EXPANDER_COLUMN_ID = \"ledger:expander\";\n\nexport function isInternalColumn(columnId: string): boolean {\n return columnId === ROW_DRAG_COLUMN_ID || columnId === SELECTION_COLUMN_ID || columnId === EXPANDER_COLUMN_ID;\n}\n\n/**\n * Human-readable column title for every plain-text surface — the columns panel, CSV headers,\n * filter and editor field names. An explicit `meta.label` wins; otherwise the string `header`;\n * a render-function header falls back to the column id, which is why such columns should\n * declare a `meta.label`.\n */\nexport function columnHeaderText<TData extends RowData>(column: Column<TData, unknown>): string {\n const { header, meta } = column.columnDef;\n\n return meta?.label ?? (typeof header === \"string\" ? header : column.id);\n}\n\nexport interface BuildColumnsInput<TData extends RowData> {\n\n columns: Array<ColumnDef<TData, any>>;\n withRowDrag: boolean;\n withSelection: boolean;\n withExpander: boolean;\n rowDragColumn?: Partial<ColumnDef<TData, unknown>>;\n selectionColumn?: Partial<ColumnDef<TData, unknown>>;\n expanderColumn?: Partial<ColumnDef<TData, unknown>>;\n}\n\n/**\n * Author-declared sizing, snapshotted per leaf definition BEFORE TanStack merges its default\n * column def (size 150, minSize 20) into every `column.columnDef` — after that merge, \"the\n * author declared no size\" is indistinguishable from \"the author chose 150\". The width engine\n * (docs/sizing.md) reads this registry through the per-column meta clone created below.\n */\nexport interface RawColumnSizing {\n size: number | undefined;\n minSize: number | undefined;\n maxSize: number | undefined;\n}\n\nconst rawSizingByMeta = new WeakMap<object, RawColumnSizing>();\n\nexport function rawColumnSizing(columnDef: { meta?: object }): RawColumnSizing | undefined {\n return columnDef.meta ? rawSizingByMeta.get(columnDef.meta) : undefined;\n}\n\n/**\n * The per-column `enableResizing` knob rides ledger's `ColumnDef` alias — the TanStack module\n * that would declare it (`columnResizingFeature`) is deliberately unregistered — so reads off\n * the resolved instance definition narrow here.\n */\nexport function columnEnableResizing(columnDef: object): boolean | undefined {\n return (columnDef as { enableResizing?: boolean }).enableResizing;\n}\n\n/**\n * An injected column is an ordinary def, so an override is an ordinary merge — the author's keys\n * win over ledger's defaults. The id alone is reserved: `isInternalColumn` is how the render\n * layer recognizes these columns (centered content, stop-propagation, excluded from CSV and the\n * columns panel), so it is reapplied last.\n */\nfunction injectedColumn<TData extends RowData>(\n defaults: ColumnDef<TData, any>,\n override: Partial<ColumnDef<TData, unknown>> | undefined\n): ColumnDef<TData, any> {\n return processLeaf(\n override\n ? {\n ...defaults,\n ...override,\n id: defaults.id\n } as ColumnDef<TData, any>\n : defaults\n );\n}\n\nexport function buildColumns<TData extends RowData>({\n columns,\n withRowDrag,\n withSelection,\n withExpander,\n rowDragColumn,\n selectionColumn,\n expanderColumn\n}: BuildColumnsInput<TData>): Array<ColumnDef<TData, any>> {\n const result: Array<ColumnDef<TData, any>> = [];\n\n if (withRowDrag) {\n result.push(injectedColumn<TData>({\n id: ROW_DRAG_COLUMN_ID,\n size: 36,\n minSize: 36,\n maxSize: 36,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableGrouping: false,\n // A header with nothing to say: the handles below explain themselves, and the drag\n // column offers no all-rows action the way selection's header checkbox does.\n header: () => null,\n cell: ({ row, table }) => <RowDragCell row={row} table={table as TableInstance<TData>} />\n }, rowDragColumn));\n }\n\n if (withSelection) {\n result.push(injectedColumn<TData>({\n id: SELECTION_COLUMN_ID,\n size: 40,\n minSize: 40,\n maxSize: 40,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableGrouping: false,\n // Contexts carry the core `Table` type, but the runtime object IS the adapter-augmented\n // instance — the assertion narrows the type to what actually exists.\n header: ({ table }) => <SelectionHeaderCell table={table as TableInstance<TData>} />,\n cell: ({ row }) => <SelectionCell row={row} />\n }, selectionColumn));\n }\n\n if (withExpander) {\n result.push(injectedColumn<TData>({\n id: EXPANDER_COLUMN_ID,\n size: 36,\n minSize: 36,\n maxSize: 36,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableGrouping: false,\n header: ({ table }) => <ExpanderHeaderCell table={table as TableInstance<TData>} />,\n cell: ({ row }) => <ExpanderCell row={row} />\n }, expanderColumn));\n }\n\n for (const column of columns) {\n result.push(processColumn(column));\n }\n\n return result;\n}\n\n/**\n * Group definitions recurse so every LEAF gets processed — its raw sizing registered and its\n * `meta.filter` variant mapped.\n */\nfunction processColumn<TData extends RowData>(column: ColumnDef<TData, any>): ColumnDef<TData, any> {\n if (\"columns\" in column && Array.isArray(column.columns)) {\n return { ...column, columns: column.columns.map(child => processColumn(child)) };\n }\n\n return processLeaf(column);\n}\n\nfunction processLeaf<TData extends RowData>(column: ColumnDef<TData, any>): ColumnDef<TData, any> {\n // A fresh meta clone per leaf keys the raw-sizing registry (and survives TanStack's merge).\n const meta = { ...column.meta };\n rawSizingByMeta.set(meta, {\n size: column.size,\n minSize: column.minSize,\n maxSize: column.maxSize\n });\n\n return withVariantFilterFn({ ...column, meta });\n}\n\nfunction withVariantFilterFn<TData extends RowData>(column: ColumnDef<TData, any>): ColumnDef<TData, any> {\n const filter = column.meta?.filter;\n\n if (!filter || typeof filter === \"function\" || column.filterFn) {\n return column;\n }\n\n const variant = typeof filter === \"string\" ? filter : filter.variant;\n\n return { ...column, filterFn: filterFnByVariant[variant] };\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { TableInstance } from \"./types\";\n\nimport { isInternalColumn } from \"./build-columns\";\n\n/**\n * Pure edits over TanStack's flat `columnOrder` array, shared by the two affordances that\n * reorder columns: the header drag (`use-column-reorder.ts`) and the columns panel\n * (`columns-panel.tsx`).\n *\n * The flat array is the ONLY thing `columnOrder` governs — a pinned column's position comes from\n * its index inside `columnPinning.start` / `.end` instead (TanStack's `getStartLeafColumns` maps\n * over that array, while `getCenterLeafColumns` filters the `columnOrder`-sorted leaf list). So\n * reordering the center zone edits `columnOrder`, and reordering a pinned zone edits\n * `columnPinning` — never both.\n */\n\n/**\n * The flat order to edit from: the state order stripped of ids the table no longer defines, with\n * any column it never mentioned appended in definition order. An empty slice means \"definition\n * order\", which is exactly `getAllLeafColumns()`.\n */\nexport function resolveColumnOrder<TData extends RowData>(table: TableInstance<TData>): string[] {\n const leafIds = table.getAllLeafColumns().map(column => column.id);\n // Slice atoms exist on both the hook wrapper and the core instance handed to header renderers.\n const columnOrder = table.atoms.columnOrder.get();\n\n if (columnOrder.length === 0) {\n return leafIds;\n }\n\n return [\n ...columnOrder.filter(id => leafIds.includes(id)),\n ...leafIds.filter(id => !columnOrder.includes(id))\n ];\n}\n\nexport interface ColumnDropTarget {\n id: string;\n side: \"before\" | \"after\";\n}\n\nexport type ColumnZone = \"start\" | \"center\" | \"end\";\n\nexport function getColumnZone<TData extends RowData>(table: TableInstance<TData>, columnId: string): ColumnZone | null {\n const pinned = table.getColumn(columnId)?.getIsPinned();\n\n return pinned === \"start\" || pinned === \"end\" ? pinned : pinned === false ? \"center\" : null;\n}\n\n/**\n * Move `columnId` to sit immediately before or after `target.id`. Returns the input untouched\n * when the target is no longer part of the order.\n */\nexport function moveColumnBeside(order: string[], columnId: string, target: ColumnDropTarget): string[] {\n const without = order.filter(id => id !== columnId);\n const targetIndex = without.indexOf(target.id);\n\n if (targetIndex === -1) {\n return order;\n }\n\n const insertAt = target.side === \"before\" ? targetIndex : targetIndex + 1;\n\n return [...without.slice(0, insertAt), columnId, ...without.slice(insertAt)];\n}\n\n/**\n * Rewrite the flat order so the center columns read `nextCenterIds`, leaving every pinned column\n * in the slot it already occupies: each center slot takes the next id off the new sequence.\n * Pinned ids keep their flat positions because those positions are inert — a pinned column\n * renders from its `columnPinning` index, not from here.\n */\nexport function applyCenterOrder(order: string[], nextCenterIds: string[]): string[] {\n const centerIds = new Set(nextCenterIds);\n const queue = [...nextCenterIds];\n\n return order.map(id => centerIds.has(id) ? queue.shift()! : id);\n}\n\n/**\n * Reorder a header inside its current display zone. Pin controls are the only way to cross a\n * zone boundary; a drop across one is rejected so the visual affordance never lies.\n */\nexport function reorderColumnWithinZone<TData extends RowData>(\n table: TableInstance<TData>,\n columnId: string,\n target: ColumnDropTarget\n): boolean {\n const zone = getColumnZone(table, columnId);\n\n if (!zone || getColumnZone(table, target.id) !== zone) {\n return false;\n }\n\n if (zone === \"center\") {\n const centerIds = table.getCenterLeafColumns()\n .map(column => column.id)\n .filter(id => !isInternalColumn(id));\n const nextCenterIds = moveColumnBeside(centerIds, columnId, target);\n\n table.setColumnOrder(applyCenterOrder(resolveColumnOrder(table), nextCenterIds));\n\n return true;\n }\n\n const start = table.getStartLeafColumns()\n .map(column => column.id)\n .filter(id => !isInternalColumn(id));\n const end = table.getEndLeafColumns()\n .map(column => column.id)\n .filter(id => !isInternalColumn(id));\n const zoneOrder = zone === \"start\" ? start : end;\n const nextZoneOrder = moveColumnBeside(zoneOrder, columnId, target);\n\n table.setColumnPinning({\n start: zone === \"start\" ? nextZoneOrder : start,\n end: zone === \"end\" ? nextZoneOrder : end\n });\n\n return true;\n}\n","import type { ComponentType, SVGProps } from \"react\";\n\n/**\n * The table chrome's glyphs and the `icons` registry that swaps them (docs/styling.md#icons).\n *\n * The defaults are vendored from Lucide (https://lucide.dev): path data copied verbatim from\n * `lucide-static` v1.34.0, so there is no icon-library dependency and the set is a default, not\n * a lock — any component satisfying `DataTableIconProps` slots in, and `lucide-react` components\n * satisfy it as-is.\n *\n * License of the vendored path data — ISC, Copyright (c) 2026 Lucide Icons and Contributors:\n * permission to use, copy, modify, and/or distribute this software for any purpose with or\n * without fee is hereby granted, provided that the above copyright notice and this permission\n * notice appear in all copies. The chevron, search and x glyphs are derived from Feather\n * (MIT, Copyright (c) 2013-present Cole Bemis).\n */\ninterface IconProps extends SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nfunction Icon({\n size = 16,\n children,\n ...others\n}: IconProps) {\n return (\n <svg\n aria-hidden\n fill=\"none\"\n height={size}\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n viewBox=\"0 0 24 24\"\n width={size}\n {...others}\n >\n {children}\n </svg>\n );\n}\n\n// Glyphs, named for their Lucide source icons. Module-private: components reach them through\n// the resolved registry, never directly.\n\nfunction IconInbox(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n </Icon>\n );\n}\n\nfunction IconTriangleAlert(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </Icon>\n );\n}\n\nfunction IconChevronUp(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m18 15-6-6-6 6\" />\n </Icon>\n );\n}\n\nfunction IconChevronDown(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m6 9 6 6 6-6\" />\n </Icon>\n );\n}\n\nfunction IconChevronRight(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m9 18 6-6-6-6\" />\n </Icon>\n );\n}\n\nfunction IconChevronsUpDown(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m7 15 5 5 5-5\" />\n <path d=\"m7 9 5-5 5 5\" />\n </Icon>\n );\n}\n\nfunction IconFunnel(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z\" />\n </Icon>\n );\n}\n\nfunction IconGripVertical(props: IconProps) {\n return (\n <Icon {...props}>\n <circle cx=\"9\" cy=\"12\" r=\"1\" />\n <circle cx=\"9\" cy=\"5\" r=\"1\" />\n <circle cx=\"9\" cy=\"19\" r=\"1\" />\n <circle cx=\"15\" cy=\"12\" r=\"1\" />\n <circle cx=\"15\" cy=\"5\" r=\"1\" />\n <circle cx=\"15\" cy=\"19\" r=\"1\" />\n </Icon>\n );\n}\n\n/**\n * The three pin states speak one language — where the column sits relative to the table's edges\n * (a pushpin cannot say start from end, which is why `pin` / `pin-off` were passed over).\n */\nfunction IconArrowLeftToLine(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M3 19V5\" />\n <path d=\"m13 6-6 6 6 6\" />\n <path d=\"M7 12h14\" />\n </Icon>\n );\n}\n\nfunction IconArrowRightToLine(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M17 12H3\" />\n <path d=\"m11 18 6-6-6-6\" />\n <path d=\"M21 5v14\" />\n </Icon>\n );\n}\n\n/**\n * Neither edge: the column moves with the scroll again.\n */\nfunction IconMoveHorizontal(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m18 8 4 4-4 4\" />\n <path d=\"M2 12h20\" />\n <path d=\"m6 8-4 4 4 4\" />\n </Icon>\n );\n}\n\n/**\n * \"Put it back the way it was\": counter-clockwise is the industry's undo, clockwise its\n * refresh — the table shows both, so they must not be the same glyph.\n */\nfunction IconRotateCcw(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </Icon>\n );\n}\n\nfunction IconRotateCw(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\" />\n <path d=\"M21 3v5h-5\" />\n </Icon>\n );\n}\n\nfunction IconSearch(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m21 21-4.34-4.34\" />\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n </Icon>\n );\n}\n\nfunction IconX(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </Icon>\n );\n}\n\nfunction IconListTree(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M8 5h13\" />\n <path d=\"M13 12h8\" />\n <path d=\"M13 19h8\" />\n <path d=\"M3 10a2 2 0 0 0 2 2h3\" />\n <path d=\"M3 5v12a2 2 0 0 0 2 2h3\" />\n </Icon>\n );\n}\n\n/**\n * What a replacement icon receives — the two knobs the chrome actually turns. Lucide icons are\n * drawn on a 24px grid at stroke 2; a custom component is free to ignore either.\n */\nexport interface DataTableIconProps {\n /**\n * Rendered width and height in px. The chrome passes 12–16 for controls and 40 for the\n * empty/error indicators.\n */\n size?: number;\n strokeWidth?: number;\n}\n\nexport type DataTableIconComponent = ComponentType<DataTableIconProps>;\n\n/**\n * Every glyph the table chrome renders, one slot per affordance. Slots are named for the\n * `DataTableLabels` key of the same affordance where one exists (`pinStart`, `retry`,\n * `clearSelection`, …), so the two registries read as one vocabulary.\n */\nexport interface DataTableIcons {\n /* Header */\n sortAsc: DataTableIconComponent;\n sortDesc: DataTableIconComponent;\n /**\n * The neutral both-directions affordance an unsorted sortable column shows.\n */\n sortable: DataTableIconComponent;\n filterColumn: DataTableIconComponent;\n\n /* Rows — one chevron, rotated open by the stylesheet (expand-all and groups included). */\n expandRow: DataTableIconComponent;\n /**\n * The drag handle of the injected row-ordering column, and the ghost that follows a drag.\n */\n reorderRow: DataTableIconComponent;\n\n /* States */\n empty: DataTableIconComponent;\n noResults: DataTableIconComponent;\n error: DataTableIconComponent;\n retry: DataTableIconComponent;\n\n /* Global search */\n search: DataTableIconComponent;\n\n /* Selection */\n clearSelection: DataTableIconComponent;\n\n /* Columns panel */\n resetColumns: DataTableIconComponent;\n reorderColumn: DataTableIconComponent;\n /**\n * Both the group toggle and the grouped rest-state mark.\n */\n groupByColumn: DataTableIconComponent;\n pinStart: DataTableIconComponent;\n unpin: DataTableIconComponent;\n pinEnd: DataTableIconComponent;\n}\n\nexport const defaultIcons: DataTableIcons = {\n sortAsc: IconChevronUp,\n sortDesc: IconChevronDown,\n sortable: IconChevronsUpDown,\n filterColumn: IconFunnel,\n expandRow: IconChevronRight,\n reorderRow: IconGripVertical,\n empty: IconInbox,\n noResults: IconSearch,\n error: IconTriangleAlert,\n retry: IconRotateCw,\n search: IconSearch,\n clearSelection: IconX,\n resetColumns: IconRotateCcw,\n reorderColumn: IconGripVertical,\n groupByColumn: IconListTree,\n pinStart: IconArrowLeftToLine,\n unpin: IconMoveHorizontal,\n pinEnd: IconArrowRightToLine\n};\n\nexport function resolveIcons(icons: Partial<DataTableIcons> | undefined): DataTableIcons {\n return icons ? { ...defaultIcons, ...icons } : defaultIcons;\n}\n","/**\n * Every user-visible string in the library flows through this object — components never hardcode\n * a locale. App-wide configuration is the Mantine-native mechanism (theme defaultProps, see\n * docs/i18n.md); a complete zh-CN preset ships from \"./locales\".\n */\nexport interface DataTableLabels {\n /* Pagination */\n paginationSummary: (from: number, to: number, total: number) => string;\n rowsPerPage: string;\n\n /* Selection */\n selectAllRows: string;\n selectRow: string;\n selectedCount: (count: number) => string;\n clearSelection: string;\n\n /* Expansion */\n expandRow: string;\n collapseRow: string;\n expandAll: string;\n collapseAll: string;\n\n /* Active row (enableActiveRow) */\n /**\n * Describes the body viewport — the keyboard focus stop — while `enableActiveRow` is on. It\n * is the only place the arrow-key row model is announced, so say what the keys do. A\n * description, never a name: that div is roleless, and `generic` prohibits a name.\n */\n rowNavigation: string;\n /**\n * Announced politely whenever the current row changes: focus stays on the viewport, so without\n * this the move is visual only.\n */\n currentRow: (row: string, index: number, count: number) => string;\n\n /* Columns panel */\n columnsPanel: string;\n resetColumns: string;\n /**\n * Logical positions (TanStack v9 vocabulary): start/end map to left/right in LTR layouts and\n * mirror under RTL.\n */\n pinStart: string;\n pinEnd: string;\n unpin: string;\n /**\n * Zone captions the columns panel shows above its pinned columns; nouns for the state, where\n * `pinStart` / `pinEnd` name the action.\n */\n pinnedStart: string;\n pinnedEnd: string;\n groupByColumn: string;\n ungroupColumn: string;\n columnWidth: string;\n /**\n * Width placeholder for a column whose definition declares no `size` — it grows to share the\n * leftover viewport. A column that declares one shows that number instead.\n */\n columnWidthAuto: string;\n\n /* Column interactions */\n resizeColumn: string;\n reorderColumn: string;\n\n /* Filters */\n /**\n * Names the funnel trigger and the control inside it — an unnamed control in a table of them\n * is unusable, so the column title is interpolated rather than left generic.\n */\n filterColumn: (column: string) => string;\n clearFilter: string;\n filterPlaceholder: string;\n filterRangeMin: string;\n filterRangeMax: string;\n\n /* Global search */\n searchPlaceholder: string;\n\n /* States */\n loading: string;\n empty: string;\n /**\n * Zero rows while a column filter or the global search is active — a different situation\n * than an empty data set, so it gets its own message.\n */\n noResults: string;\n loadingMore: string;\n error: string;\n retry: string;\n loadMoreError: string;\n\n /* Editing */\n /**\n * Names an inline editor by the column it edits.\n */\n editColumn: (column: string) => string;\n editPending: string;\n\n /* Row ordering (enableRowOrdering) */\n /**\n * Names every drag handle; the row a handle belongs to is evident from its position, so the\n * label states the action, matching `selectRow` / `expandRow`.\n */\n reorderRow: string;\n /**\n * Why the handles are disabled — shown as their tooltip while sorting, a filter, a search or\n * grouping controls the visible order.\n */\n rowOrderingUnavailable: string;\n /**\n * Announced when a drag lifts a row. The one place the keyboard drag model is spoken, so say\n * what the keys do.\n */\n rowReorderLifted: (row: string) => string;\n /**\n * Announced as the drop target changes; `row` names the target the same way `currentRow`\n * names rows (leading visible cell).\n */\n rowReorderTarget: (row: string, side: \"before\" | \"after\") => string;\n rowReorderDropped: (row: string) => string;\n rowReorderCanceled: string;\n}\n\nexport const defaultLabels: DataTableLabels = {\n paginationSummary: (from, to, total) => `${from}–${to} of ${total}`,\n rowsPerPage: \"Rows per page\",\n\n selectAllRows: \"Select all rows\",\n selectRow: \"Select row\",\n selectedCount: count => `${count} selected`,\n clearSelection: \"Clear selection\",\n\n rowNavigation: \"Table rows — use the arrow keys to move between rows\",\n currentRow: (row, index, count) => `${row}, row ${index} of ${count}`,\n\n expandRow: \"Expand row\",\n collapseRow: \"Collapse row\",\n expandAll: \"Expand all rows\",\n collapseAll: \"Collapse all rows\",\n\n columnsPanel: \"Columns\",\n resetColumns: \"Reset\",\n pinStart: \"Pin to start\",\n pinEnd: \"Pin to end\",\n unpin: \"Unpin\",\n pinnedStart: \"Pinned start\",\n pinnedEnd: \"Pinned end\",\n groupByColumn: \"Group by this column\",\n ungroupColumn: \"Ungroup\",\n columnWidth: \"Width\",\n columnWidthAuto: \"Auto\",\n\n resizeColumn: \"Drag to resize; double-click to fit content\",\n reorderColumn: \"Drag to reorder column\",\n\n filterColumn: column => `Filter ${column}`,\n clearFilter: \"Clear filter\",\n filterPlaceholder: \"Filter…\",\n filterRangeMin: \"Min\",\n filterRangeMax: \"Max\",\n\n searchPlaceholder: \"Search…\",\n\n loading: \"Loading\",\n empty: \"No data\",\n noResults: \"No matching records\",\n loadingMore: \"Loading more\",\n error: \"Couldn't load data\",\n retry: \"Retry\",\n loadMoreError: \"Couldn't load more rows\",\n\n editColumn: column => `Edit ${column}`,\n editPending: \"Saving\",\n\n reorderRow: \"Drag to reorder row\",\n rowOrderingUnavailable: \"Clear sorting, filters, and grouping to reorder rows\",\n rowReorderLifted: row => `${row} lifted — use the arrow keys to move, space to drop, escape to cancel`,\n rowReorderTarget: (row, side) => side === \"before\" ? `Before ${row}` : `After ${row}`,\n rowReorderDropped: row => `${row} dropped`,\n rowReorderCanceled: \"Reorder canceled\"\n};\n\nexport function resolveLabels(labels: Partial<DataTableLabels> | undefined): DataTableLabels {\n return labels ? { ...defaultLabels, ...labels } : defaultLabels;\n}\n","import type { DragEndEvent } from \"@dnd-kit/react\";\nimport type { PopoverProps } from \"@mantine/core\";\nimport type { ColumnPinningPosition, RowData } from \"@tanstack/react-table\";\nimport type { CSSProperties, ReactElement } from \"react\";\n\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { Column, TableInstance } from \"./types\";\n\n/**\n * `DataTable.ColumnsPanel` — one surface for every column-layout decision: order (drag),\n * visibility, pinning, width, and grouping. It replaces the per-column header menu, whose\n * \"hide column\" item was a trap door — a hidden column took its own menu with it.\n *\n * Trigger-agnostic by construction. `children` IS the trigger and the panel opens from it in a\n * Popover; with no children the panel renders bare, so a drawer, a sidebar, or a settings page\n * hosts it just as well. Bare is the primary shape — the rest of the compound family\n * (`.Search` / `.Pagination` / `.SelectionBar`) is bare content the page places, too.\n *\n * Presentation contract (docs/columns.md): at rest a row is identity — checkbox and name — plus\n * dimmed marks only where the layout deviates from default (captions over pinned zones, an\n * overridden width, a grouped column, a dimmed hidden name). The machinery — drag handle, width\n * field, pin segment, group toggle — surfaces on the hovered or keyboard-focused row and stays\n * inline where hover does not exist. The reveal is stylesheet-only: every control is always in\n * the DOM and the accessibility tree.\n */\nimport { move } from \"@dnd-kit/helpers\";\nimport { DragDropProvider } from \"@dnd-kit/react\";\nimport { useSortable } from \"@dnd-kit/react/sortable\";\nimport {\n ActionIcon,\n Button,\n Center,\n Checkbox,\n Group,\n NumberInput,\n Popover,\n SegmentedControl,\n Text,\n Tooltip,\n useProps,\n VisuallyHidden\n} from \"@mantine/core\";\nimport clsx from \"clsx\";\n\nimport { columnEnableResizing, columnHeaderText, isInternalColumn, rawColumnSizing } from \"./build-columns\";\nimport { applyCenterOrder, resolveColumnOrder } from \"./column-order\";\nimport { resolveIcons } from \"./icons\";\nimport { resolveLabels } from \"./labels\";\n\nexport interface DataTableColumnsPanelProps<TData extends RowData> {\n table: TableInstance<TData>;\n /**\n * The control that opens the panel, wrapped as the Popover target — a button, an icon in a\n * header cell, anything. Omitted: the panel renders bare for a drawer, a sidebar, or a page\n * of its own.\n */\n children?: ReactElement;\n /**\n * Forwarded to the Popover; only meaningful alongside a trigger.\n */\n popoverProps?: Omit<PopoverProps, \"children\">;\n labels?: Partial<DataTableLabels>;\n icons?: Partial<DataTableIcons>;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * The three lists the panel renders, in table display order. `start` / `center` / `end` are\n * TanStack's own words (`getStartLeafColumns` / `getCenterLeafColumns` / `getEndLeafColumns`);\n * \"zone\" is ledger's collective noun for them, because TanStack names the accessors but never\n * the set.\n */\ntype ColumnZone = \"start\" | \"center\" | \"end\";\n\ninterface ColumnsPanelZone<TData extends RowData> {\n id: ColumnZone;\n columns: Array<Column<TData, unknown>>;\n}\n\n/**\n * Leaf columns per zone — hidden ones included (bringing them back is what the panel is for) and\n * ledger's injected columns excluded (they can never be reordered, hidden, or unpinned). The\n * order is TanStack's: a pinned zone reads its `columnPinning` array, the center reads\n * `columnOrder`.\n */\nfunction resolveZones<TData extends RowData>(table: TableInstance<TData>): Array<ColumnsPanelZone<TData>> {\n const external = (columns: Array<Column<TData, unknown>>) => columns.filter(column => !isInternalColumn(column.id));\n\n return [\n { id: \"start\", columns: external(table.getStartLeafColumns()) },\n { id: \"center\", columns: external(table.getCenterLeafColumns()) },\n { id: \"end\", columns: external(table.getEndLeafColumns()) }\n ];\n}\n\n/**\n * The pinned zones caption themselves — the zone's pin glyph beside its name, the same pair the\n * row's pin segments speak; the center is the default territory and stays unlabeled.\n */\nconst zoneCaptions = {\n start: {\n label: \"pinnedStart\",\n icon: \"pinStart\"\n },\n end: {\n label: \"pinnedEnd\",\n icon: \"pinEnd\"\n }\n} satisfies Partial<Record<ColumnZone, { label: keyof DataTableLabels; icon: keyof DataTableIcons }>>;\n\ninterface ZoneCaptionProps {\n zone: keyof typeof zoneCaptions;\n labels: DataTableLabels;\n icons: DataTableIcons;\n}\n\nfunction ZoneCaption({\n zone,\n labels,\n icons\n}: ZoneCaptionProps) {\n const caption = zoneCaptions[zone];\n const Glyph = icons[caption.icon];\n\n // A ledger-owned div, not <Text>: the host may load Mantine's stylesheet unlayered, where the\n // Text reset (`padding: 0` on its <p>) beats anything the ledger layer declares — the caption's\n // box, type, and color all live in the stylesheet instead.\n return (\n <div className=\"ledger-columns-panel-zone-label\">\n <Glyph size={12} />\n {labels[caption.label]}\n </div>\n );\n}\n\n/**\n * The three-state position control, one segment per TanStack `ColumnPinningPosition`. `key`\n * addresses both registries — the icon slots are named for their label keys. `value` stands in\n * for the position inside the SegmentedControl, whose values must be strings (\"center\" is the\n * zone name for TanStack's `false`).\n */\nconst pinSegments: Array<{\n position: ColumnPinningPosition;\n value: \"start\" | \"center\" | \"end\";\n key: \"pinStart\" | \"unpin\" | \"pinEnd\";\n}> = [\n {\n position: \"start\",\n value: \"start\",\n key: \"pinStart\"\n },\n {\n position: false,\n value: \"center\",\n key: \"unpin\"\n },\n {\n position: \"end\",\n value: \"end\",\n key: \"pinEnd\"\n }\n];\n\nconst columnsPanelDefaultProps = {} satisfies Partial<DataTableColumnsPanelProps<RowData>>;\n\nexport function DataTableColumnsPanel<TData extends RowData>(props: DataTableColumnsPanelProps<TData>) {\n const {\n table,\n children,\n popoverProps,\n labels,\n icons,\n className,\n style\n } = useProps(\"DataTableColumnsPanel\", columnsPanelDefaultProps, props);\n\n const content = (\n <ColumnsPanelContent\n className={className}\n icons={resolveIcons(icons)}\n labels={resolveLabels(labels)}\n style={style}\n table={table}\n />\n );\n\n if (!children) {\n return content;\n }\n\n // 360 fits the widest row a column can ask for — handle, checkbox, a comfortable title, and\n // the revealed toolbar — so the default never squeezes; `popoverProps` tunes it for column\n // sets that need less or titles that need more.\n return (\n <Popover position=\"bottom-end\" shadow=\"md\" width={360} {...popoverProps}>\n <Popover.Target>{children}</Popover.Target>\n\n {/* A dropdown grows without bound, so it gets a definite cap here and the panel's own list\n becomes the scroller; p={0} because the panel brings its own padding. */}\n <Popover.Dropdown display=\"flex\" mah=\"60vh\" p={0}>\n {content}\n </Popover.Dropdown>\n </Popover>\n );\n}\n\ninterface ColumnsPanelContentProps<TData extends RowData> {\n table: TableInstance<TData>;\n labels: DataTableLabels;\n icons: DataTableIcons;\n className?: string;\n style?: CSSProperties;\n}\n\nfunction ColumnsPanelContent<TData extends RowData>({\n table,\n labels,\n icons,\n className,\n style\n}: ColumnsPanelContentProps<TData>) {\n const zones = resolveZones(table);\n\n // The same rule the header drag applies (use-column-reorder.ts): with column groups, sibling\n // order inside a group is ambiguous — that hook already carries the dev warning.\n const orderable\n = table.options.meta?.ledger?.enableColumnOrdering === true\n && table.getHeaderGroups().length === 1;\n\n const zoneIds = (id: ColumnZone) => zones.find(zone => zone.id === id)?.columns.map(column => column.id) ?? [];\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { source } = event.operation;\n\n if (event.canceled || !source) {\n return;\n }\n\n const zone = zones.find(candidate => candidate.columns.some(column => column.id === source.id));\n\n if (!zone) {\n return;\n }\n\n const ids = zone.columns.map(column => column.id);\n const next = move(ids, event);\n\n if (next === ids) {\n return;\n }\n\n if (zone.id === \"center\") {\n table.setColumnOrder(applyCenterOrder(resolveColumnOrder(table), next));\n\n return;\n }\n\n // Assembled from the panel's own zone lists, never from the columnPinning slice: that one\n // carries the injected column ids useDataTable merges in on every render, and echoing them\n // back would leak `ledger:*` into the consumer's onColumnPinningChange and persisted state.\n table.setColumnPinning({\n start: zone.id === \"start\" ? next : zoneIds(\"start\"),\n end: zone.id === \"end\" ? next : zoneIds(\"end\")\n });\n };\n\n const handleReset = () => {\n // Exactly the layout set `persistState` persists by default (docs/state.md). Each reset\n // targets `table.initialState`, which useDataTable seeds from the `defaultX` options — so\n // this restores the application's declared layout, not merely an empty one.\n table.resetColumnOrder();\n table.resetColumnVisibility();\n table.resetColumnPinning();\n table.resetColumnSizing();\n };\n\n return (\n <DragDropProvider onDragEnd={handleDragEnd}>\n <div className={clsx(\"ledger-columns-panel\", className)} style={style}>\n <Group className=\"ledger-columns-panel-header\" gap=\"xs\" justify=\"space-between\" wrap=\"nowrap\">\n <Text fw={600} size=\"sm\">\n {labels.columnsPanel}\n </Text>\n\n <Button\n color=\"gray\"\n leftSection={<icons.resetColumns size={14} />}\n size=\"compact-xs\"\n variant=\"subtle\"\n onClick={handleReset}\n >\n {labels.resetColumns}\n </Button>\n </Group>\n\n <div className=\"ledger-columns-panel-list\">\n {zones\n .filter(zone => zone.columns.length > 0)\n .map(zone => (\n <div key={zone.id} className=\"ledger-columns-panel-zone\" data-pinned={zone.id !== \"center\" || undefined}>\n {zone.id !== \"center\" && <ZoneCaption icons={icons} labels={labels} zone={zone.id} />}\n\n {zone.columns.map((column, index) => (\n <ColumnsPanelItem\n key={column.id}\n column={column}\n icons={icons}\n index={index}\n labels={labels}\n orderable={orderable}\n table={table}\n zone={zone.id}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n </DragDropProvider>\n );\n}\n\ninterface ColumnsPanelItemProps<TData extends RowData> {\n column: Column<TData, unknown>;\n table: TableInstance<TData>;\n labels: DataTableLabels;\n icons: DataTableIcons;\n index: number;\n zone: ColumnZone;\n orderable: boolean;\n}\n\nfunction ColumnsPanelItem<TData extends RowData>({\n column,\n table,\n labels,\n icons,\n index,\n zone,\n orderable\n}: ColumnsPanelItemProps<TData>) {\n // `type`/`accept` both carry the zone, so a column only ever sorts among its own kind: moving\n // between zones is what the pin controls are for, and an empty zone has no drop target anyway.\n const {\n ref,\n handleRef,\n isDragging\n } = useSortable({\n id: column.id,\n index,\n group: zone,\n type: zone,\n accept: zone,\n disabled: !orderable\n });\n\n const title = columnHeaderText(column);\n const pinned = column.getIsPinned();\n const grouped = column.getIsGrouped();\n const canPin = column.getCanPin();\n // Ledger's own gate — the TanStack `columnResizingFeature` (and `getCanResize`) is unregistered.\n const canResize\n = table.options.meta?.ledger?.enableColumnResizing === true\n && columnEnableResizing(column.columnDef) !== false;\n const canGroup = table.options.enableGrouping === true && column.getCanGroup();\n\n // The field holds the OVERRIDE; empty falls back to whatever the definition prescribes — the\n // author's `size`, or growing where none is declared. The placeholder shows that fallback\n // rather than a blanket \"auto\", which would misdescribe every column that declares a size.\n // Author sizing comes from the RAW registry, never `columnDef.size`: TanStack merges its\n // `size: 150` default into every resolved definition, which would make \"unsized\"\n // unrepresentable (docs/sizing.md).\n // Read through the slice atom, not `table.state`: `.state` exists only on the hook's wrapper,\n // while a panel hosted in a header cell receives the core instance — atoms live on both.\n const width = table.atoms.columnSizing.get()[column.id];\n const declaredWidth = rawColumnSizing(column.columnDef)?.size ?? table.options.defaultColumn?.size;\n\n const handleWidthChange = (value: number | string) => {\n table.setColumnSizing(previous => {\n // Cleared: drop the entry entirely rather than zeroing it — the same move the resize drag\n // makes on Escape (use-column-resize.ts), and the only state the width engine reads as\n // \"no override\" (docs/sizing.md).\n if (value === \"\") {\n const { [column.id]: _dropped, ...rest } = previous;\n\n return rest;\n }\n\n return { ...previous, [column.id]: Number(value) };\n });\n };\n\n return (\n <Group\n ref={ref}\n className=\"ledger-columns-panel-item\"\n data-dragging={isDragging || undefined}\n data-hidden={!column.getIsVisible() || undefined}\n gap=\"xs\"\n wrap=\"nowrap\"\n >\n {orderable && (\n <Tooltip label={labels.reorderColumn} openDelay={500}>\n <ActionIcon\n ref={handleRef}\n aria-label={labels.reorderColumn}\n className=\"ledger-columns-panel-handle\"\n color=\"gray\"\n size=\"sm\"\n variant=\"subtle\"\n >\n <icons.reorderColumn />\n </ActionIcon>\n </Tooltip>\n )}\n\n {/* miw={0} is load-bearing: a flex item defaults to `min-width: auto`, so the nowrap title\n would set an unshrinkable floor — long names would shove the rest of the row instead of\n ellipsing. The tooltip rides `wrapperProps` because Checkbox forwards bare props to its\n INPUT, and a title there would only answer on the box, never on the truncated text. */}\n <Checkbox\n checked={column.getIsVisible()}\n classNames={{ labelWrapper: \"ledger-columns-panel-label\" }}\n disabled={!column.getCanHide()}\n flex={1}\n label={title}\n miw={0}\n size=\"sm\"\n wrapperProps={{ title }}\n onChange={event => column.toggleVisibility(event.currentTarget.checked)}\n />\n\n {/* Rest-state marks for the two deviations the zone captions cannot carry. The toolbar\n covers them while revealed, and the touch stylesheet drops them outright — there the\n real controls sit inline and already say the same thing. */}\n {(grouped || width !== undefined) && (\n <div className=\"ledger-columns-panel-indicators\">\n {grouped && <icons.groupByColumn size={12} />}\n {/* lh=1 collapses the line box onto the digits, so flex centering lands the mark on the\n row's true midline instead of the taller line box's. */}\n {width !== undefined && <Text lh={1} size=\"xs\">{`${width}px`}</Text>}\n </div>\n )}\n\n {(canResize || canGroup || canPin) && (\n <div className=\"ledger-columns-panel-controls\">\n {/* startValue mirrors the placeholder: stepping an empty field materializes the\n declared width as the override and counts on from there, instead of jumping to\n minSize the way the default (0, clamped) would. */}\n {canResize && (\n <NumberInput\n aria-label={labels.columnWidth}\n classNames={{ input: \"ledger-columns-panel-width-input\" }}\n max={column.columnDef.maxSize}\n min={column.columnDef.minSize}\n placeholder={declaredWidth === undefined ? labels.columnWidthAuto : String(declaredWidth)}\n size=\"xs\"\n startValue={declaredWidth}\n step={10}\n value={width ?? \"\"}\n w={72}\n onChange={handleWidthChange}\n />\n )}\n\n {canGroup && (\n <Tooltip label={grouped ? labels.ungroupColumn : labels.groupByColumn} openDelay={500}>\n <ActionIcon\n aria-label={grouped ? labels.ungroupColumn : labels.groupByColumn}\n aria-pressed={grouped}\n size=\"input-xs\"\n variant={grouped ? \"light\" : \"subtle\"}\n onClick={() => column.toggleGrouping()}\n >\n <icons.groupByColumn />\n </ActionIcon>\n </Tooltip>\n )}\n\n {/* One radio group, not three toggle buttons: the pin state is a single choice of\n position, and the selected segment says which without a tooltip. Each glyph rides a\n <Center> (Mantine's own recipe for icon segments): left inline, the svg would sit on\n the text baseline and hang above the segment's midline by the descender's height.\n The label key serves twice — the visually hidden accessible name and the Tooltip\n label. */}\n {canPin && (\n <SegmentedControl\n size=\"xs\"\n value={pinSegments.find(segment => segment.position === pinned)?.value ?? \"center\"}\n data={pinSegments.map(({ value, key }) => {\n const Glyph = icons[key];\n\n return {\n value,\n label: (\n <Tooltip label={labels[key]} openDelay={500}>\n {/* h=18: the 14px glyph alone would size the control at 26px next to the\n width input's 30 — 18 plus the segment's own chrome lands both at 30. */}\n <Center h={18}>\n <Glyph size={14} />\n <VisuallyHidden>{labels[key]}</VisuallyHidden>\n </Center>\n </Tooltip>\n )\n };\n })}\n onChange={value => {\n column.pin(pinSegments.find(segment => segment.value === value)?.position ?? false);\n }}\n />\n )}\n </div>\n )}\n </Group>\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Column, Row, TableInstance } from \"./types\";\n\n/**\n * CSV export over the live table instance (RFC 4180 quoting, CRLF line ends). Exports accessor\n * columns only, in their current visible order; `meta.export` excludes a column or overrides\n * its exported header/value. Scopes read the same row models the screen shows — a\n * server-paginated table can therefore only export the rows it has.\n */\nimport { columnHeaderText, isInternalColumn } from \"./build-columns\";\n\nexport interface ToCsvOptions {\n /**\n * Which rows to export:\n * - `\"filtered\"` (default) — everything after filters and sorting, before pagination;\n * - `\"all\"` — the unfiltered data set;\n * - `\"page\"` — the current page (identical to `\"filtered\"` without pagination);\n * - `\"selected\"` — the current selection.\n */\n scope?: \"filtered\" | \"all\" | \"page\" | \"selected\";\n delimiter?: string;\n /**\n * Include the header line. Default true.\n */\n withHeaders?: boolean;\n /**\n * Prefix text a spreadsheet would evaluate as a formula (leading `=`, `+`, `-`, `@`, tab or\n * CR — the OWASP CSV-injection set) with a `'`. Applies to header text and string-valued\n * cells; numeric cells keep their sign. Default false — the quote is data to every\n * non-spreadsheet consumer, so it is opt-in for exports that feed spreadsheets.\n */\n escapeFormulas?: boolean;\n}\n\nexport function toCsv<TData extends RowData>(table: TableInstance<TData>, options: ToCsvOptions = {}): string {\n const {\n scope = \"filtered\",\n delimiter = \",\",\n withHeaders = true,\n escapeFormulas = false\n } = options;\n\n const rows = rowsForScope(table, scope);\n\n const columns = [\n ...table.getStartVisibleLeafColumns(),\n ...table.getCenterVisibleLeafColumns(),\n ...table.getEndVisibleLeafColumns()\n ].filter(column => !isInternalColumn(column.id)\n && column.accessorFn !== undefined\n && column.columnDef.meta?.export !== false);\n\n const lines: string[] = [];\n\n if (withHeaders) {\n lines.push(\n columns\n .map(column => {\n const text = exportHeaderText(column);\n\n return escapeCsvValue(escapeFormulas ? defuseFormula(text) : text, delimiter);\n })\n .join(delimiter)\n );\n }\n\n for (const row of rows) {\n lines.push(\n columns\n .map(column => {\n const raw = exportCellValue(column, row);\n const text = serializeCsvValue(raw);\n\n // Only string cells can smuggle a formula; serialized numbers keep their sign.\n return escapeCsvValue(escapeFormulas && typeof raw === \"string\" ? defuseFormula(text) : text, delimiter);\n })\n .join(delimiter)\n );\n }\n\n return lines.join(\"\\r\\n\");\n}\n\nfunction rowsForScope<TData extends RowData>(table: TableInstance<TData>, scope: NonNullable<ToCsvOptions[\"scope\"]>) {\n switch (scope) {\n case \"selected\": {\n // `rows` is the selected *tree*: a row only appears there if it is selected itself, so a\n // selected child of an unselected parent is nowhere in it. `flatRows` is every selected\n // row, each once, in the order they are drawn.\n return table.getSelectedRowModel().flatRows;\n }\n\n case \"all\": {\n return table.getCoreRowModel().rows;\n }\n\n case \"page\": {\n return table.getRowModel().rows;\n }\n\n case \"filtered\": {\n return table.getPrePaginatedRowModel().rows;\n }\n }\n}\n\nfunction exportHeaderText<TData extends RowData>(column: Column<TData, unknown>): string {\n const exportMeta = column.columnDef.meta?.export;\n\n return (typeof exportMeta === \"object\" ? exportMeta.header : undefined) ?? columnHeaderText(column);\n}\n\nfunction exportCellValue<TData extends RowData>(column: Column<TData, unknown>, row: Row<TData>): unknown {\n const exportMeta = column.columnDef.meta?.export;\n\n return typeof exportMeta === \"object\" && exportMeta.value\n ? exportMeta.value(row)\n : row.getValue(column.id);\n}\n\nfunction serializeCsvValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n\n return String(value);\n}\n\nconst FORMULA_LEAD = /^[=+\\-@\\t\\r]/;\n\nfunction defuseFormula(value: string): string {\n return FORMULA_LEAD.test(value) ? `'${value}` : value;\n}\n\nfunction escapeCsvValue(value: string, delimiter: string): string {\n if (value.includes(\"\\\"\") || value.includes(delimiter) || value.includes(\"\\n\") || value.includes(\"\\r\")) {\n return `\"${value.replaceAll(\"\\\"\", \"\\\"\\\"\")}\"`;\n }\n\n return value;\n}\n","import clsx from \"clsx\";\n\n/**\n * React's HTML attribute types enumerate every `aria-*` attribute but no `data-*` one: JSX\n * accepts them through a compiler special case that an object literal does not get. The escape\n * hatch therefore admits them explicitly — `data-*` is half the point of it.\n */\nexport type DataAttributes = Record<`data-${string}`, string | number | boolean | null | undefined>;\n\n/**\n * The DOM escape hatch (docs/styling.md#dom-props): every rendered row, cell, and header cell\n * accepts consumer props — attributes, `data-*`, `aria-*`, inline styles, extra handlers —\n * either as a static object or as a function of the element's subject.\n *\n * `ref` is deliberately excluded from every one of these types: they are declarative prop hooks\n * resolved per render (per virtual item, for rows), not component instances, and ledger already\n * owns the row ref for virtualization measurement.\n */\nexport type DataTableElementProps<TProps, TSubject>\n = | (TProps & DataAttributes)\n | ((subject: TSubject) => (TProps & DataAttributes) | undefined);\n\nexport function resolveElementProps<TProps, TSubject>(\n props: DataTableElementProps<TProps, TSubject> | undefined,\n subject: TSubject\n): (TProps & DataAttributes) | undefined {\n return typeof props === \"function\"\n ? (props as (subject: TSubject) => (TProps & DataAttributes) | undefined)(subject)\n : props;\n}\n\n/**\n * Compose consumer props with ledger's own, with four rules:\n *\n * - ledger's structural props win — `role`, the `data-*` state contract and the ARIA indices are\n * the styling and semantic contract, not suggestions;\n * - but only where ledger actually sets one: an owned key holding `undefined` means \"ledger has\n * no opinion here\" and must not erase the consumer's value;\n * - `className` and `style` compose, consumer last — an escape hatch that silently dropped an\n * author's declaration would not be one, so overriding a ledger inline value (a pinned cell's\n * sticky offset, say) is possible and is the author's to own;\n * - a handler present on both sides chains, ledger's first (its stop-propagation covenant and\n * active-row bookkeeping run before the consumer sees the event).\n */\nexport function mergeElementProps<TOwned extends Record<string, any>>(\n consumer: Record<string, any> | undefined,\n owned: TOwned\n): TOwned {\n if (!consumer) {\n return owned;\n }\n\n const merged: Record<string, any> = { ...consumer };\n\n for (const [key, ownedValue] of Object.entries(owned)) {\n const consumerValue = consumer[key];\n\n if (\n key.startsWith(\"on\")\n && typeof ownedValue === \"function\"\n && typeof consumerValue === \"function\"\n ) {\n merged[key] = (...args: unknown[]) => {\n ownedValue(...args);\n consumerValue(...args);\n };\n } else if (ownedValue !== undefined) {\n // An owned key holding `undefined` is \"no opinion\", and React reads a missing prop and an\n // undefined one alike — so skipping the write leaves the consumer's value standing.\n merged[key] = ownedValue;\n }\n }\n\n const className = clsx(owned.className, consumer.className);\n\n merged.className = className === \"\" ? undefined : className;\n\n if (consumer.style || owned.style) {\n merged.style = { ...owned.style, ...consumer.style };\n }\n\n return merged as TOwned;\n}\n","/**\n * Environment probing — deliberately dependency-free so it stays importable (and testable)\n * in environments where the rest of the graph cannot load.\n */\n\n/**\n * Bundlers replace `process.env.NODE_ENV`; the local declaration keeps package sources free of ambient node types.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention -- mirrors the platform env var name verbatim\ndeclare const process: { env: { NODE_ENV?: string } };\n\n/**\n * The mode, read from the one expression every bundler replaces.\n *\n * It has to be read *unguarded* for that to work. Vite substitutes `process.env.NODE_ENV`\n * textually in client code — dev server included, and that covers library source served through\n * the `source` export condition — so a `typeof process` guard in front of it short-circuits in\n * the browser before the substituted value is ever reached, and every dev guard goes quiet\n * exactly where a developer is looking at the console. Guarding it the other way round is worse:\n * \"no `process` object at runtime\" would then mean development, and in a browser that is what a\n * production bundle looks like, so the warning channel survives into production.\n *\n * So the read comes first and the *failure* is what is caught. Where something replaced the\n * expression, the value decides and the production build folds to `false`; where nothing did —\n * a bundle shipped without a `process` shim — the read throws and the answer is \"not\n * development\", which is the safe way to be wrong.\n *\n * Exported as a function so the regression test can probe it under a synchronously scoped\n * `process` stub — holding the stub across an async module re-import breaks the test runner's\n * own internals.\n */\nexport function computeIsDev(): boolean {\n let nodeEnv: string | undefined;\n\n try {\n nodeEnv = process.env.NODE_ENV;\n } catch {\n nodeEnv = undefined;\n }\n\n return nodeEnv !== undefined && nodeEnv !== \"production\";\n}\n\nexport const isDev: boolean = computeIsDev();\n\nconst emittedWarnings = new Set<string>();\n\n/**\n * Dev-only, once-per-session warning — the guard-rail channel catalogued in docs/state.md.\n */\nexport function warnOnce(key: string, message: string): void {\n if (!isDev || emittedWarnings.has(key)) {\n return;\n }\n\n emittedWarnings.add(key);\n\n console.warn(`[ledger] ${message}`);\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { SortToggleSpec } from \"./toggle-fns\";\nimport type { LedgerMeta } from \"./types\";\nimport type { LedgerExpansionController, LedgerSelectionController } from \"./use-row-commands\";\n\n/**\n * The row-state toggles, kept off the public `LedgerMeta`.\n *\n * `LedgerMeta` is exported and documented (docs/api.md) — it is what an application reads when it\n * reaches into `table.options.meta.ledger`. These controllers are ledger's own plumbing between\n * the hook and its controls, so they ride the same object without being part of that contract:\n * `useDataTable` builds a `LedgerInternalMeta`, and the few internal readers ask for them by way\n * of `ledgerCommands`.\n */\n\nexport interface LedgerSortingController {\n toggle: (spec: SortToggleSpec, multi: boolean) => void;\n}\n\nexport interface LedgerCommands {\n sorting: LedgerSortingController;\n selection: LedgerSelectionController;\n expansion: LedgerExpansionController;\n}\n\nexport type LedgerInternalMeta<TData extends RowData> = LedgerCommands & LedgerMeta<TData>;\n\nexport function ledgerCommands(meta: LedgerMeta<any> | undefined): LedgerCommands | undefined {\n return meta as LedgerInternalMeta<any> | undefined;\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { CSSProperties } from \"react\";\n\nimport type { DataTableLabels } from \"./labels\";\nimport type { TableInstance } from \"./types\";\n\n/**\n * The pagination bar: summary on the start side, rows-per-page and page controls on the end\n * side. One core rendering, two skins — the built-in bar (inside <DataTable>, styled through the\n * Styles API) and the standalone `DataTable.Pagination` compound for custom placement.\n * TanStack's 0-based `pageIndex` converts to Mantine `Pagination`'s 1-based `value` here and\n * nowhere else.\n */\nimport { Group, Pagination, Select, Text, useProps } from \"@mantine/core\";\nimport clsx from \"clsx\";\nimport { useId } from \"react\";\n\nimport { useDataTableContext } from \"./context\";\nimport { resolveLabels } from \"./labels\";\n\nexport const DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 50, 100];\n\ninterface PaginationBarCoreProps<TData extends RowData> {\n table: TableInstance<TData>;\n labels: DataTableLabels;\n pageSizeOptions: number[];\n className?: string;\n style?: CSSProperties;\n}\n\nfunction PaginationBarCore<TData extends RowData>({\n table,\n labels,\n pageSizeOptions,\n className,\n style\n}: PaginationBarCoreProps<TData>) {\n const pageSizeLabelId = useId();\n const { pageIndex, pageSize } = table.atoms.pagination.get();\n // `options.rowCount` (server mode) wins inside TanStack; client mode counts pre-paginated rows.\n const total = table.getRowCount();\n const pageCount = Math.max(1, table.getPageCount());\n const from = total === 0 ? 0 : pageIndex * pageSize + 1;\n const to = Math.min(total, (pageIndex + 1) * pageSize);\n // The size on screen is always offerable, whoever set it: a controlled `pagination` (or a\n // persisted one) may hold a size the author never listed, and a Select whose value is absent\n // from its data renders blank. Always de-duplicated and ascending, so the list a reader sees\n // does not depend on how the current size got there.\n const sizeOptions = [...new Set([...pageSizeOptions, pageSize])].toSorted((left, right) => left - right);\n\n return (\n <Group className={className} gap=\"md\" justify=\"space-between\" style={style} wrap=\"wrap\">\n <Text c=\"dimmed\" size=\"sm\">\n {labels.paginationSummary(from, to, total)}\n </Text>\n\n <Group gap=\"md\" wrap=\"nowrap\">\n <Group gap=\"xs\" wrap=\"nowrap\">\n {/* The visible text IS the label — pointing at it beats duplicating it into an\n aria-label, which would let the two drift apart (WCAG 2.5.3, label in name). */}\n <Text key=\"label\" c=\"dimmed\" id={pageSizeLabelId} size=\"sm\">\n {labels.rowsPerPage}\n </Text>\n\n <Select\n allowDeselect={false}\n aria-labelledby={pageSizeLabelId}\n data={sizeOptions.map(String)}\n size=\"xs\"\n value={String(pageSize)}\n w={84}\n onChange={value => value !== null && table.setPageSize(Number(value))}\n />\n </Group>\n\n <Pagination\n size=\"sm\"\n total={pageCount}\n value={pageIndex + 1}\n onChange={page => table.setPageIndex(page - 1)}\n />\n </Group>\n </Group>\n );\n}\n\n/**\n * The built-in bar rendered by <DataTable> (context-styled).\n */\nexport function PaginationBar<TData extends RowData>({ table, pageSizeOptions }: { table: TableInstance<TData>; pageSizeOptions: number[] }) {\n const { labels, getStyles } = useDataTableContext();\n const { className, style } = getStyles(\"paginationBar\");\n\n return (\n <PaginationBarCore\n className={className}\n labels={labels}\n pageSizeOptions={pageSizeOptions}\n style={style}\n table={table}\n />\n );\n}\n\nexport interface DataTablePaginationProps<TData extends RowData> {\n table: TableInstance<TData>;\n pageSizeOptions?: number[];\n labels?: Partial<DataTableLabels>;\n className?: string;\n style?: CSSProperties;\n}\n\nconst paginationDefaultProps = {} satisfies Partial<DataTablePaginationProps<RowData>>;\n\n/**\n * Standalone compound (`DataTable.Pagination`) — place it anywhere, theme it via defaultProps.\n */\nexport function DataTablePagination<TData extends RowData>(props: DataTablePaginationProps<TData>) {\n const {\n table,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n labels,\n className,\n style\n } = useProps(\"DataTablePagination\", paginationDefaultProps, props);\n\n return (\n <PaginationBarCore\n className={clsx(\"ledger-pagination-bar\", className)}\n labels={resolveLabels(labels)}\n pageSizeOptions={pageSizeOptions}\n style={style}\n table={table}\n />\n );\n}\n","import type { TextInputProps } from \"@mantine/core\";\nimport type { RowData } from \"@tanstack/react-table\";\n\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { TableInstance } from \"./types\";\n\n/**\n * `DataTable.Search` — the global-filter input, debounced. A standalone compound: takes the\n * table instance, composes anywhere (toolbars are the page's territory).\n */\nimport { CloseButton, TextInput, useProps } from \"@mantine/core\";\nimport { useDebouncedCallback } from \"@mantine/hooks\";\nimport { useEffect, useState } from \"react\";\n\nimport { resolveIcons } from \"./icons\";\nimport { resolveLabels } from \"./labels\";\n\nexport interface DataTableSearchProps<TData extends RowData>\n extends Omit<TextInputProps, \"value\" | \"defaultValue\" | \"onChange\"> {\n table: TableInstance<TData>;\n /**\n * Debounce before the global filter applies, in milliseconds.\n */\n debounce?: number;\n labels?: Partial<DataTableLabels>;\n icons?: Partial<DataTableIcons>;\n}\n\nconst searchDefaultProps = { debounce: 200 } satisfies Partial<DataTableSearchProps<RowData>>;\n\nexport function DataTableSearch<TData extends RowData>(props: DataTableSearchProps<TData>) {\n const {\n table,\n debounce,\n labels,\n icons,\n placeholder,\n ...others\n } = useProps(\n \"DataTableSearch\",\n searchDefaultProps,\n props\n );\n\n const resolved = resolveLabels(labels);\n const resolvedIcons = resolveIcons(icons);\n const globalFilter = (table.atoms.globalFilter.get() as string | undefined) ?? \"\";\n const [value, setValue] = useState(globalFilter);\n\n const apply = useDebouncedCallback((next: string) => table.setGlobalFilter(next), debounce);\n const subscribeGlobalFilter = table.options.meta?.ledger?.filtering.subscribeGlobalFilter;\n\n // A reset to the current table value is invisible to React state. Subscribe to set attempts so\n // it still cancels a pending local value before that value can write itself back later.\n useEffect(() => subscribeGlobalFilter?.(next => {\n apply.cancel();\n setValue(next);\n }), [apply, subscribeGlobalFilter]);\n\n // Follow external changes (a programmatic reset, a controlled slice) once they settle.\n useEffect(() => {\n apply.cancel();\n setValue(globalFilter);\n }, [apply, globalFilter]);\n\n const clear = () => {\n apply.cancel();\n setValue(\"\");\n table.setGlobalFilter(\"\");\n };\n\n const resolvedPlaceholder = placeholder ?? resolved.searchPlaceholder;\n\n return (\n <TextInput\n // A placeholder is not a label — it disappears the moment there is a value. The visible\n // text doubles as the name so the two never disagree; `others` lets a caller override it.\n aria-label={resolvedPlaceholder}\n leftSection={<resolvedIcons.search />}\n placeholder={resolvedPlaceholder}\n rightSectionPointerEvents=\"all\"\n value={value}\n rightSection={value !== \"\"\n && <CloseButton aria-label={resolved.clearFilter} size=\"sm\" onClick={clear} />}\n onChange={event => {\n setValue(event.currentTarget.value);\n apply(event.currentTarget.value);\n }}\n {...others}\n />\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { TableInstance } from \"./types\";\n\n/**\n * `DataTable.SelectionBar` — renders only while rows are selected: the count, a clear action,\n * and whatever bulk actions the page passes as children.\n */\nimport { Button, Group, Text, useProps } from \"@mantine/core\";\nimport clsx from \"clsx\";\n\nimport { resolveIcons } from \"./icons\";\nimport { resolveLabels } from \"./labels\";\n\nexport interface DataTableSelectionBarProps<TData extends RowData> {\n table: TableInstance<TData>;\n labels?: Partial<DataTableLabels>;\n icons?: Partial<DataTableIcons>;\n /**\n * Bulk actions, rendered after the count and clear control.\n */\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nconst selectionBarDefaultProps = {} satisfies Partial<DataTableSelectionBarProps<RowData>>;\n\nexport function DataTableSelectionBar<TData extends RowData>(props: DataTableSelectionBarProps<TData>) {\n const {\n table,\n labels,\n icons,\n children,\n className,\n style\n } = useProps(\n \"DataTableSelectionBar\",\n selectionBarDefaultProps,\n props\n );\n\n const resolved = resolveLabels(labels);\n const resolvedIcons = resolveIcons(icons);\n // The selection state's own count, deliberately — not `getSelectedRowModel().flatRows.length`.\n // That model resolves the state against the rows the table actually holds, which under server\n // pagination is one page: a bar counting it would drop everything selected on the pages that\n // are no longer loaded, and the id-keyed state is precisely what survives paging\n // (docs/selection.md). The corollary is that ids the data no longer holds still count, which is\n // the same reason selection requires a stable `getRowId`.\n const count = Object.values(table.atoms.rowSelection.get()).filter(Boolean).length;\n\n if (count === 0) {\n return null;\n }\n\n return (\n <Group className={clsx(\"ledger-selection-bar\", className)} gap=\"sm\" style={style}>\n <Text fw={500} size=\"sm\">\n {resolved.selectedCount(count)}\n </Text>\n\n <Button\n leftSection={<resolvedIcons.clearSelection />}\n size=\"compact-xs\"\n variant=\"subtle\"\n onClick={() => table.resetRowSelection()}\n >\n {resolved.clearSelection}\n </Button>\n\n {children}\n </Group>\n );\n}\n","/**\n * What the editing gate is, as the predicates every path shares: how a column's `meta.edit` is\n * read, whether a cell may be edited *right now*, and how a thrown value becomes a message. Not\n * referentially pure, and the difference matters — `canEditCell` calls the application's own\n * `edit.enabled(row)`, which may answer differently with no render in between, which is why the\n * render layer, the commits and the checkbox toggle each ask again rather than cache an answer\n * (docs/architecture.md). The session controllers and the editors both need these, and a\n * controller must not depend on a view module to get them.\n */\nimport type { Cell, DataTableEditRenderer, DataTableInstantEditRenderer, Row } from \"./types\";\n\n/**\n * One shape for every `meta.edit` form: which interaction model the column declared, its\n * renderer, and the gates. `validate` and `enabled` ride any kind — they are the session's\n * gate and gatekeeper, not properties of the control being rendered.\n */\nexport type NormalizedEdit\n = | {\n kind: \"session\";\n render: DataTableEditRenderer<any, unknown>;\n enabled?: (row: Row<any>) => boolean;\n validate?: (value: unknown, row: Row<any>) => string | null;\n }\n | {\n kind: \"instant\";\n render: DataTableInstantEditRenderer<any, unknown>;\n enabled?: (row: Row<any>) => boolean;\n validate?: (value: unknown, row: Row<any>) => string | null;\n };\n\nexport function editErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function normalizeEdit(\n edit: NonNullable<Cell<any, unknown>[\"column\"][\"columnDef\"][\"meta\"]>[\"edit\"]\n): NormalizedEdit | null {\n if (!edit) {\n return null;\n }\n\n if (typeof edit === \"function\") {\n return { kind: \"session\", render: edit };\n }\n\n if (\"instant\" in edit) {\n return {\n kind: \"instant\",\n render: edit.instant,\n enabled: edit.enabled,\n validate: edit.validate\n };\n }\n\n return {\n kind: \"session\",\n render: edit.render,\n enabled: edit.enabled,\n validate: edit.validate as NormalizedEdit[\"validate\"]\n };\n}\n\n/**\n * The value the cell of *this* render holds, through its own column's accessor.\n *\n * Not `cell.getValue()`: upstream caches a row's values on the row object, and that cache is only\n * rebuilt when `data` changes — so a column whose `accessorFn` changed under the same data would\n * go on answering with the accessor it had before, and an editor drawing from it would show a\n * value the table has stopped holding. Resolving here also means a redraw between renders cannot\n * pick up a definition from a render pass that never reached the screen.\n */\nexport function cellValue(cell: Cell<any, unknown>): unknown {\n return cell.column.accessorFn?.(cell.row.original, cell.row.index);\n}\n\nexport interface EditGate {\n enableEditing: boolean;\n /**\n * The commit belongs to the application (docs/editing.md), so the handler for the live mode is\n * part of the gate: without it an edit has nowhere to go, and offering one anyway means opening\n * an editor, validating it, closing it \"successfully\", and writing nothing.\n */\n hasCommitHandler: boolean;\n}\n\n/**\n * The gate itself, over values the caller supplies: the switch and handler of one render, the\n * column's `meta.edit` as that render defined it, and the row it resolved. Every caller decides\n * which render that is — the one being drawn, or the one that reached the screen — because the\n * core they would otherwise read it from carries whichever pass ran last, committed or not\n * (see `use-committed-table.ts`).\n */\nexport function canEditWith(\n row: Row<any>,\n edit: NonNullable<Cell<any, unknown>[\"column\"][\"columnDef\"][\"meta\"]>[\"edit\"],\n gate: EditGate\n): boolean {\n if (!gate.enableEditing || !gate.hasCommitHandler) {\n return false;\n }\n\n if (!edit) {\n return false;\n }\n\n return !(typeof edit === \"object\" && edit.enabled && !edit.enabled(row));\n}\n\n/**\n * Whether this cell is editable in the render being drawn. Render-phase only: it reads the\n * definitions and switches through the cell's own table, which is the core — correct while a\n * render is in progress, and a trap at event time.\n */\nexport function canEditCell(cell: Cell<any, unknown>, row: Row<any>): boolean {\n const { table } = cell.getContext();\n const ledger = table.options.meta?.ledger;\n\n return canEditWith(row, cell.column.columnDef.meta?.edit, {\n enableEditing: ledger?.enableEditing ?? false,\n hasCommitHandler: Boolean(ledger && (ledger.editing.mode === \"row\" ? ledger.onRowEditCommit : ledger.onEditCommit))\n });\n}\n","import type { KeyboardEvent } from \"react\";\n\nimport type { Cell } from \"./types\";\n\n/**\n * The editor hosts, for both modes. Each is a view of its session plus a keyboard surface: the\n * draft, the validation, the in-flight commit and the failure all belong to the controller, so\n * that a hidden column or a virtual scroll unmounting an editor takes nothing with it\n * (docs/architecture.md). The host renders no control of its own — the renderer the column\n * declared does (docs/editing.md#editors) — it supplies the context, the keyboard map, the blur\n * commit, and the pending presentation around it.\n */\nimport { Loader } from \"@mantine/core\";\nimport { useLayoutEffect, useReducer, useRef } from \"react\";\n\nimport { columnHeaderText } from \"./build-columns\";\nimport { useDataTableContext } from \"./context\";\nimport { cellValue, normalizeEdit } from \"./edit-meta\";\nimport { useEventCallback } from \"./utils\";\n\nexport { canEditCell } from \"./edit-meta\";\n\nexport function CellEditor({ cell }: { cell: Cell<any, unknown> }) {\n const { labels, getStyles } = useDataTableContext();\n const { table } = cell.getContext();\n const editing = table.options.meta?.ledger?.editing;\n const normalized = normalizeEdit(cell.column.columnDef.meta?.edit);\n const rowId = cell.row.id;\n const columnId = cell.column.id;\n\n const [, redraw] = useReducer((token: number) => token + 1, 0);\n const redrawFromSession = useEventCallback(() => redraw());\n\n // Layout, not passive: the registry is what \"on screen right now\" means to the session, and a\n // commit that unmounts this editor is followed by microtasks — a settling write among them —\n // long before a passive cleanup would run.\n const register = editing?.register;\n\n // Bound to the controller and the cell, not to this component's lifetime: in hook mode the\n // table can be swapped for another instance while React keeps this editor, and a registration\n // left with the controller that is gone means the one now in charge cannot reach it.\n useLayoutEffect(\n () => register?.(rowId, columnId, { redraw: redrawFromSession }),\n [register, rowId, columnId, redrawFromSession]\n );\n\n // An instant column has no session for this host to draw — a change in the cell is the commit\n // (docs/editing.md#instant-editing) — so a programmatic `startEditing` on one renders nothing.\n if (!normalized || normalized.kind === \"instant\" || !editing) {\n return null;\n }\n\n const draft = editing.drafts.read(rowId, columnId, cellValue(cell));\n const editError = editing.drafts.error(rowId, columnId);\n const pending = editing.drafts.pending(rowId, columnId);\n\n const setValue = (value: unknown) => {\n editing.drafts.write(rowId, columnId, value);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case \"Enter\": {\n event.preventDefault();\n void editing.commit();\n\n break;\n }\n\n case \"Escape\": {\n event.preventDefault();\n event.stopPropagation();\n editing.cancel();\n\n break;\n }\n\n case \"Tab\": {\n event.preventDefault();\n // The session owns the move: where the caret goes next depends on the row as the screen\n // has it, and this editor could only ask the shared core (docs/architecture.md).\n editing.moveTo(event.shiftKey);\n\n break;\n }\n // No default\n }\n };\n\n const editor = normalized.render({\n row: cell.row,\n column: cell.column,\n value: draft,\n setValue,\n commit: () => editing.commit(),\n cancel: () => editing.cancel(),\n error: editError,\n pending,\n mode: \"cell\",\n autoFocus: true,\n label: labels.editColumn(columnHeaderText(cell.column))\n });\n\n return (\n <div\n aria-busy={pending || undefined}\n aria-label={pending ? labels.editPending : undefined}\n data-pending={pending || undefined}\n onBlur={event => {\n // Blur commits — unless focus moved elsewhere inside the editor (e.g. a select option).\n if (!event.currentTarget.contains(event.relatedTarget)) {\n editing.commit();\n }\n }}\n onClick={event => event.stopPropagation()}\n onDoubleClick={event => event.stopPropagation()}\n onKeyDown={handleKeyDown}\n {...getStyles(\"cellEditor\")}\n >\n {editor}\n {pending && <Loader size={12} />}\n </div>\n );\n}\n\n/**\n * The row-mode editor host (docs/editing.md#row-mode): one per editable cell of the editing\n * row, all mounted at once. Drafts write through to the controller's store (they must survive\n * a virtualized unmount), blur never commits, and Enter/Escape commit or cancel the whole row.\n */\nexport function RowCellEditor({ cell }: { cell: Cell<any, unknown> }) {\n const { labels, getStyles } = useDataTableContext();\n const { table } = cell.getContext();\n const editing = table.options.meta?.ledger?.editing;\n const rowApi = editing?.row;\n const normalized = normalizeEdit(cell.column.columnDef.meta?.edit);\n const columnId = cell.column.id;\n const rowId = cell.row.id;\n\n // The store is the value, not a copy of it: what the row holds moves under an open editor —\n // the application feeds a write back, normalizes it, or the controller throws the edit away —\n // and local state would go on showing a value the row had already left behind. Rendering is\n // the only thing left to ask for.\n const [, redraw] = useReducer((token: number) => token + 1, 0);\n const draft = rowApi ? rowApi.drafts.read(rowId, columnId, cellValue(cell)) : cellValue(cell);\n const editError = rowApi?.drafts.error(rowId, columnId) ?? null;\n const pending = rowApi?.drafts.pending(rowId) ?? false;\n const containerRef = useRef<HTMLDivElement | null>(null);\n // Ref-read, not consumed — StrictMode's remount and virtualizer round-trips keep the focus.\n const autoFocus = rowApi?.shouldFocus(columnId) ?? false;\n\n const setValue = useEventCallback((value: unknown) => {\n rowApi?.drafts.write(rowId, columnId, value);\n redraw();\n });\n\n /**\n * Everything this editor shows lives in the session, so a change there is answered by drawing\n * again — there is nothing here to put back.\n */\n const redrawFromSession = useEventCallback(() => redraw());\n\n const focusEditor = useEventCallback(() => {\n containerRef.current\n ?.querySelector<HTMLElement>(\":scope input, :scope select, :scope textarea, :scope button\")\n ?.focus();\n });\n const register = rowApi?.register;\n\n // Layout, not passive: the registry is what \"on screen right now\" means to the session, and a\n // commit that unmounts this editor is followed by microtasks — a settling write among them —\n // long before a passive cleanup would have run. A registration that outlives its DOM would put\n // a failure on a column nobody can see. Bound to the controller and the column, not to this\n // component's lifetime: in hook mode the table can be swapped for another instance while React\n // keeps this editor, and a registration left with the controller that is gone means the one\n // now in charge cannot reach it.\n useLayoutEffect(() => register?.(columnId, { focus: focusEditor, redraw: redrawFromSession }), [register, columnId, focusEditor, redrawFromSession]);\n\n if (!normalized || !editing) {\n return null;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // An inner control that consumed the key (a select picking its option) keeps it.\n if (event.defaultPrevented) {\n return;\n }\n\n if (event.key === \"Enter\") {\n event.preventDefault();\n editing.row.stop({ commit: true });\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n editing.row.stop({ commit: false });\n }\n };\n\n const label = labels.editColumn(columnHeaderText(cell.column));\n\n const editor\n = normalized.kind === \"instant\"\n ? normalized.render({\n row: cell.row,\n column: cell.column,\n value: draft,\n // In row mode an instant control joins the row like any other editor: its commit\n // stages the value in the row draft, and the atomic row commit owns the write\n // (docs/editing.md#instant-editing).\n commit: (value: unknown) => {\n setValue(value);\n\n return true;\n },\n error: editError,\n pending,\n label\n })\n : normalized.render({\n row: cell.row,\n column: cell.column,\n value: draft,\n setValue,\n // Row mode: commit/cancel operate on the whole row, matching the keyboard map. The\n // result is the row's real one — validation across every editable column, and the\n // application's handler — not an acknowledgement that the request was made.\n commit: () => editing.row.commit(),\n cancel: () => editing.row.stop({ commit: false }),\n error: editError,\n pending,\n mode: \"row\",\n autoFocus,\n label\n });\n\n return (\n <div\n ref={containerRef}\n aria-busy={pending || undefined}\n aria-label={pending ? labels.editPending : undefined}\n data-pending={pending || undefined}\n onClick={event => event.stopPropagation()}\n onDoubleClick={event => event.stopPropagation()}\n onKeyDown={handleKeyDown}\n {...getStyles(\"cellEditor\")}\n >\n {editor}\n {pending && <Loader size={12} />}\n </div>\n );\n}\n","/**\n * Pinned-column geometry. Offsets are referenced as CSS variables (written table-level next to\n * the width variables), so a resize drag updates one style object and never re-renders rows;\n * TanStack v9's logical `start`/`end` positions pair with logical insets, so RTL mirrors for\n * free.\n */\nimport type { RowData } from \"@tanstack/react-table\";\nimport type { CSSProperties } from \"react\";\n\nimport type { Column } from \"./types\";\n\nimport { columnAfterVar, columnStartVar } from \"./utils\";\n\nexport function pinnedCellStyle<TData extends RowData>(column: Column<TData, unknown>): CSSProperties | undefined {\n const pinned = column.getIsPinned();\n\n if (pinned === \"start\") {\n return { insetInlineStart: `var(${columnStartVar(column.id)})` };\n }\n\n if (pinned === \"end\") {\n return { insetInlineEnd: `var(${columnAfterVar(column.id)})` };\n }\n\n return undefined;\n}\n\n/**\n * The boundary cell of a pinned block — where the scroll shadow renders.\n */\nexport function pinnedEdge<TData extends RowData>(column: Column<TData, unknown>): \"start\" | \"end\" | undefined {\n if (column.getIsPinned() === \"start\" && column.getIsLastColumn(\"start\")) {\n return \"start\";\n }\n\n if (column.getIsPinned() === \"end\" && column.getIsFirstColumn(\"end\")) {\n return \"end\";\n }\n\n return undefined;\n}\n","import type { PointerEvent } from \"react\";\n\n/**\n * The tooltip behind `meta.truncate` (docs/columns.md) and the header label.\n *\n * Resolved at hover time from the element itself, for three reasons the old render-time\n * `title={cell.getValue()}` got wrong: the rendered text is what is actually clipped (a custom\n * `cell` renderer's output included), a non-primitive value still has readable text, and a\n * tooltip is only worth having when the text really overflows.\n *\n * Deliberately imperative: measuring every truncated cell on every render would thrash layout\n * across a virtualized body, and the read here happens once, on the hover that precedes the\n * browser's own tooltip delay. Native `title` therefore reaches pointer users only — a richer\n * tooltip is a `meta.cellProps` or custom `cell` job.\n */\nexport function syncTruncationTitle(event: PointerEvent<HTMLElement>): void {\n const element = event.currentTarget;\n const text = element.scrollWidth > element.clientWidth ? element.textContent : null;\n\n if (text === null || text === \"\") {\n element.removeAttribute(\"title\");\n } else {\n element.title = text;\n }\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Header } from \"./types\";\n\n/**\n * Column virtualization (docs/virtualization.md#column-virtualization). Only the center zone\n * windows — pinned columns are sticky and always mounted — and the window is the width\n * engine's own numbers, not a second virtualizer: every column width is already an exact\n * integer pixel (use-column-widths.ts), so the rendered range is a binary search over their\n * prefix sums, derived in the same render pass that draws the colgroup. A measuring\n * virtualizer would hold a parallel copy of the horizontal geometry that resize, responsive\n * breakpoints, and grow redistribution would each have to invalidate by hand.\n */\nimport { startTransition, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\n\nimport { useEventCallback } from \"./utils\";\n\nconst DEFAULT_COLUMN_OVERSCAN = 4;\n\nexport { DEFAULT_COLUMN_OVERSCAN };\n\nexport interface ColumnWindowInput {\n enabled: boolean;\n /**\n * Extra columns rendered beyond the visible range on each side.\n */\n overscan: number;\n viewport: HTMLDivElement | null;\n /**\n * Visible center leaf column ids in display order — the zone that windows.\n */\n centerColumnIds: readonly string[];\n /**\n * The width engine's resolved integer pixels per visible leaf column id.\n */\n widths: Record<string, number>;\n /**\n * The sticky pinned overlays narrow the visible center strip by their summed widths.\n */\n pinnedStartWidth: number;\n pinnedEndWidth: number;\n}\n\nexport interface ColumnWindow {\n /**\n * The rendered center slice, `[start, end)` over the center zone.\n */\n start: number;\n end: number;\n /**\n * Widths of the not-rendered runs — the two spacer `<col>`s.\n */\n leadingSpace: number;\n trailingSpace: number;\n}\n\n/**\n * The render-facing descriptor: the window plus the display geometry every renderer tiles by.\n */\nexport interface ColumnWindowView extends ColumnWindow {\n pinnedStartCount: number;\n pinnedEndCount: number;\n centerCount: number;\n /**\n * Total visible leaf columns — `aria-colcount`.\n */\n totalLeafCount: number;\n /**\n * Display index (pinned-aware) per visible leaf column id; `aria-colindex` is this + 1.\n */\n displayIndexById: ReadonlyMap<string, number>;\n}\n\n/**\n * First index whose value is greater than `target` (`values` ascending).\n */\nfunction upperBound(values: readonly number[], target: number): number {\n let low = 0;\n let high = values.length;\n\n while (low < high) {\n const mid = (low + high) >> 1;\n\n if (values[mid]! <= target) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n\n return low;\n}\n\n/**\n * First index whose value is at least `target` (`values` ascending).\n */\nfunction lowerBound(values: readonly number[], target: number): number {\n let low = 0;\n let high = values.length;\n\n while (low < high) {\n const mid = (low + high) >> 1;\n\n if (values[mid]! < target) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n\n return low;\n}\n\n/**\n * The measured window over `[0, centerCount)` given a scroll position: the columns whose spans\n * intersect the visible center strip, extended by `overscan` on each side. Pure — the hook's\n * unit-testable core.\n */\nexport function measureColumnWindow(input: {\n offsets: readonly number[];\n scrollLeft: number;\n clientWidth: number;\n pinnedStartWidth: number;\n pinnedEndWidth: number;\n overscan: number;\n}): { start: number; end: number } {\n const count = input.offsets.length - 1;\n // RTL viewports report a negative scrollLeft; the window only needs the distance scrolled.\n const from = Math.abs(input.scrollLeft);\n const to = from + Math.max(0, input.clientWidth - input.pinnedStartWidth - input.pinnedEndWidth);\n const first = Math.max(0, upperBound(input.offsets, from) - 1);\n const last = Math.max(first + 1, lowerBound(input.offsets, to));\n\n return {\n start: Math.max(0, first - input.overscan),\n end: Math.min(count, last + input.overscan)\n };\n}\n\nexport function useColumnWindow({\n enabled,\n overscan,\n viewport,\n centerColumnIds,\n widths,\n pinnedStartWidth,\n pinnedEndWidth\n}: ColumnWindowInput): ColumnWindow | null {\n // Prefix sums over the center zone: offsets[i] is where column i starts, offsets at the end\n // is the zone's total width.\n const offsets = useMemo(\n () => {\n const out: number[] = [0];\n let sum = 0;\n\n for (const id of centerColumnIds) {\n sum += widths[id] ?? 0;\n out.push(sum);\n }\n\n return out;\n },\n [centerColumnIds, widths]\n );\n\n const [range, setRange] = useState({ end: 0, start: 0 });\n\n // Chase state: at most one transition is ever in flight, and the freshest target rides a ref\n // so that flight lands on the newest window it can. Restarting the transition per scroll\n // event instead would starve it — a smooth scroll fires one event per frame, each restart\n // abandons the sliced render, and nothing commits until the scrolling stops.\n const chaseTarget = useRef<{ start: number; end: number } | null>(null);\n const transitionPending = useRef(false);\n const lastScrollLeft = useRef(0);\n\n const measure = useEventCallback((defer: boolean) => {\n if (!enabled || !viewport || centerColumnIds.length === 0) {\n return;\n }\n\n const scrollLeft = Math.abs(viewport.scrollLeft);\n const strip = Math.max(0, viewport.clientWidth - pinnedStartWidth - pinnedEndWidth);\n // A discrete leap (scrollToColumn, a scrollbar jump) has no continuation to starve and no\n // shear to fear — one event, and the mirror already ran ahead of this listener — while a\n // transition would leave the landing blank for a render. It applies synchronously.\n const jumped = Math.abs(scrollLeft - lastScrollLeft.current) > strip;\n lastScrollLeft.current = scrollLeft;\n\n const next = measureColumnWindow({\n clientWidth: viewport.clientWidth,\n offsets,\n overscan,\n pinnedEndWidth,\n pinnedStartWidth,\n scrollLeft: viewport.scrollLeft\n });\n\n // The committed window shares nothing with where the viewport now is — the visible strip\n // is already fully blank, so a transition has nothing left to keep responsive. Committing\n // synchronously puts content under the pointer now; this is what keeps a fast scrollbar\n // drag showing bands instead of white.\n const blank = next.start >= range.end || next.end <= range.start;\n\n if (!defer || jumped || blank) {\n chaseTarget.current = null;\n setRange(previous => previous.start === next.start && previous.end === next.end ? previous : next);\n\n return;\n }\n\n if (next.start === range.start && next.end === range.end) {\n chaseTarget.current = null;\n\n return;\n }\n\n // Scroll-driven shifts render as a TRANSITION — a shift re-renders every windowed cell,\n // and a blocking render freezes the main-thread scrollLeft mirror while the compositor\n // keeps moving the body, shearing the header away for the render's whole duration.\n // Time-sliced, the render yields and the mirror stays inside the frame; the window filling\n // in a beat behind a fast fling is the standard virtualization trade.\n chaseTarget.current = next;\n\n if (transitionPending.current) {\n return;\n }\n\n transitionPending.current = true;\n // Read at processing time, so the flight lands on the newest target. ALWAYS a fresh\n // object, even when a synchronous commit got there first (`chaseTarget` null) and the\n // values repeat: `transitionPending` is only cleared by the commit effect below, so a\n // flight that bailed out of committing would jam the chase shut for good — the jitter\n // deadlock a scrollbar drag reliably found.\n startTransition(() => {\n setRange(previous => {\n return { ...chaseTarget.current ?? previous };\n });\n });\n });\n\n // The chase step: a commit landed, so re-measure from the live scroll position — a smooth\n // scroll has moved on while the transition rendered, and the next hop starts from here.\n // Terminates because the measure above no-ops once the window matches the scroll.\n useEffect(() => {\n transitionPending.current = false;\n measure(true);\n }, [range, measure]);\n\n // A layout effect so the first real window replaces the minimal initial render before paint.\n // Subscriptions only — re-measuring on geometry changes is the next effect's job, so a width\n // change never churns the listener and the observer (a resize drag reshapes `offsets` on\n // every pointer move).\n useLayoutEffect(() => {\n if (!enabled || !viewport) {\n return;\n }\n\n measure(false);\n const onScroll = () => measure(true);\n viewport.addEventListener(\"scroll\", onScroll, { passive: true });\n const observer = new ResizeObserver(() => measure(false));\n observer.observe(viewport);\n\n return () => {\n viewport.removeEventListener(\"scroll\", onScroll);\n observer.disconnect();\n };\n }, [enabled, viewport, measure]);\n\n // A width or pinned-boundary change re-derives the range from the same scroll position in\n // the same commit that moved the columns; `measure` itself guards the disabled states.\n useLayoutEffect(() => {\n measure(false);\n }, [measure, offsets, pinnedStartWidth, pinnedEndWidth]);\n\n const count = centerColumnIds.length;\n\n return useMemo(\n () => {\n if (!enabled || count === 0) {\n return null;\n }\n\n // Clamped against the CURRENT columns: the measured range may predate a width or\n // composition change by one commit, and the spaces must always sum with the rendered\n // columns to the exact zone total.\n const start = Math.min(range.start, count - 1);\n const end = Math.max(start + 1, Math.min(range.end, count));\n\n return {\n end,\n leadingSpace: offsets[start] ?? 0,\n start,\n trailingSpace: (offsets[count] ?? 0) - (offsets[end] ?? 0)\n };\n },\n [enabled, count, range, offsets]\n );\n}\n\n// ------------------------------------------------------------------------------------------------\n// Tiling helpers — how the three synced tables render against a window\n// ------------------------------------------------------------------------------------------------\n\n/**\n * Rendered column count including the spacer cols — what a full-width cell (detail panel,\n * loader row) spans.\n */\nexport function renderedColCount(view: ColumnWindowView | null, leafColumnCount: number): number {\n if (view === null) {\n return leafColumnCount;\n }\n\n return view.pinnedStartCount\n + (view.end - view.start)\n + view.pinnedEndCount\n + (view.start > 0 ? 1 : 0)\n + (view.end < view.centerCount ? 1 : 0);\n}\n\nexport interface WindowedRowCells<T> {\n leading: T[];\n windowed: T[];\n trailing: T[];\n}\n\n/**\n * A leaf-level row's cells against the window. `cells` is the full display-ordered list, so a\n * segment cell's display index is its segment offset plus the segment's start.\n */\nexport function windowRowCells<T>(cells: readonly T[], view: ColumnWindowView): WindowedRowCells<T> {\n return {\n leading: cells.slice(0, view.pinnedStartCount),\n trailing: view.pinnedEndCount === 0 ? [] : cells.slice(cells.length - view.pinnedEndCount),\n windowed: cells.slice(view.pinnedStartCount + view.start, view.pinnedStartCount + view.end)\n };\n}\n\nexport type WindowedHeaderCell<TData extends RowData>\n = | { kind: \"header\"; header: Header<TData, unknown>; colSpan: number; ariaColIndex: number }\n | { kind: \"spacer\"; edge: \"leading\" | \"trailing\" };\n\n/**\n * One clamp rule for every header and footer row (docs/virtualization.md#column-virtualization):\n * a header's colSpan is the number of its leaf columns actually rendered, plus a spacer col its\n * span fully contains (a header whose rendered leaves sit on both sides of a hidden run is one\n * rectangle and must absorb it); headers with nothing rendered vanish, and a spacer col nobody\n * absorbed stands alone. Well-defined because v9 builds header groups over the display-ordered\n * leaves — every header instance covers a contiguous run, pinning splits included.\n */\nexport function windowHeaderCells<TData extends RowData>(\n headers: Array<Header<TData, unknown>>,\n view: ColumnWindowView\n): Array<WindowedHeaderCell<TData>> {\n const windowStart = view.pinnedStartCount + view.start;\n const windowEnd = view.pinnedStartCount + view.end;\n const centerEnd = view.pinnedStartCount + view.centerCount;\n\n const isRendered = (index: number) => index < view.pinnedStartCount || index >= centerEnd || (index >= windowStart && index < windowEnd);\n\n const out: Array<WindowedHeaderCell<TData>> = [];\n let leadingPending = view.start > 0;\n let trailingPending = view.end < view.centerCount;\n\n for (const header of headers) {\n let low = Infinity;\n let high = -Infinity;\n let renderedCount = 0;\n let firstRendered = Infinity;\n // Unique indexes: for a placeholder chain (an ungrouped column passing through a group\n // row) v9's getLeafHeaders yields the same leaf column more than once.\n const seen = new Set<number>();\n\n for (const leaf of header.getLeafHeaders()) {\n const index = view.displayIndexById.get(leaf.column.id);\n\n if (index !== undefined && !seen.has(index)) {\n seen.add(index);\n low = Math.min(low, index);\n high = Math.max(high, index);\n\n if (isRendered(index)) {\n renderedCount += 1;\n firstRendered = Math.min(firstRendered, index);\n }\n }\n }\n\n if (renderedCount === 0) {\n continue;\n }\n\n // A rendered leaf in the pinned-start zone AND one at or past the window start puts the\n // leading hidden run inside this header's rectangle; same shape on the trailing side.\n const absorbLeading = leadingPending && low < view.pinnedStartCount && high >= windowStart;\n const absorbTrailing = trailingPending && low < windowEnd && high >= centerEnd;\n\n if (leadingPending && !absorbLeading && high >= windowStart) {\n out.push({ edge: \"leading\", kind: \"spacer\" });\n leadingPending = false;\n }\n\n if (trailingPending && !absorbTrailing && low >= windowEnd) {\n out.push({ edge: \"trailing\", kind: \"spacer\" });\n trailingPending = false;\n }\n\n if (absorbLeading) {\n leadingPending = false;\n }\n\n if (absorbTrailing) {\n trailingPending = false;\n }\n\n out.push({\n ariaColIndex: firstRendered + 1,\n colSpan: renderedCount + (absorbLeading ? 1 : 0) + (absorbTrailing ? 1 : 0),\n header,\n kind: \"header\"\n });\n }\n\n if (trailingPending) {\n out.push({ edge: \"trailing\", kind: \"spacer\" });\n }\n\n return out;\n}\n","/**\n * Sticky offsets for pinned display items: each top item sticks at the body edge plus the measured\n * heights above it (bottom items mirror upward). One shared `top` value would stack every pinned\n * row/detail item onto the same edge. Heights are measured, not assumed — they follow content and\n * spacing.\n */\nimport { useCallback, useLayoutEffect, useRef, useState } from \"react\";\n\ninterface PinnedRowOffsets {\n top: number[];\n bottom: number[];\n}\n\nconst NONE: PinnedRowOffsets = { top: [], bottom: [] };\n\nexport interface PinnedRowMeasurer {\n offsets: PinnedRowOffsets;\n registerTopRow: (index: number) => (element: Element | null) => void;\n registerBottomRow: (index: number) => (element: Element | null) => void;\n}\n\nexport function usePinnedRowOffsets(topCount: number, bottomCount: number): PinnedRowMeasurer {\n const [offsets, setOffsets] = useState<PinnedRowOffsets>(NONE);\n const topRows = useRef<Array<Element | null>>([]);\n const bottomRows = useRef<Array<Element | null>>([]);\n const topCallbacks = useRef<Array<(element: Element | null) => void>>([]);\n const bottomCallbacks = useRef<Array<(element: Element | null) => void>>([]);\n const observerRef = useRef<ResizeObserver | null>(null);\n\n /**\n * How many items of each end actually reached the screen. Mirrored in a layout effect, never\n * read from the props while measuring: refs are shared between the current tree and a\n * work-in-progress one, so a transition React renders and then throws away — a sibling suspends\n * — would otherwise take a row that is still on screen out of the measurement, and its ref\n * callback would never run again to put it back.\n */\n const committedCounts = useRef({ bottom: bottomCount, top: topCount });\n\n const measure = useCallback(() => {\n const cumulative = (elements: Array<Element | null>, count: number) => {\n const result: number[] = [];\n let sum = 0;\n\n for (let index = 0; index < count; index += 1) {\n result.push(sum);\n sum += elements[index]?.getBoundingClientRect().height ?? 0;\n }\n\n return result;\n };\n\n // Only what is on screen is measured, and all of it: an element registered for a row that has\n // not committed yet is not part of the layout, and a row that has is, whether or not anything\n // has re-attached its element since.\n const counts = committedCounts.current;\n\n // Bottom rows stack upward: the LAST bottom-pinned row sits at 0, the ones above it offset\n // by the heights below them.\n const bottom: number[] = [];\n let below = 0;\n\n for (let index = counts.bottom - 1; index >= 0; index -= 1) {\n bottom[index] = below;\n below += bottomRows.current[index]?.getBoundingClientRect().height ?? 0;\n }\n\n const next = { top: cumulative(topRows.current, counts.top), bottom };\n\n setOffsets(previous => previous.top.join(\",\") === next.top.join(\",\") && previous.bottom.join(\",\") === next.bottom.join(\",\")\n ? previous\n : next);\n }, []);\n\n useLayoutEffect(() => {\n const observer = new ResizeObserver(measure);\n observerRef.current = observer;\n\n for (const element of [...topRows.current, ...bottomRows.current]) {\n if (element) {\n observer.observe(element);\n }\n }\n\n measure();\n\n return () => {\n observerRef.current = null;\n observer.disconnect();\n };\n }, [measure]);\n\n /**\n * A real change in how many items are pinned: the counts the measurement works from move here,\n * in the commit phase, and the rows that left take their elements with them. Then everything\n * still there is measured again, because what stays has moved.\n */\n useLayoutEffect(() => {\n const counts = committedCounts.current;\n\n if (counts.top === topCount && counts.bottom === bottomCount) {\n return;\n }\n\n committedCounts.current = { bottom: bottomCount, top: topCount };\n topRows.current.length = topCount;\n bottomRows.current.length = bottomCount;\n measure();\n });\n\n const register = useCallback(\n (\n elements: { current: Array<Element | null> },\n callbacks: { current: Array<(element: Element | null) => void> },\n index: number\n ) => {\n const existing = callbacks.current[index];\n\n if (existing) {\n return existing;\n }\n\n let currentElement: Element | null = null;\n\n const callback = (element: Element | null) => {\n if (element === currentElement) {\n return;\n }\n\n if (currentElement) {\n observerRef.current?.unobserve(currentElement);\n }\n\n currentElement = element;\n // Written whatever the array's length is: a row growing the list attaches its element\n // during the same commit that carries the new count, and the effect above has not run\n // yet. The effect is what trims anything the screen no longer holds.\n elements.current[index] = element;\n\n if (element) {\n observerRef.current?.observe(element);\n }\n\n measure();\n };\n\n callbacks.current[index] = callback;\n\n return callback;\n },\n [measure]\n );\n\n const registerTopRow = useCallback(\n (index: number) => register(topRows, topCallbacks, index),\n [register]\n );\n\n const registerBottomRow = useCallback(\n (index: number) => register(bottomRows, bottomCallbacks, index),\n [register]\n );\n\n return {\n offsets,\n registerTopRow,\n registerBottomRow\n };\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { Virtualizer } from \"@tanstack/react-virtual\";\nimport type { MouseEvent, ReactNode, RefObject } from \"react\";\n\nimport type { RowReorderTarget } from \"./row-reorder\";\nimport type { Cell, ColumnDef, DataTableInstantEditRenderer, Row, TableInstance } from \"./types\";\nimport type { ColumnWindowView } from \"./use-column-window\";\n\n/**\n * The body: display-row synthesis (detail panels become synthetic rows so every <tr> is exactly\n * one virtual item), spacer-row virtualization in normal table flow, sticky pinned rows, grouped\n * and aggregated cells, tree indentation, skeleton and loader rows. Rows are memoized on\n * explicit volatile props — resizing never re-renders them (widths and pinned offsets are CSS\n * variables).\n */\nimport { ActionIcon, Button, Loader, Table as MantineTable, Skeleton } from \"@mantine/core\";\nimport { flexRender } from \"@tanstack/react-table\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { memo, useCallback, useEffect, useLayoutEffect, useMemo, useReducer } from \"react\";\n\nimport { columnHeaderText, EXPANDER_COLUMN_ID, isInternalColumn, ROW_DRAG_COLUMN_ID, SELECTION_COLUMN_ID } from \"./build-columns\";\nimport { canEditCell, CellEditor, RowCellEditor } from \"./cell-editor\";\nimport { useDataTableContext } from \"./context\";\nimport { cellValue, normalizeEdit } from \"./edit-meta\";\nimport { mergeElementProps, resolveElementProps } from \"./element-props\";\nimport { warnOnce } from \"./env\";\nimport { pinnedCellStyle, pinnedEdge } from \"./pinning\";\nimport { syncTruncationTitle } from \"./truncate\";\nimport { renderedColCount, windowRowCells } from \"./use-column-window\";\nimport { usePinnedRowOffsets } from \"./use-pinned-row-offsets\";\nimport { useEventCallback } from \"./utils\";\n\nconst TREE_INDENT_PX = 20;\nconst DEFAULT_ESTIMATED_ROW_HEIGHT = 44;\nconst DEFAULT_OVERSCAN = 8;\n\nexport interface VirtualizationConfig {\n estimateHeight: number;\n overscan: number;\n}\n\nexport type DisplayRow<TData extends RowData>\n = | { kind: \"data\"; key: string; row: Row<TData>; dataIndex: number }\n | { kind: \"detail\"; key: string; row: Row<TData> };\n\n/**\n * Whether any leaf definition declares a merge — the gate that keeps span-index reads (and the\n * per-row span signature) entirely out of tables that never span.\n */\nfunction hasSpanningColumns(columns: Array<ColumnDef<any, any>> | undefined): boolean {\n if (!columns) {\n return false;\n }\n\n return columns.some(column => \"columns\" in column && Array.isArray(column.columns)\n ? hasSpanningColumns(column.columns)\n : column.spanRows !== undefined || column.spanColumns !== undefined);\n}\n\n/**\n * One stable identity for an unoccupied pinned zone, so the display-row memos can hold.\n */\nconst NO_ROWS: Array<Row<any>> = [];\n\nexport function buildDisplayRows<TData extends RowData>(rows: Array<Row<TData>>, withDetailPanels: boolean): Array<DisplayRow<TData>> {\n const display: Array<DisplayRow<TData>> = [];\n let dataIndex = 0;\n\n for (const row of rows) {\n display.push({\n kind: \"data\",\n key: row.id,\n row,\n dataIndex\n });\n dataIndex += 1;\n\n // A grouped row's expansion reveals its children, not a panel — `renderDetailPanel` speaks\n // about a data row (docs/grouping.md#boundaries).\n if (withDetailPanels && row.getIsExpanded() && !row.getIsGrouped()) {\n display.push({\n kind: \"detail\",\n key: `${row.id}:detail`,\n row\n });\n }\n }\n\n return display;\n}\n\n/**\n * The same count without the array. `aria-rowcount` needs the number, not the rows, and building\n * three throwaway `DisplayRow[]`s per render is O(N) allocation the virtualizer then repeats on\n * every scroll range change.\n */\nexport function countDisplayRows<TData extends RowData>(rows: Array<Row<TData>>, withDetailPanels: boolean): number {\n if (!withDetailPanels) {\n return rows.length;\n }\n\n let count = rows.length;\n\n for (const row of rows) {\n if (row.getIsExpanded() && !row.getIsGrouped()) {\n count += 1;\n }\n }\n\n return count;\n}\n\n// ------------------------------------------------------------------------------------------------\n// Cells\n// ------------------------------------------------------------------------------------------------\n\n/**\n * Grouped cell: expander, the grouped value, and the group size.\n */\nfunction GroupCell({ cell }: { cell: Cell<any, unknown> }) {\n const {\n labels,\n icons,\n expansion\n } = useDataTableContext();\n const { row } = cell;\n const expandedGroup = row.getIsExpanded();\n const canExpandGroup = row.getCanExpand();\n\n return (\n <span data-group-cell>\n <ActionIcon\n aria-expanded={expandedGroup}\n aria-label={expandedGroup ? labels.collapseRow : labels.expandRow}\n data-expanded={expandedGroup || undefined}\n size=\"xs\"\n variant=\"subtle\"\n onClick={event => {\n event.stopPropagation();\n expansion?.toggle(row.id, expandedGroup, canExpandGroup);\n }}\n >\n <icons.expandRow size={12} />\n </ActionIcon>\n\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n\n <span data-group-count>\n (\n {row.subRows.length}\n )\n </span>\n </span>\n );\n}\n\n/**\n * The instant-apply host (docs/editing.md#instant-editing): a change in the cell *is* the\n * commit, so no session ever opens. A view of its target in the controller, like the editor\n * hosts are views of their session — what a commit leaves behind must survive the column being\n * hidden, a breakpoint removing it, or a virtual scroll taking the row off screen, none of\n * which are the write landing. The column's own renderer supplies the control; the host owns\n * the chrome around it — the pending loader, the failure alert, and the click fences that keep\n * `onRowClick` out.\n */\nfunction InstantCell({ cell, render }: { cell: Cell<any, unknown>; render: DataTableInstantEditRenderer<any, unknown> }) {\n const { labels, getStyles } = useDataTableContext();\n const { table } = cell.getContext();\n const instant = table.options.meta?.ledger?.editing.instant;\n const rowId = cell.row.id;\n const columnId = cell.column.id;\n\n const [, redraw] = useReducer((token: number) => token + 1, 0);\n const redrawFromTarget = useEventCallback(() => redraw());\n const register = instant?.register;\n\n // Layout, not passive: the registry is what \"on screen right now\" means to the target, and a\n // commit that unmounts this control is followed by microtasks — a settling write among them.\n useLayoutEffect(\n () => register?.(rowId, columnId, { redraw: redrawFromTarget }),\n [register, rowId, columnId, redrawFromTarget]\n );\n\n if (!instant) {\n return null;\n }\n\n const value = instant.value(rowId, columnId, cellValue(cell));\n const pending = instant.pending(rowId, columnId);\n const error = instant.error(rowId, columnId);\n\n return (\n <span\n aria-busy={pending || undefined}\n data-pending={pending || undefined}\n onClick={event => event.stopPropagation()}\n onDoubleClick={event => event.stopPropagation()}\n {...getStyles(\"instantCell\")}\n >\n {render({\n row: cell.row,\n column: cell.column,\n value,\n commit: next => instant.commit(rowId, columnId, next),\n pending,\n error,\n label: labels.editColumn(columnHeaderText(cell.column))\n })}\n\n {/* Out of flow (`instantSpinner`): the control must not move while its write is out. */}\n {pending && <Loader aria-label={labels.editPending} size={12} {...getStyles(\"instantSpinner\")} />}\n {error && <span role=\"alert\">{error}</span>}\n </span>\n );\n}\n\ninterface DataCellProps {\n cell: Cell<any, unknown>;\n editing: boolean;\n /**\n * The whole row is in row-mode editing — every editable cell hosts its editor.\n */\n rowEditing: boolean;\n isFirstDataCell: boolean;\n depth: number;\n /**\n * Merged-cell extents (1 = no span); covered cells are skipped by the row, never rendered.\n */\n rowSpan: number;\n colSpan: number;\n /**\n * Set only under a column window: the cell's 1-based position among ALL visible leaf columns,\n * windowed-out ones included.\n */\n ariaColIndex: number | undefined;\n}\n\nfunction DataCell({\n cell,\n editing,\n rowEditing,\n isFirstDataCell,\n depth,\n rowSpan,\n colSpan,\n ariaColIndex\n}: DataCellProps) {\n const { getStyles } = useDataTableContext();\n const { column, row } = cell;\n const { table } = cell.getContext();\n const ledger = table.options.meta?.ledger;\n const editMode = ledger?.editing.mode ?? \"cell\";\n const { meta } = column.columnDef;\n\n const grouped = cell.getIsGrouped();\n // getIsAggregated() is true for ANY row with subRows — a grouping concept that leaks into\n // trees (getSubRows) and would swallow the expander button and the author's cell renderer\n // on every parent row. Aggregated rendering only exists on real grouping rows.\n const aggregated = cell.getIsAggregated() && row.getIsGrouped();\n const placeholder = cell.getIsPlaceholder();\n // The gate, asked in the render that has to answer it. Ending a session whose eligibility is\n // gone is a side effect, so reconciliation runs after the paint — but whether an editor is on\n // the screen is this render's own question, and this render already knows the gate is shut. Ask\n // it later and the commit that shuts the gate still paints a live editor for one frame, which\n // is a frame the user can type into.\n const gateOpen = !grouped && !aggregated && !placeholder && canEditCell(cell, row);\n const editable = !editing && gateOpen;\n // `editing` / `rowEditing` are the other half: they already mean a live *session*, not merely a\n // slice that names this target — a gate that shut ends the session even when a controlled\n // application declines to close it, and neither editor may become interactive again if that\n // gate reopens (docs/architecture.md).\n const cellEditorActive = editing && gateOpen;\n const rowEditorActive = rowEditing && gateOpen;\n const normalizedEdit = normalizeEdit(meta?.edit);\n const instantEdit = normalizedEdit?.kind === \"instant\" ? normalizedEdit : null;\n\n let content: ReactNode;\n\n if (grouped) {\n content = <GroupCell cell={cell} />;\n } else if (aggregated) {\n content = flexRender(column.columnDef.aggregatedCell ?? column.columnDef.cell, cell.getContext());\n } else if (placeholder) {\n content = null;\n } else if (cellEditorActive) {\n content = <CellEditor cell={cell} />;\n } else if (rowEditorActive) {\n content = <RowCellEditor cell={cell} />;\n } else if (editable && instantEdit && editMode === \"cell\") {\n content = <InstantCell cell={cell} render={instantEdit.render} />;\n } else {\n content = flexRender(column.columnDef.cell, cell.getContext());\n\n if (meta?.truncate) {\n content = (\n <span data-truncate onPointerEnter={syncTruncationTitle}>\n {content}\n </span>\n );\n }\n }\n\n const startEditing\n = editable && !rowEditorActive && (editMode === \"row\" || !instantEdit) && ledger\n ? (event: MouseEvent) => {\n event.stopPropagation();\n\n if (editMode === \"row\") {\n ledger.editing.row.start(row.id, { focusColumnId: column.id });\n } else {\n ledger.editing.start({ rowId: row.id, columnId: column.id });\n }\n }\n : undefined;\n\n if (isFirstDataCell && depth > 0) {\n content = <div style={{ paddingInlineStart: depth * TREE_INDENT_PX }}>{content}</div>;\n }\n\n const selector\n = column.id === SELECTION_COLUMN_ID\n ? \"selectionCell\"\n : column.id === EXPANDER_COLUMN_ID\n ? \"expanderCell\"\n : column.id === ROW_DRAG_COLUMN_ID\n ? \"rowDragCell\"\n : \"cell\";\n // An injected column is a control column: nothing in it activates the row (docs/rows.md). The\n // built-in checkbox and chevron stop their own events, but the column's renderer is\n // overridable (`selectionColumn` / `expanderColumn`), and whatever an application puts there\n // cannot be expected to know that rule — so the host cell holds it instead. A `cellProps`\n // handler still runs: ledger's own is chained ahead of it, not in place of it.\n const stopActivation = isInternalColumn(column.id)\n ? (event: MouseEvent) => event.stopPropagation()\n : undefined;\n\n // Two merges, not one spread. The Styles API answer is a consumer like `cellProps` is — it\n // may carry `attributes` handlers, and those have to run *with* ledger's, not instead of\n // them, while `role` and the structural data-attributes stay ledger's. Spreading the answer\n // into the owned object would let an `attributes.selectionCell.onClick` replace the handler\n // that keeps a control column from activating its row, and rewrite `role` besides.\n const owned = mergeElementProps(getStyles(selector, { style: pinnedCellStyle(column) }), {\n \"aria-colindex\": ariaColIndex,\n \"aria-colspan\": colSpan > 1 ? colSpan : undefined,\n \"aria-rowspan\": rowSpan > 1 ? rowSpan : undefined,\n colSpan: colSpan > 1 ? colSpan : undefined,\n \"data-align\": meta?.align,\n \"data-editable\": editable || undefined,\n \"data-editing\": cellEditorActive || rowEditorActive || undefined,\n \"data-leading\": column.getIsFirstColumn() || undefined,\n \"data-ledger-column-id\": column.id,\n \"data-pinned\": column.getIsPinned() || undefined,\n \"data-pinned-edge\": pinnedEdge(column),\n role: \"cell\",\n rowSpan: rowSpan > 1 ? rowSpan : undefined,\n onClick: stopActivation ?? (ledger?.editTrigger === \"click\" ? startEditing : undefined),\n onDoubleClick: stopActivation ?? (ledger?.editTrigger === \"double-click\" ? startEditing : undefined)\n });\n\n return (\n <MantineTable.Td\n {...mergeElementProps(resolveElementProps(meta?.cellProps, cell), owned)}\n >\n {content}\n </MantineTable.Td>\n );\n}\n\n// ------------------------------------------------------------------------------------------------\n// Rows\n// ------------------------------------------------------------------------------------------------\n\ninterface DataRowProps {\n row: Row<any>;\n dataIndex: number;\n editingColumnId: string | null;\n /**\n * Row-mode editing targets this row — every editable cell mounts its editor.\n */\n editingRow: boolean;\n /**\n * A live reorder lifted this row (docs/rows.md#row-ordering) — it dims in place.\n */\n dragging: boolean;\n /**\n * The lifted row would land on this edge of this row — the drop indicator.\n */\n dropSide: \"before\" | \"after\" | null;\n selected: boolean;\n active: boolean;\n expanded: boolean;\n depth: number;\n pinKey: string;\n columnsKey: string;\n /**\n * Merged cells active for this table (never under virtualization).\n */\n spanning: boolean;\n /**\n * Per-row span signature — spans depend on NEIGHBOR rows, which this row's own props cannot\n * see, so the signature busts the memo when an adjacent change reshapes the merge.\n */\n spanKey: string;\n /**\n * Stable memo token for column definitions and editing behavior that cells read indirectly\n * through the stable TanStack table instance.\n */\n renderVersion: object;\n /**\n * The live column window — `null` renders every visible cell. Window shifts change its\n * identity, which is exactly when a row must redraw.\n */\n columnWindow: ColumnWindowView | null;\n pinnedPosition?: \"top\" | \"bottom\";\n /**\n * Sticky offset for pinned rows — measured cumulative height of the pinned rows before it.\n */\n pinnedOffset?: number;\n virtualIndex?: number;\n measureRef?: (element: Element | null) => void;\n ariaRowIndex?: number;\n}\n\nfunction DataRowImpl({\n row,\n dataIndex,\n editingColumnId,\n editingRow,\n dragging,\n dropSide,\n selected,\n active,\n expanded,\n depth,\n spanning,\n columnWindow,\n pinnedPosition,\n pinnedOffset,\n virtualIndex,\n measureRef,\n ariaRowIndex\n}: DataRowProps) {\n const {\n getStyles,\n onRowClick,\n onRowActivate,\n onRowDoubleClick,\n onRowContextMenu,\n rowProps,\n activeRowEnabled,\n setActiveRow\n } = useDataTableContext();\n\n const cells = row.getVisibleCells();\n const firstDataCellIndex = cells.findIndex(cell => !isInternalColumn(cell.column.id));\n\n /* The body scroller holds no header, so top offsets start at the scroller's own edge. */\n const pinnedStyle\n = pinnedPosition === \"top\"\n ? { top: `${pinnedOffset ?? 0}px` }\n : pinnedPosition === \"bottom\"\n ? { bottom: `${pinnedOffset ?? 0}px` }\n : undefined;\n\n const handler = (callback?: (row: Row<any>, event: MouseEvent) => void) => callback ? (event: MouseEvent) => callback(row, event) : undefined;\n\n // A click makes the row current before the consumer's own handlers see it. A click is also an\n // activation, so both fire here — `onRowClick` first, as the more specific of the two.\n const handleClick = onRowClick || onRowActivate || activeRowEnabled\n ? (event: MouseEvent) => {\n if (activeRowEnabled) {\n setActiveRow?.(row.id);\n }\n\n onRowClick?.(row, event);\n onRowActivate?.(row, event);\n }\n : undefined;\n\n return (\n <MantineTable.Tr\n ref={measureRef}\n {...mergeElementProps(resolveElementProps(rowProps, row), {\n \"aria-current\": active || undefined,\n \"aria-rowindex\": ariaRowIndex,\n \"aria-selected\": selected || undefined,\n \"data-active\": active || undefined,\n \"data-clickable\": handleClick ? true : undefined,\n \"data-dragging\": dragging || undefined,\n \"data-drop-side\": dropSide ?? undefined,\n \"data-editing-row\": editingRow || undefined,\n \"data-expanded\": expanded || undefined,\n \"data-index\": virtualIndex,\n \"data-parity\": dataIndex >= 0 ? dataIndex % 2 === 0 ? \"odd\" : \"even\" : undefined,\n \"data-pinned-row\": pinnedPosition,\n \"data-row-id\": row.id,\n \"data-selected\": selected || undefined,\n role: \"row\",\n onClick: handleClick,\n onContextMenu: handler(onRowContextMenu),\n onDoubleClick: handler(onRowDoubleClick),\n ...getStyles(\"row\", { style: pinnedStyle })\n })}\n >\n {renderRowCells()}\n </MantineTable.Tr>\n );\n\n // Cells against the column window: pinned segments in full, the windowed center slice, and\n // spacer cells over the spacer cols (docs/virtualization.md#column-virtualization). Spanning\n // never coexists with a window (the body gates it), so the two branches stay disjoint.\n function renderRowCells(): ReactNode {\n const renderCell = (cell: Cell<any, unknown>, displayIndex: number) => {\n if (spanning && cell.getIsCovered()) {\n return null;\n }\n\n return (\n <DataCell\n key={cell.id}\n ariaColIndex={columnWindow === null ? undefined : displayIndex + 1}\n cell={cell}\n colSpan={spanning ? cell.getColSpan() : 1}\n depth={depth}\n editing={editingColumnId === cell.column.id}\n isFirstDataCell={displayIndex === firstDataCellIndex}\n rowEditing={editingRow}\n rowSpan={spanning ? cell.getRowSpan() : 1}\n />\n );\n };\n\n if (columnWindow === null) {\n return cells.map((cell, index) => renderCell(cell, index));\n }\n\n const segments = windowRowCells(cells, columnWindow);\n const windowedStart = columnWindow.pinnedStartCount + columnWindow.start;\n const trailingStart = cells.length - columnWindow.pinnedEndCount;\n\n return (\n <>\n {segments.leading.map((cell, index) => renderCell(cell, index))}\n {columnWindow.start > 0 && <td aria-hidden data-ledger-spacer />}\n {segments.windowed.map((cell, index) => renderCell(cell, windowedStart + index))}\n {columnWindow.end < columnWindow.centerCount && <td aria-hidden data-ledger-spacer />}\n {segments.trailing.map((cell, index) => renderCell(cell, trailingStart + index))}\n </>\n );\n }\n}\n\nconst DataRow = memo(DataRowImpl) as typeof DataRowImpl;\n\ninterface DetailRowProps {\n row: Row<any>;\n /**\n * The panel renderer of the render that put this row on screen. A prop rather than a context\n * field because an application writes it inline: taking its identity into the context value\n * would rebuild the context on every render and leave nothing below memoized (context.ts).\n */\n renderDetailPanel?: (row: Row<any>) => ReactNode;\n colSpan: number;\n /**\n * The panel dims with its lifted parent, and carries the \"after the pair\" drop indicator\n * (docs/rows.md#row-ordering).\n */\n dragging: boolean;\n dropSide: \"after\" | null;\n pinnedPosition?: \"top\" | \"bottom\";\n pinnedOffset?: number;\n virtualIndex?: number;\n measureRef?: (element: Element | null) => void;\n ariaRowIndex?: number;\n}\n\nfunction DetailRow({\n row,\n renderDetailPanel,\n colSpan,\n dragging,\n dropSide,\n pinnedPosition,\n pinnedOffset,\n virtualIndex,\n measureRef,\n ariaRowIndex\n}: DetailRowProps) {\n const { getStyles } = useDataTableContext();\n const pinnedStyle\n = pinnedPosition === \"top\"\n ? { top: `${pinnedOffset ?? 0}px` }\n : pinnedPosition === \"bottom\"\n ? { bottom: `${pinnedOffset ?? 0}px` }\n : undefined;\n\n return (\n <MantineTable.Tr\n ref={measureRef}\n data-detail-row\n aria-rowindex={ariaRowIndex}\n data-dragging={dragging || undefined}\n data-drop-side={dropSide ?? undefined}\n data-index={virtualIndex}\n data-pinned-row={pinnedPosition}\n role=\"row\"\n {...getStyles(\"row\", { style: pinnedStyle })}\n >\n <MantineTable.Td colSpan={colSpan} role=\"cell\" {...getStyles(\"detailPanel\")}>\n {renderDetailPanel?.(row)}\n </MantineTable.Td>\n </MantineTable.Tr>\n );\n}\n\n// ------------------------------------------------------------------------------------------------\n// Loading rows\n// ------------------------------------------------------------------------------------------------\n\nfunction SkeletonRows({\n rowCount,\n columnCount,\n ariaRowIndexStart\n}: {\n rowCount: number;\n columnCount: number;\n ariaRowIndexStart?: number;\n}) {\n const { getStyles } = useDataTableContext();\n\n return (\n <>\n {Array.from({ length: rowCount }, (_, rowIndex) => (\n <MantineTable.Tr\n key={rowIndex}\n aria-rowindex={ariaRowIndexStart === undefined ? undefined : ariaRowIndexStart + rowIndex}\n role=\"row\"\n {...getStyles(\"row\")}\n >\n {Array.from({ length: columnCount }, (_, columnIndex) => (\n <MantineTable.Td key={columnIndex} role=\"cell\" {...getStyles(\"cell\")}>\n <Skeleton height={10} radius=\"sm\" />\n </MantineTable.Td>\n ))}\n </MantineTable.Tr>\n ))}\n </>\n );\n}\n\nfunction LoaderRow({ colSpan, ariaRowIndex }: { colSpan: number; ariaRowIndex?: number }) {\n const { getStyles, labels } = useDataTableContext();\n\n return (\n <MantineTable.Tr aria-rowindex={ariaRowIndex} role=\"row\" {...getStyles(\"loaderRow\")}>\n <MantineTable.Td colSpan={colSpan} role=\"cell\">\n <div {...getStyles(\"loaderRowContent\")}>\n {/* dots, not the oval arc: the arc's ink orbits its box, so at rest sizes it reads as\n misaligned against the text in any single frame; the dots' mass never moves. */}\n <Loader size=\"xs\" type=\"dots\" />\n <span>{labels.loadingMore}</span>\n </div>\n </MantineTable.Td>\n </MantineTable.Tr>\n );\n}\n\nfunction LoadMoreErrorRow({\n colSpan,\n message,\n ariaRowIndex,\n onRetry\n}: {\n colSpan: number;\n message: ReactNode;\n ariaRowIndex?: number;\n onRetry?: () => void;\n}) {\n const {\n getStyles,\n labels,\n icons\n } = useDataTableContext();\n\n return (\n <MantineTable.Tr data-error aria-rowindex={ariaRowIndex} role=\"row\" {...getStyles(\"loaderRow\")}>\n {/* The alert lives on the message, never on the cell: `role=\"alert\"` would replace\n `role=\"cell\"` and leave the row with no cell in the accessibility tree. */}\n <MantineTable.Td colSpan={colSpan} role=\"cell\">\n <div {...getStyles(\"loaderRowContent\")}>\n <span role=\"alert\">{message === true ? labels.loadMoreError : message}</span>\n\n {onRetry && (\n <Button\n color=\"gray\"\n leftSection={<icons.retry size={14} />}\n size=\"compact-xs\"\n variant=\"subtle\"\n onClick={onRetry}\n >\n {labels.retry}\n </Button>\n )}\n </div>\n </MantineTable.Td>\n </MantineTable.Tr>\n );\n}\n\n// ------------------------------------------------------------------------------------------------\n// Body\n// ------------------------------------------------------------------------------------------------\n\nexport interface TableBodyProps {\n table: TableInstance<any>;\n virtualization: VirtualizationConfig | null;\n /**\n * The live column window (docs/virtualization.md#column-virtualization) — `null` renders\n * every visible leaf column.\n */\n columnWindow: ColumnWindowView | null;\n viewportRef: RefObject<HTMLDivElement | null>;\n loading: boolean;\n loadingMore: boolean;\n loadMoreError: boolean | ReactNode;\n onLoadMoreRetry?: () => void;\n /**\n * The live row-reorder session (docs/rows.md#row-ordering): the lifted row dims, the target\n * row draws the drop indicator. Both `null` while the gate is off or no drag is live.\n */\n reorderSourceId: string | null;\n reorderTarget: RowReorderTarget | null;\n skeletonRowCount: number;\n onVirtualizerChange: (virtualizer: Virtualizer<HTMLDivElement, Element> | null) => void;\n}\n\nexport function TableBody({\n table,\n virtualization,\n columnWindow,\n viewportRef,\n loading,\n loadingMore,\n loadMoreError,\n onLoadMoreRetry,\n reorderSourceId,\n reorderTarget,\n skeletonRowCount,\n onVirtualizerChange\n}: TableBodyProps) {\n const { getStyles, withColumnHeaders } = useDataTableContext();\n const ledger = table.options.meta?.ledger;\n\n const withDetailPanels = Boolean(ledger?.renderDetailPanel);\n const spanningDeclared = useMemo(() => hasSpanningColumns(ledger?.columns), [ledger?.columns]);\n const spanningActive\n = spanningDeclared\n && virtualization === null\n && columnWindow === null\n && !withDetailPanels\n && table.options.enableCellSpanning !== false;\n\n if (spanningDeclared && virtualization !== null) {\n warnOnce(\n \"spanning-virtualized\",\n \"spanRows/spanColumns are ignored while virtualizedRows — a merged cell breaks the one-<tr>-per-virtual-item invariant.\"\n );\n }\n\n if (spanningDeclared && columnWindow !== null) {\n warnOnce(\n \"spanning-virtualized-columns\",\n \"spanRows/spanColumns are ignored while virtualizedColumns — a merged cell would reach across the windowed colgroup.\"\n );\n }\n\n if (spanningDeclared && withDetailPanels) {\n // Spans are computed over data rows only, but a detail panel inserts a synthetic <tr>\n // between them: an unmodified rowSpan would reach across the panel while the covered cell\n // below it is still dropped, tearing the column structure apart.\n warnOnce(\n \"spanning-detail-panel\",\n \"spanRows/spanColumns are ignored while renderDetailPanel is set — a detail row lands inside the span a merged cell would reach across.\"\n );\n }\n\n const rowPinningActive = table.options.enableRowPinning === true;\n // A fresh `[]` per render would defeat the memos below; the empty zone is one stable array.\n const topRows = rowPinningActive ? table.getTopRows() : NO_ROWS;\n const bottomRows = rowPinningActive ? table.getBottomRows() : NO_ROWS;\n const centerRows = rowPinningActive ? table.getCenterRows() : table.getRowModel().rows;\n\n // Every zone uses the same synthesis: an expanded pinned row owns a detail item just like a\n // center row, and the sticky offset engine measures both items independently. Memoized because\n // the virtualizer re-renders this component on every scroll range change: rebuilding the\n // display rows there would make each scroll step O(rows) in a table sized for virtualization.\n // The row arrays are a sufficient key even though the synthesis reads `row.getIsExpanded()`:\n // v9's expanded row model returns the pre-expanded array while nothing is expanded and a\n // freshly built one as soon as something is, so every `expanded` transition changes identity.\n const topDisplayRows = useMemo(() => buildDisplayRows(topRows, withDetailPanels), [topRows, withDetailPanels]);\n const centerDisplayRows = useMemo(() => buildDisplayRows(centerRows, withDetailPanels), [centerRows, withDetailPanels]);\n const bottomDisplayRows = useMemo(() => buildDisplayRows(bottomRows, withDetailPanels), [bottomRows, withDetailPanels]);\n const pinnedRowOffsets = usePinnedRowOffsets(topDisplayRows.length, bottomDisplayRows.length);\n\n /* aria-rowindex numbers header rows first (docs/virtualization.md) — none when they are off. */\n const headerRowCount = withColumnHeaders ? table.getHeaderGroups().length : 0;\n\n /**\n * `getItemKey` sits in virtual-core's `getMeasurementOptions` memo **by reference**, and that\n * memo feeds `getMeasurements`. A fresh closure per render therefore invalidates the whole\n * measurement pass, which then walks every item from index 0 — an O(rows) sweep on each of\n * the re-renders the virtualizer itself triggers while scrolling. It stays stable for as long\n * as the display rows do, which is exactly when the measurements are still valid.\n */\n const getItemKey = useCallback(\n (index: number) => centerDisplayRows[index]?.key ?? index,\n [centerDisplayRows]\n );\n const estimateHeight = virtualization?.estimateHeight ?? DEFAULT_ESTIMATED_ROW_HEIGHT;\n const estimateSize = useCallback(() => estimateHeight, [estimateHeight]);\n\n const virtualizer = useVirtualizer({\n count: centerDisplayRows.length,\n enabled: virtualization !== null,\n estimateSize,\n getItemKey,\n getScrollElement: () => viewportRef.current,\n overscan: virtualization?.overscan ?? DEFAULT_OVERSCAN,\n // The upstream React 19 compatibility setting: with it on, a row measured as its ref\n // attaches (a scrollToIndex landing in unmeasured territory) has the virtualizer calling\n // flushSync inside React's commit — React noops it to a batched update and warns, so the\n // sync flush never actually happened on that path anyway.\n useFlushSync: false\n });\n\n const virtualEnabled = virtualization !== null;\n\n useEffect(() => {\n onVirtualizerChange(virtualEnabled ? virtualizer : null);\n\n return () => onVirtualizerChange(null);\n }, [virtualEnabled, virtualizer, onVirtualizerChange]);\n\n const leafColumnCount = table.getVisibleLeafColumns().length;\n // What a full-width cell (skeleton, detail panel, loader) spans — the rendered cols, spacer\n // cols included, under a column window.\n const fullWidthColSpan = renderedColCount(columnWindow, leafColumnCount);\n const totalDisplayRowCount = topDisplayRows.length + centerDisplayRows.length + bottomDisplayRows.length;\n // Presence, never identity: what a row's cells read from the commit handlers is whether the\n // live mode has one at all — that is the whole of their part in `canEditCell`, and the write\n // itself goes through the controllers, whose event callbacks always reach the latest. An\n // application that writes its handler inline (the ordinary way to write one) hands `meta` a new\n // function on every render, and taking its identity here would put a new token on every row and\n // leave nothing memoized at all.\n const canCommitCell = Boolean(ledger?.onEditCommit);\n const canCommitRow = Boolean(ledger?.onRowEditCommit);\n // The handles read this through the table instance, so it must bust the row memo: when a sort\n // arrives, the rows that happen to keep their position would otherwise keep enabled handles.\n const rowOrderable = ledger?.rowOrdering.orderable === true;\n const renderVersion = useMemo(\n () => {\n return {\n // meta.ledger.columns, never options.columns: v9 re-resolves options per state tick,\n // so the options-side identity would bust the row memo on every state change.\n columns: ledger?.columns,\n editTrigger: ledger?.editTrigger,\n editMode: ledger?.editing.mode,\n enableEditing: ledger?.enableEditing,\n canCommitCell,\n canCommitRow,\n rowOrderable\n };\n },\n [ledger?.columns, ledger?.enableEditing, ledger?.editTrigger, ledger?.editing.mode, canCommitCell, canCommitRow, rowOrderable]\n );\n\n if (loading && totalDisplayRowCount === 0) {\n return (\n <MantineTable.Tbody {...getStyles(\"tbody\")}>\n <SkeletonRows\n ariaRowIndexStart={virtualEnabled ? headerRowCount + 1 : undefined}\n columnCount={fullWidthColSpan}\n rowCount={skeletonRowCount}\n />\n </MantineTable.Tbody>\n );\n }\n\n /* Memo-busting signatures: rows re-render when pinning or the visible column set changes. */\n const pinning = table.atoms.columnPinning.get();\n const pinKey = JSON.stringify([pinning.start, pinning.end]);\n const columnsKey = JSON.stringify([\n table.getVisibleLeafColumns().map(column => column.id),\n columnWindow === null ? null : [columnWindow.start, columnWindow.end]\n ]);\n const editingCell = ledger?.editing.cell ?? null;\n const editingRowId = ledger?.editing.mode === \"row\" ? ledger.editing.row.id : null;\n const activeRowId = ledger?.activeRow.enabled ? ledger.activeRow.id : null;\n\n interface DisplayRowRenderOptions {\n displayIndex: number;\n pinnedPosition?: \"top\" | \"bottom\";\n pinnedOffset?: number;\n virtualIndex?: number;\n measureRef?: (element: Element | null) => void;\n }\n\n const renderDisplayRow = (\n displayRow: DisplayRow<any>,\n options: DisplayRowRenderOptions\n ): ReactNode => {\n const zoneStart\n = options.pinnedPosition === \"top\"\n ? headerRowCount\n : options.pinnedPosition === \"bottom\"\n ? headerRowCount + topDisplayRows.length + centerDisplayRows.length\n : headerRowCount + topDisplayRows.length;\n const ariaRowIndex = virtualEnabled ? zoneStart + options.displayIndex + 1 : undefined;\n\n if (displayRow.kind === \"detail\") {\n return (\n <DetailRow\n key={displayRow.key}\n ariaRowIndex={ariaRowIndex}\n colSpan={fullWidthColSpan}\n dragging={reorderSourceId === displayRow.row.id}\n measureRef={options.measureRef}\n pinnedOffset={options.pinnedOffset}\n pinnedPosition={options.pinnedPosition}\n renderDetailPanel={ledger?.renderDetailPanel}\n row={displayRow.row}\n virtualIndex={options.virtualIndex}\n // \"After\" an expanded row means after the pair — the panel travels with its row, so\n // the panel's bottom edge is where that indicator draws (docs/rows.md#row-ordering).\n dropSide={reorderTarget?.rowId === displayRow.row.id && reorderTarget.side === \"after\"\n ? \"after\"\n : null}\n />\n );\n }\n\n const { row, dataIndex } = displayRow;\n const dropSide\n = reorderTarget?.rowId === row.id\n && !(reorderTarget.side === \"after\" && withDetailPanels && row.getIsExpanded())\n ? reorderTarget.side\n : null;\n const spanKey = spanningActive\n ? row.getVisibleCells()\n .map(cell => cell.getIsCovered() ? \"x\" : `${cell.getRowSpan()}:${cell.getColSpan()}`)\n .join(\" \")\n : \"\";\n\n return (\n <DataRow\n key={displayRow.key}\n active={activeRowId === row.id}\n ariaRowIndex={ariaRowIndex}\n columnsKey={columnsKey}\n columnWindow={columnWindow}\n dataIndex={options.pinnedPosition ? -1 : dataIndex}\n depth={row.depth}\n dragging={reorderSourceId === row.id}\n dropSide={dropSide}\n editingRow={editingRowId === row.id && (ledger?.editing.row.active(row.id) ?? false)}\n expanded={row.getIsExpanded()}\n measureRef={options.measureRef}\n pinKey={pinKey}\n pinnedOffset={options.pinnedOffset}\n pinnedPosition={options.pinnedPosition}\n renderVersion={renderVersion}\n row={row}\n selected={row.getIsSelected()}\n spanKey={spanKey}\n spanning={spanningActive}\n virtualIndex={options.virtualIndex}\n editingColumnId={editingCell?.rowId === row.id && (ledger?.editing.active(row.id, editingCell.columnId) ?? false)\n ? editingCell.columnId\n : null}\n />\n );\n };\n\n let center: ReactNode;\n\n if (virtualEnabled) {\n const items = virtualizer.getVirtualItems();\n const firstItem = items[0];\n const lastItem = items.at(-1);\n const topSpace = firstItem ? firstItem.start : 0;\n const bottomSpace = lastItem ? virtualizer.getTotalSize() - lastItem.end : 0;\n\n center = (\n <>\n {topSpace > 0 && <tr aria-hidden data-ledger-spacer style={{ height: topSpace }} />}\n\n {items.map(item => {\n const displayRow = centerDisplayRows[item.index];\n\n return displayRow\n ? renderDisplayRow(displayRow, {\n displayIndex: item.index,\n virtualIndex: item.index,\n measureRef: virtualizer.measureElement\n })\n : null;\n })}\n\n {bottomSpace > 0 && <tr aria-hidden data-ledger-spacer style={{ height: bottomSpace }} />}\n </>\n );\n } else {\n center = centerDisplayRows.map((displayRow, displayIndex) => renderDisplayRow(displayRow, { displayIndex }));\n }\n\n return (\n <MantineTable.Tbody {...getStyles(\"tbody\")}>\n {topDisplayRows.map((displayRow, displayIndex) => renderDisplayRow(displayRow, {\n displayIndex,\n measureRef: pinnedRowOffsets.registerTopRow(displayIndex),\n pinnedOffset: pinnedRowOffsets.offsets.top[displayIndex],\n pinnedPosition: \"top\"\n }))}\n\n {center}\n\n {bottomDisplayRows.map((displayRow, displayIndex) => renderDisplayRow(displayRow, {\n displayIndex,\n measureRef: pinnedRowOffsets.registerBottomRow(displayIndex),\n pinnedOffset: pinnedRowOffsets.offsets.bottom[displayIndex],\n pinnedPosition: \"bottom\"\n }))}\n\n {loadMoreError\n ? (\n <LoadMoreErrorRow\n ariaRowIndex={virtualEnabled ? headerRowCount + totalDisplayRowCount + 1 : undefined}\n colSpan={fullWidthColSpan}\n message={loadMoreError}\n onRetry={onLoadMoreRetry}\n />\n )\n : loadingMore && (\n <LoaderRow\n ariaRowIndex={virtualEnabled ? headerRowCount + totalDisplayRowCount + 1 : undefined}\n colSpan={fullWidthColSpan}\n />\n )}\n </MantineTable.Tbody>\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Header, TableInstance } from \"./types\";\nimport type { ColumnWindowView } from \"./use-column-window\";\n\n/**\n * Column footers (totals row). Rendered only when at least one leaf column declares a `footer`;\n * pinned columns keep their sticky offsets so the totals track their columns.\n */\nimport { Table as MantineTable } from \"@mantine/core\";\nimport { flexRender } from \"@tanstack/react-table\";\n\nimport { useDataTableContext } from \"./context\";\nimport { mergeElementProps, resolveElementProps } from \"./element-props\";\nimport { pinnedCellStyle, pinnedEdge } from \"./pinning\";\nimport { windowHeaderCells } from \"./use-column-window\";\n\n/**\n * The footer rows that actually render. `getFooterGroups()` mirrors *every* header level, so a\n * grouped header whose totals live on the leaves yields a trailing group row holding nothing —\n * dead space that still draws row and column borders. A level earns its row by carrying a\n * `footer` of its own, which also lets a group column declare one (previously the leaf-only\n * test dropped the whole region in that case).\n */\nexport function visibleFooterGroups<TData extends RowData>(table: TableInstance<TData>) {\n return table.getFooterGroups().filter(footerGroup => footerGroup.headers.some(\n footer => !footer.isPlaceholder && footer.column.columnDef.footer !== undefined\n ));\n}\n\nexport function tableHasFooter<TData extends RowData>(table: TableInstance<TData>): boolean {\n return visibleFooterGroups(table).length > 0;\n}\n\nexport function TableFooter<TData extends RowData>({\n table,\n ariaRowIndexStart,\n columnWindow\n}: {\n table: TableInstance<TData>;\n ariaRowIndexStart?: number;\n columnWindow: ColumnWindowView | null;\n}) {\n const { getStyles, footerRowProps } = useDataTableContext();\n\n const renderCell = (\n footer: Header<TData, unknown>,\n colSpan: number | undefined,\n ariaColIndex: number | undefined\n ) => (\n <MantineTable.Th\n key={footer.id}\n {...mergeElementProps(resolveElementProps(footer.column.columnDef.meta?.footerCellProps, footer), {\n \"aria-colindex\": ariaColIndex,\n colSpan: colSpan ?? footer.colSpan,\n \"data-align\": footer.column.columnDef.meta?.align,\n // Autosize measures the footer like every other rendered cell, and finds it the\n // same way (docs/sizing.md).\n \"data-ledger-column-id\": footer.column.id,\n \"data-pinned\": footer.column.getIsPinned() || undefined,\n \"data-pinned-edge\": pinnedEdge(footer.column),\n // Totals are data, not headers — under the ARIA table they are plain cells.\n role: \"cell\",\n ...getStyles(\"footerCell\", { style: pinnedCellStyle(footer.column) })\n })}\n >\n {footer.isPlaceholder\n ? null\n : flexRender(footer.column.columnDef.footer, footer.getContext())}\n </MantineTable.Th>\n );\n\n return (\n <MantineTable.Tfoot {...getStyles(\"tfoot\")}>\n {visibleFooterGroups(table).map((footerGroup, groupIndex) => (\n <MantineTable.Tr\n key={footerGroup.id}\n {...mergeElementProps(resolveElementProps(footerRowProps, footerGroup), {\n \"aria-rowindex\": ariaRowIndexStart === undefined ? undefined : ariaRowIndexStart + groupIndex,\n role: \"row\",\n ...getStyles(\"footerRow\")\n })}\n >\n {/* Footer groups mirror header groups, so the same clamp rule tiles them\n (docs/virtualization.md#column-virtualization). */}\n {columnWindow === null\n ? footerGroup.headers.map(footer => renderCell(footer, undefined, undefined))\n : windowHeaderCells(footerGroup.headers, columnWindow).map(cell => cell.kind === \"spacer\"\n ? <th key={`ledger:spacer-${cell.edge}`} aria-hidden data-ledger-spacer />\n : renderCell(cell.header, cell.colSpan, cell.ariaColIndex))}\n </MantineTable.Tr>\n ))}\n </MantineTable.Tfoot>\n );\n}\n","import type { ColumnSizingState } from \"@tanstack/react-table\";\n\nimport type { ResizerSpec } from \"./use-column-resize\";\n\n/**\n * Fit a column to its rendered content (the resizer's double-click). Measures the header cell,\n * every RENDERED body cell of the column — under virtualization that is the current window, which\n * is the industry contract for autosize (unrendered rows have no boxes to measure) — and the\n * footer cell, which is rendered content the column has to hold like any other. Writes the result\n * through `columnSizing`, clamped like an interactive resize.\n *\n * The column, its constraints and whether it carries a filter all arrive from the render that put\n * the handle on screen, for the reason `use-column-resize.ts` gives.\n *\n * Measurement forces `white-space: nowrap` on every cell first and reads afterwards, so the\n * whole pass costs one reflow. Truncating cells clip their own overflow (the td never grows),\n * so the content width is read from the `[data-truncate]` span instead of the cell box.\n */\n\n/**\n * Breathing room over the tightest fit — content flush against the column edge reads clipped.\n */\nconst AUTOSIZE_SLACK_PX = 8;\n\n/**\n * Reserved for the hover-revealed header actions overlay (the filter button) so autosize does\n * not park the drag line underneath it.\n */\nconst HEADER_ACTIONS_ALLOWANCE_PX = 28;\n\n/**\n * Computed lengths always resolve to `Npx`; strip the unit before coercing.\n */\nfunction asPx(value: string): number {\n return Number(value.replace(\"px\", \"\")) || 0;\n}\n\nfunction horizontalPadding(element: HTMLElement): number {\n const style = getComputedStyle(element);\n\n return asPx(style.paddingInlineStart) + asPx(style.paddingInlineEnd);\n}\n\nfunction bodyCellWidth(cell: HTMLElement): number {\n const truncated = cell.querySelector<HTMLElement>(\":scope [data-truncate]\");\n\n return truncated\n ? truncated.scrollWidth + horizontalPadding(cell)\n : cell.scrollWidth;\n}\n\nfunction headerCellWidth(th: HTMLElement, hasFilter: boolean): number {\n // The label's truncate span clips its own overflow, so the th box never reports the full\n // text — read the span, then re-add the chrome around it.\n const labelText = th.querySelector<HTMLElement>(\":scope .ledger-header-label [data-truncate]\");\n\n if (!labelText) {\n return th.scrollWidth;\n }\n\n const indicator = th.querySelector<HTMLElement>(\":scope .ledger-sort-indicator\");\n const indicatorWidth = indicator ? indicator.offsetWidth + 6 : 0;\n\n return labelText.scrollWidth\n + indicatorWidth\n + horizontalPadding(th)\n + (hasFilter ? HEADER_ACTIONS_ALLOWANCE_PX : 0);\n}\n\nexport interface AutosizeSpec extends Pick<ResizerSpec, \"columnId\" | \"minSize\" | \"maxSize\"> {\n /**\n * The column carries a filter control, so the header reserves room for the hover overlay.\n */\n hasFilter: boolean;\n}\n\nexport function autosizeColumn(\n setColumnSizing: (updater: (previous: ColumnSizingState) => ColumnSizingState) => void,\n {\n columnId,\n minSize,\n maxSize,\n hasFilter\n }: AutosizeSpec,\n main: HTMLElement\n): void {\n const selector = `[data-ledger-column-id=\"${CSS.escape(columnId)}\"]`;\n const headerCell = main.querySelector<HTMLElement>(`:scope .ledger-header ${selector}`);\n const bodyCells = [...main.querySelectorAll<HTMLElement>(`:scope .ledger-tbody ${selector}`)];\n // A footer cell that spans columns says nothing about the width of any one of them.\n const footerCells = [...main.querySelectorAll<HTMLElement>(`:scope .ledger-footer ${selector}`)]\n .filter(cell => (cell as HTMLTableCellElement).colSpan <= 1);\n const contentCells = [...bodyCells, ...footerCells];\n const cells = headerCell ? [headerCell, ...contentCells] : contentCells;\n\n if (cells.length === 0) {\n return;\n }\n\n // Write phase, then read phase — the forced nowrap costs one reflow for the whole column.\n const previousWhitespace = cells.map(cell => cell.style.whiteSpace);\n\n for (const cell of cells) {\n cell.style.whiteSpace = \"nowrap\";\n }\n\n let content = headerCell ? headerCellWidth(headerCell, hasFilter) : 0;\n\n for (const cell of contentCells) {\n content = Math.max(content, bodyCellWidth(cell));\n }\n\n for (const [index, cell] of cells.entries()) {\n cell.style.whiteSpace = previousWhitespace[index] ?? \"\";\n }\n\n const next = Math.min(Math.max(Math.round(content + AUTOSIZE_SLACK_PX), minSize), maxSize);\n\n setColumnSizing(previous => previous[columnId] === next ? previous : { ...previous, [columnId]: next });\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { DateRangeFilterValue } from \"./filter-fns\";\nimport type { Column, DataTableFilterConfig } from \"./types\";\n\n/**\n * Header filter UI: a funnel trigger (filled while active) opening a popover with the control\n * `meta.filter` declares. Client mode derives `select`/`multi-select` options from faceted\n * values when none are given; server mode requires explicit options and degrades to the text\n * variant (with a dev warning) when they are missing. Date bounds render an inline\n * `@mantine/dates` range calendar (no nested popover to misread as an outside click);\n * its values are the same `YYYY-MM-DD` strings the filter fn compares.\n *\n * Clearing lives on each control, not on a shared popover row: `select`/`multi-select` use\n * their native clear buttons, `text` clears from its right section, `range` from the end of\n * its input row, and the calendar from a caption under it. Only a custom render-prop filter —\n * a black box that may ship no clear of its own — keeps the popover-level fallback.\n */\nimport { ActionIcon, Button, CloseButton, Group, MultiSelect, NumberInput, Popover, Select, Stack, TextInput } from \"@mantine/core\";\nimport { DatePicker } from \"@mantine/dates\";\nimport { useDebouncedCallback } from \"@mantine/hooks\";\nimport { useEffect, useState } from \"react\";\n\nimport { columnHeaderText } from \"./build-columns\";\nimport { useDataTableContext } from \"./context\";\nimport { warnOnce } from \"./env\";\n\nconst FACETED_OPTIONS_CAP = 100;\n\nexport interface FilterPopoverProps<TData extends RowData> {\n column: Column<TData, unknown>;\n}\n\nexport function FilterPopover<TData extends RowData>({ column }: FilterPopoverProps<TData>) {\n const {\n labels,\n icons,\n getStyles,\n filterMode\n } = useDataTableContext();\n const filter = column.columnDef.meta?.filter;\n\n if (!filter || !column.getCanFilter()) {\n return null;\n }\n\n const active = column.getFilterValue() !== undefined;\n // Every filter control in a header is the same control; only the column tells them apart.\n const name = labels.filterColumn(columnHeaderText(column));\n\n return (\n <Popover trapFocus position=\"bottom-start\" width={240}>\n <Popover.Target>\n <ActionIcon\n aria-label={name}\n data-active={active || undefined}\n size=\"sm\"\n variant={active ? \"light\" : \"subtle\"}\n onClick={event => event.stopPropagation()}\n >\n <icons.filterColumn />\n </ActionIcon>\n </Popover.Target>\n\n <Popover.Dropdown {...getStyles(\"filterPopover\")} onClick={event => event.stopPropagation()}>\n <Stack gap=\"xs\">\n {typeof filter === \"function\"\n ? (\n <>\n {filter(column)}\n\n {active && (\n <Group justify=\"flex-end\">\n <CloseButton\n aria-label={labels.clearFilter}\n size=\"sm\"\n onClick={() => column.setFilterValue(undefined)}\n />\n </Group>\n )}\n </>\n )\n : (\n <VariantFilterControl\n column={column}\n config={typeof filter === \"string\" ? { variant: filter } : filter}\n filterMode={filterMode}\n name={name}\n />\n )}\n </Stack>\n </Popover.Dropdown>\n </Popover>\n );\n}\n\ninterface VariantFilterControlProps<TData extends RowData> {\n column: Column<TData, unknown>;\n config: DataTableFilterConfig;\n filterMode: \"client\" | \"server\";\n /**\n * Accessible name, shared with the funnel trigger — a placeholder is not a label.\n */\n name: string;\n}\n\nfunction VariantFilterControl<TData extends RowData>({\n column,\n config,\n filterMode,\n name\n}: VariantFilterControlProps<TData>) {\n const { labels } = useDataTableContext();\n\n switch (config.variant) {\n case \"text\": {\n return <TextFilter column={column} name={name} placeholder={config.placeholder ?? labels.filterPlaceholder} />;\n }\n\n case \"select\": {\n return <SelectFilter column={column} config={config} filterMode={filterMode} name={name} />;\n }\n\n case \"multi-select\": {\n return <SelectFilter column={column} config={config} filterMode={filterMode} name={name} />;\n }\n\n case \"range\": {\n return <RangeFilter column={column} name={name} />;\n }\n\n case \"date-range\": {\n return <DateRangeFilter column={column} name={name} />;\n }\n }\n}\n\n/**\n * The select family, whose two variants differ only in cardinality — one control, one option\n * source, one degradation path.\n */\nfunction SelectFilter<TData extends RowData>({\n column,\n config,\n filterMode,\n name\n}: {\n column: Column<TData, unknown>;\n config: Extract<DataTableFilterConfig, { variant: \"select\" | \"multi-select\" }>;\n filterMode: \"client\" | \"server\";\n name: string;\n}) {\n const { labels } = useDataTableContext();\n const placeholder = config.placeholder ?? labels.filterPlaceholder;\n // Declared options win; client mode derives them from the faceted values, which server mode has\n // no rows to compute. An explicitly empty list is a declaration like any other.\n const options = config.options ?? (filterMode === \"server\" ? undefined : facetedOptions(column));\n\n if (!options) {\n warnOnce(\n `filter-options-${column.id}`,\n `Column \"${column.id}\" uses a ${config.variant} filter in server mode without options — faceted values need client-side rows. Falling back to a text filter.`\n );\n\n return <TextFilter column={column} name={name} placeholder={placeholder} />;\n }\n\n if (config.variant === \"multi-select\") {\n return (\n <MultiSelect\n clearable\n searchable\n aria-label={name}\n clearButtonProps={{ \"aria-label\": labels.clearFilter }}\n comboboxProps={{ withinPortal: false }}\n data={options}\n placeholder={placeholder}\n value={(column.getFilterValue() as string[] | undefined) ?? []}\n onChange={value => column.setFilterValue(value.length > 0 ? value : undefined)}\n />\n );\n }\n\n return (\n <Select\n clearable\n searchable\n aria-label={name}\n clearButtonProps={{ \"aria-label\": labels.clearFilter }}\n // Inside the filter popover the combobox must not portal out: a portal dropdown\n // reads as an outside click and closes the popover mid-interaction.\n comboboxProps={{ withinPortal: false }}\n data={options}\n placeholder={placeholder}\n value={(column.getFilterValue() as string | undefined) ?? null}\n onChange={value => column.setFilterValue(value ?? undefined)}\n />\n );\n}\n\nfunction TextFilter<TData extends RowData>({\n column,\n name,\n placeholder\n}: { column: Column<TData, unknown>; name: string; placeholder: string }) {\n // Straight from the context, never through a table instance: this control redraws from its\n // own state, in renders the table root has no part in, and the instance it would reach for\n // then is whatever pass wrote it last (context.ts).\n const { labels, subscribeColumnFilters } = useDataTableContext();\n // Only a string is this control's value. A server-mode `select`/`multi-select` that degrades\n // here (no options to build) inherits whatever filter was already set, and a multi-select's is\n // an array — which a TextInput would render as its comma-joined form and then write back as\n // one string.\n const raw = column.getFilterValue();\n const filterValue = typeof raw === \"string\" ? raw : \"\";\n const [value, setValue] = useState(filterValue);\n const apply = useDebouncedCallback(\n (next: string) => column.setFilterValue(next === \"\" ? undefined : next),\n { delay: 200, flushOnUnmount: true }\n );\n\n useEffect(() => subscribeColumnFilters?.(filters => {\n const next = filters.find(filter => filter.id === column.id)?.value;\n\n apply.cancel();\n setValue(typeof next === \"string\" ? next : \"\");\n }), [apply, column.id, subscribeColumnFilters]);\n\n useEffect(() => {\n apply.cancel();\n setValue(filterValue);\n }, [apply, filterValue]);\n\n return (\n <TextInput\n aria-label={name}\n placeholder={placeholder}\n rightSectionPointerEvents=\"all\"\n value={value}\n rightSection={value !== \"\" && (\n <CloseButton\n aria-label={labels.clearFilter}\n size=\"sm\"\n onClick={() => {\n apply.cancel();\n setValue(\"\");\n column.setFilterValue(undefined);\n }}\n />\n )}\n onChange={event => {\n setValue(event.currentTarget.value);\n apply(event.currentTarget.value);\n }}\n />\n );\n}\n\nfunction RangeFilter<TData extends RowData>({ column, name }: { column: Column<TData, unknown>; name: string }) {\n const { labels } = useDataTableContext();\n const [min, max] = (column.getFilterValue() as [number | undefined, number | undefined] | undefined) ?? [\n undefined,\n undefined\n ];\n const [facetMin, facetMax] = column.getFacetedMinMaxValues() ?? [undefined, undefined];\n\n const setBound = (index: 0 | 1) => (raw: number | string) => {\n const bound = typeof raw === \"number\" ? raw : undefined;\n const next: [number | undefined, number | undefined] = index === 0 ? [bound, max] : [min, bound];\n column.setFilterValue(next[0] === undefined && next[1] === undefined ? undefined : next);\n };\n\n const active = min !== undefined || max !== undefined;\n\n return (\n // The pair is one control: the group carries the column's name, the inputs their bound.\n <Group aria-label={name} gap=\"xs\" role=\"group\" wrap=\"nowrap\">\n <NumberInput\n aria-label={labels.filterRangeMin}\n flex={1}\n placeholder={facetMin === undefined ? labels.filterRangeMin : String(facetMin)}\n value={min ?? \"\"}\n onChange={setBound(0)}\n />\n\n <NumberInput\n aria-label={labels.filterRangeMax}\n flex={1}\n placeholder={facetMax === undefined ? labels.filterRangeMax : String(facetMax)}\n value={max ?? \"\"}\n onChange={setBound(1)}\n />\n\n {/* Space is reserved while inactive so the inputs keep their width as the button appears. */}\n <CloseButton\n aria-label={labels.clearFilter}\n size=\"sm\"\n style={{ visibility: active ? undefined : \"hidden\" }}\n onClick={() => column.setFilterValue(undefined)}\n />\n </Group>\n );\n}\n\nfunction DateRangeFilter<TData extends RowData>({ column, name }: { column: Column<TData, unknown>; name: string }) {\n const { labels } = useDataTableContext();\n const filterValue = column.getFilterValue() as DateRangeFilterValue | undefined;\n const value = filterValue ?? [null, null];\n\n return (\n <>\n <DatePicker\n allowSingleDateInRange\n highlightToday\n aria-label={name}\n size=\"xs\"\n type=\"range\"\n value={value}\n onChange={next => column.setFilterValue(!next[0] && !next[1] ? undefined : next)}\n />\n\n {/* The calendar has no input row to host a clear button; a quiet caption under it is the\n date-picker-panel convention instead. */}\n {filterValue !== undefined && (\n <Group justify=\"flex-end\">\n <Button\n color=\"gray\"\n size=\"compact-xs\"\n variant=\"subtle\"\n onClick={() => column.setFilterValue(undefined)}\n >\n {labels.clearFilter}\n </Button>\n </Group>\n )}\n </>\n );\n}\n\nfunction facetedOptions<TData extends RowData>(column: Column<TData, unknown>): string[] {\n const values: string[] = [];\n\n for (const key of column.getFacetedUniqueValues().keys()) {\n if (key === null || key === undefined || key === \"\") {\n continue;\n }\n\n if (Array.isArray(key)) {\n for (const entry of key) {\n if (entry !== null && entry !== undefined) {\n values.push(String(entry));\n }\n }\n } else {\n values.push(String(key));\n }\n }\n\n return [...new Set(values)].toSorted().slice(0, FACETED_OPTIONS_CAP);\n}\n","/**\n * Pointer-based header drag reordering — no drag-and-drop dependency. A press becomes a drag\n * after a 5px threshold, so the sortable header label keeps its click; a completed drag\n * suppresses the click that follows pointerup. Escape and pointercancel abandon the drag, and\n * a mid-drag unmount releases the window listeners. Reordering is limited to single-row\n * headers: with column groups, sibling order inside a group is ambiguous.\n */\nimport type { RowData } from \"@tanstack/react-table\";\nimport type { PointerEvent as ReactPointerEvent } from \"react\";\n\nimport type { ColumnDropTarget } from \"./column-order\";\nimport type { TableInstance } from \"./types\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { isInternalColumn } from \"./build-columns\";\nimport { getColumnZone, reorderColumnWithinZone } from \"./column-order\";\nimport { warnOnce } from \"./env\";\n\nconst DRAG_THRESHOLD_PX = 5;\n\nexport interface ColumnDragState {\n draggedId: string | null;\n targetId: string | null;\n side: \"before\" | \"after\" | null;\n}\n\nconst IDLE: ColumnDragState = {\n draggedId: null,\n targetId: null,\n side: null\n};\n\nexport interface ColumnReorder {\n drag: ColumnDragState;\n getHeaderProps: (columnId: string) => { onPointerDown?: (event: ReactPointerEvent<HTMLElement>) => void };\n /**\n * True exactly once after a completed drag — the header label uses it to swallow the click.\n */\n consumeClickSuppression: () => boolean;\n}\n\ninterface DragSession {\n columnId: string;\n startX: number;\n started: boolean;\n target: ColumnDropTarget | null;\n cleanup: () => void;\n}\n\nexport function useColumnReorder<TData extends RowData>(table: TableInstance<TData>): ColumnReorder {\n const [drag, setDrag] = useState<ColumnDragState>(IDLE);\n const session = useRef<DragSession | null>(null);\n const suppressClick = useRef(false);\n\n // The listeners live on window, so a mid-drag unmount must release them here.\n useEffect(() => () => {\n session.current?.cleanup();\n session.current = null;\n }, []);\n\n const enabledOption = table.options.meta?.ledger?.enableColumnOrdering === true;\n const hasGroupedHeaders = table.getHeaderGroups().length > 1;\n\n if (enabledOption && hasGroupedHeaders) {\n warnOnce(\n \"reorder-grouped-headers\",\n \"enableColumnOrdering is ignored for tables with header groups — sibling order inside a group is ambiguous.\"\n );\n }\n\n const enabled = enabledOption && !hasGroupedHeaders;\n\n const commitReorder = (draggedId: string, target: ColumnDropTarget) => {\n reorderColumnWithinZone(table, draggedId, target);\n };\n\n const getHeaderProps: ColumnReorder[\"getHeaderProps\"] = columnId => {\n if (!enabled || isInternalColumn(columnId)) {\n return {};\n }\n\n return {\n onPointerDown: event => {\n if (\n event.button !== 0\n || session.current\n || (event.target as HTMLElement).closest(\"[data-ledger-no-drag]\")\n ) {\n return;\n }\n\n const onPointerMove = (move: globalThis.PointerEvent) => {\n const { current } = session;\n\n if (!current) {\n return;\n }\n\n if (!current.started) {\n if (Math.abs(move.clientX - current.startX) < DRAG_THRESHOLD_PX) {\n return;\n }\n\n current.started = true;\n }\n\n const headerCell = document\n .elementFromPoint(move.clientX, move.clientY)\n ?.closest<HTMLElement>(\"[data-ledger-column-id]\");\n const targetId = headerCell?.dataset.ledgerColumnId;\n\n let target: DragSession[\"target\"] = null;\n\n if (\n headerCell\n && targetId\n && targetId !== current.columnId\n && !isInternalColumn(targetId)\n && getColumnZone(table, targetId) === getColumnZone(table, current.columnId)\n ) {\n const rect = headerCell.getBoundingClientRect();\n // `before`/`after` are logical, like the drop indicator that renders them: in RTL a\n // cell's leading half is its RIGHT half, so the physical test has to be mirrored\n // (the same reasoning the resize drag applies to its delta).\n const rtl = getComputedStyle(headerCell).direction === \"rtl\";\n const inLeftHalf = move.clientX < rect.left + rect.width / 2;\n\n target = { id: targetId, side: inLeftHalf === rtl ? \"after\" : \"before\" };\n }\n\n current.target = target;\n setDrag({\n draggedId: current.columnId,\n targetId: target?.id ?? null,\n side: target?.side ?? null\n });\n };\n\n const endSession = (commit: boolean) => {\n const { current } = session;\n\n if (!current) {\n return;\n }\n\n current.cleanup();\n session.current = null;\n\n if (current.started) {\n suppressClick.current = true;\n\n if (commit && current.target) {\n commitReorder(current.columnId, current.target);\n }\n }\n\n setDrag(IDLE);\n };\n\n const onPointerUp = () => endSession(true);\n\n const onPointerCancel = () => {\n const { current } = session;\n\n // The browser aborted the pointer stream and no click will follow, so ending the\n // session here must not arm the click suppression.\n if (current) {\n current.started = false;\n }\n\n endSession(false);\n };\n\n const onKeyDown = (key: globalThis.KeyboardEvent) => {\n if (key.key === \"Escape\") {\n endSession(false);\n }\n };\n\n session.current = {\n columnId,\n startX: event.clientX,\n started: false,\n target: null,\n cleanup: () => {\n removeEventListener(\"pointermove\", onPointerMove);\n removeEventListener(\"pointerup\", onPointerUp);\n removeEventListener(\"pointercancel\", onPointerCancel);\n removeEventListener(\"keydown\", onKeyDown);\n }\n };\n\n addEventListener(\"pointermove\", onPointerMove);\n addEventListener(\"pointerup\", onPointerUp);\n addEventListener(\"pointercancel\", onPointerCancel);\n addEventListener(\"keydown\", onKeyDown);\n }\n };\n };\n\n const consumeClickSuppression = () => {\n if (!suppressClick.current) {\n return false;\n }\n\n suppressClick.current = false;\n\n return true;\n };\n\n return {\n drag,\n getHeaderProps,\n consumeClickSuppression\n };\n}\n","import type { ColumnSizingState } from \"@tanstack/react-table\";\nimport type { PointerEvent as ReactPointerEvent } from \"react\";\n\n/**\n * Pointer-based column resizing, exact by construction: the drag starts from the width the\n * engine actually rendered (docs/sizing.md), so a grow column's first drag is 1:1 instead of\n * jumping to a default. Live updates write `columnSizing` (the CSS-variable pipeline keeps this\n * cheap); Escape and pointercancel restore the width the drag started from; direction follows\n * the computed `direction` of the handle, so RTL drags resolve correctly. A mid-drag unmount\n * releases the window listeners without touching table state.\n *\n * Nothing here reaches for the table at event time. Everything a drag decides with — the column,\n * the width on screen, the constraints, the entry to restore — arrives as a `ResizerSpec` from the\n * render that put the handle on screen, because the shared TanStack core carries whatever render\n * pass ran last, a discarded one included (docs/architecture.md).\n */\nimport { useEffect, useRef, useState } from \"react\";\n\nexport interface ResizerSpec {\n columnId: string;\n /**\n * The engine-resolved width this render drew — the edge the user is grabbing.\n */\n width: number;\n minSize: number;\n maxSize: number;\n /**\n * This render's `columnSizing` entry. Escape restores it; absent means a grow column, which\n * Escape returns to having no entry at all.\n */\n sizingEntry: number | undefined;\n}\n\nexport interface ColumnResize {\n resizingId: string | null;\n getResizerProps: (spec: ResizerSpec) => { onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void };\n}\n\ninterface ResizeSession {\n startX: number;\n rtl: boolean;\n /**\n * Whether the handle for this column is still on screen, in *this* table. Asked of the table's\n * own root rather than of a captured handle — that node is replaced whenever the header\n * re-renders, which a live drag does on every move — and scoped to that root rather than to the\n * document, because two tables on a page routinely share a column id and a `name` handle in the\n * other one says nothing about this drag. It is the only signal a window-level pointer stream\n * gets that a real render has taken its column away.\n */\n onScreen: () => boolean;\n cleanup: () => void;\n}\n\nexport function useColumnResize(\n setColumnSizing: (updater: (previous: ColumnSizingState) => ColumnSizingState) => void\n): ColumnResize {\n const [resizingId, setResizingId] = useState<string | null>(null);\n const session = useRef<ResizeSession | null>(null);\n\n // The listeners live on window, so a mid-drag unmount must release them here.\n useEffect(() => () => {\n session.current?.cleanup();\n session.current = null;\n }, []);\n\n const getResizerProps: ColumnResize[\"getResizerProps\"] = ({\n columnId,\n width,\n minSize,\n maxSize,\n sizingEntry\n }) => {\n return {\n onPointerDown: event => {\n if (event.button !== 0 || session.current) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n // Captured now: React clears `currentTarget` once the dispatch returns, and the handlers\n // below outlive it.\n const handle = event.currentTarget;\n const rtl = getComputedStyle(handle).direction === \"rtl\";\n // The table this handle belongs to. `.ledger-main` is structural — it is there for as long\n // as the table is — so it survives the header re-rendering under the drag, while the\n // handle itself does not.\n const root = handle.closest(\".ledger-main\");\n const handleSelector = `.ledger-header [data-ledger-column-id=\"${CSS.escape(columnId)}\"] [data-ledger-resizer]`;\n\n const endSession = (restore: boolean) => {\n const { current } = session;\n\n if (!current) {\n return;\n }\n\n current.cleanup();\n session.current = null;\n setResizingId(null);\n\n if (restore) {\n setColumnSizing(previous => {\n const { [columnId]: _dropped, ...rest } = previous;\n\n return sizingEntry === undefined ? rest : { ...rest, [columnId]: sizingEntry };\n });\n }\n };\n\n const onPointerMove = (move: globalThis.PointerEvent) => {\n const { current } = session;\n\n if (!current) {\n return;\n }\n\n // The column really left the screen mid-drag. There is nothing under the pointer to\n // resize any more, and writing a width for a column the table no longer has is worse\n // than stopping — restoring would be too, since the entry it would restore is for a\n // column that is gone.\n if (!current.onScreen()) {\n endSession(false);\n\n return;\n }\n\n const delta = (move.clientX - current.startX) * (current.rtl ? -1 : 1);\n const next = Math.min(Math.max(Math.round(width + delta), minSize), maxSize);\n\n setColumnSizing(previous => previous[columnId] === next ? previous : { ...previous, [columnId]: next });\n };\n\n const onPointerUp = () => endSession(false);\n\n // The browser aborted the pointer stream (touch pan takeover, OS gesture) — no\n // pointerup will follow, so treat it like Escape and restore.\n const onPointerCancel = () => endSession(true);\n\n const onKeyDown = (key: globalThis.KeyboardEvent) => {\n if (key.key === \"Escape\") {\n endSession(true);\n }\n };\n\n session.current = {\n startX: event.clientX,\n rtl,\n onScreen: () => root !== null && root.isConnected && root.querySelector(handleSelector) !== null,\n cleanup: () => {\n removeEventListener(\"pointermove\", onPointerMove);\n removeEventListener(\"pointerup\", onPointerUp);\n removeEventListener(\"pointercancel\", onPointerCancel);\n removeEventListener(\"keydown\", onKeyDown);\n }\n };\n setResizingId(columnId);\n\n addEventListener(\"pointermove\", onPointerMove);\n addEventListener(\"pointerup\", onPointerUp);\n addEventListener(\"pointercancel\", onPointerCancel);\n addEventListener(\"keydown\", onKeyDown);\n }\n };\n };\n\n return {\n resizingId,\n getResizerProps\n };\n}\n","import type { ColumnSizingState, RowData } from \"@tanstack/react-table\";\nimport type { MouseEvent } from \"react\";\n\nimport type { SortToggleSpec } from \"./toggle-fns\";\nimport type { Header, TableInstance } from \"./types\";\nimport type { ResizerSpec } from \"./use-column-resize\";\nimport type { ColumnWindowView } from \"./use-column-window\";\n\n/**\n * The header: sortable labels (full-area button, shift for multi-sort, order badges), the\n * hover-revealed filter popover, the resize handle on the trailing edge, and drag-reorder\n * plumbing. Every state is a data-attribute; every class is a Styles API selector. Column\n * layout — order, visibility, pinning, width, grouping — belongs to `DataTable.ColumnsPanel`,\n * not to the header (docs/columns.md).\n */\nimport { Table as MantineTable, Tooltip } from \"@mantine/core\";\nimport { flexRender } from \"@tanstack/react-table\";\n\nimport { autosizeColumn } from \"./autosize-column\";\nimport { columnEnableResizing, isInternalColumn } from \"./build-columns\";\nimport { useDataTableContext } from \"./context\";\nimport { mergeElementProps, resolveElementProps } from \"./element-props\";\nimport { FilterPopover } from \"./filter-popover\";\nimport { ledgerCommands } from \"./ledger-commands\";\nimport { pinnedCellStyle, pinnedEdge } from \"./pinning\";\nimport { syncTruncationTitle } from \"./truncate\";\nimport { useColumnReorder } from \"./use-column-reorder\";\nimport { useColumnResize } from \"./use-column-resize\";\nimport { windowHeaderCells } from \"./use-column-window\";\n\n/**\n * `columnWidths` and `columnSizing` arrive as props, not through the context or the table: a drag\n * departs from the edge the user grabbed and restores what that render had, and both belong to\n * the render that drew the handle. Reaching for either at event time reaches the shared core,\n * which carries whatever render pass ran last — a discarded one included\n * (docs/architecture.md).\n */\nexport function TableHeader<TData extends RowData>({\n table,\n columnWidths,\n columnSizing,\n columnWindow\n}: {\n table: TableInstance<TData>;\n columnWidths: Record<string, number>;\n columnSizing: ColumnSizingState;\n columnWindow: ColumnWindowView | null;\n}) {\n const {\n getStyles,\n virtualizedRows,\n headerRowProps\n } = useDataTableContext();\n const reorder = useColumnReorder(table);\n const resize = useColumnResize(table.setColumnSizing);\n\n const renderCell = (\n header: Header<TData, unknown>,\n colSpan: number | undefined,\n ariaColIndex: number | undefined\n ) => (\n <HeaderCell\n key={header.id}\n ariaColIndex={ariaColIndex}\n colSpan={colSpan}\n columnSizing={columnSizing}\n columnWidths={columnWidths}\n header={header}\n reorder={reorder}\n resize={resize}\n table={table}\n />\n );\n\n return (\n <MantineTable.Thead {...getStyles(\"thead\")}>\n {table.getHeaderGroups().map((headerGroup, groupIndex) => (\n <MantineTable.Tr\n key={headerGroup.id}\n {...mergeElementProps(resolveElementProps(headerRowProps, headerGroup), {\n \"aria-rowindex\": virtualizedRows ? groupIndex + 1 : undefined,\n role: \"row\",\n ...getStyles(\"headerRow\")\n })}\n >\n {columnWindow === null\n ? headerGroup.headers.map(header => renderCell(header, undefined, undefined))\n : windowHeaderCells(headerGroup.headers, columnWindow).map(cell => cell.kind === \"spacer\"\n ? <th key={`ledger:spacer-${cell.edge}`} aria-hidden data-ledger-spacer />\n : renderCell(cell.header, cell.colSpan, cell.ariaColIndex))}\n </MantineTable.Tr>\n ))}\n </MantineTable.Thead>\n );\n}\n\ninterface HeaderCellProps<TData extends RowData> {\n header: Header<TData, unknown>;\n table: TableInstance<TData>;\n reorder: ReturnType<typeof useColumnReorder>;\n resize: ReturnType<typeof useColumnResize>;\n columnWidths: Record<string, number>;\n columnSizing: ColumnSizingState;\n /**\n * Both set only under a column window: the clamp rule's colSpan (use-column-window.ts)\n * replaces `header.colSpan`, and the 1-based position covers windowed-out columns too.\n */\n colSpan: number | undefined;\n ariaColIndex: number | undefined;\n}\n\nfunction HeaderCell<TData extends RowData>({\n header,\n table,\n reorder,\n resize,\n columnWidths,\n columnSizing,\n colSpan,\n ariaColIndex\n}: HeaderCellProps<TData>) {\n const {\n getStyles,\n labels,\n icons\n } = useDataTableContext();\n const { column } = header;\n const { meta } = column.columnDef;\n const internal = isInternalColumn(column.id);\n\n const canSort = column.getCanSort();\n const sorted = column.getIsSorted();\n /**\n * The whole of what a sort click applies, resolved here. v9's own handler asks the column\n * again when the click lands — for the gate, for the direction the cycle turns to next — and\n * both of those reads go to the shared core (`toggle-fns.ts`).\n */\n const sortSpec: SortToggleSpec = {\n canMultiSort: column.getCanMultiSort(),\n columnId: column.id,\n maxMultiSortColCount: table.options.maxMultiSortColCount ?? Number.MAX_SAFE_INTEGER,\n nextOrderMulti: column.getNextSortingOrder(true),\n nextOrderSingle: column.getNextSortingOrder(false)\n };\n // v9's own default, restated: the feature's `getDefaultTableOptions` is merged into the core's\n // options, not into the wrapper's, so reading only `table.options` here would silently make\n // every click a single-sort. A consumer override through `tableOptions` still wins.\n const isMultiSortEvent = table.options.isMultiSortEvent ?? ((event: unknown) => (event as MouseEvent).shiftKey);\n const sorting = ledgerCommands(table.options.meta?.ledger)?.sorting;\n const sortCount = table.atoms.sorting.get().length;\n const sortIndex = column.getSortIndex();\n // Ledger's own gate: the TanStack `columnResizingFeature` (and its `getCanResize`) is\n // deliberately unregistered — the drag pipeline is ledger's (docs/sizing.md).\n const canResize\n = table.options.meta?.ledger?.enableColumnResizing === true\n && columnEnableResizing(column.columnDef) !== false\n // Only leaves have a width: the engine resolves and consumes leaf sizing, so a handle on\n // a group header would write a `columnSizing` entry nothing ever reads.\n && column.columns.length === 0;\n const resizing = resize.resizingId === column.id;\n /**\n * Everything a drag or a fit decides with, read here, in the render that draws the handle —\n * the width on screen, the constraints this render's definition carries, the entry Escape puts\n * back, and whether the header reserves room for a filter control. The handler on the DOM then\n * needs nothing from the table at all (docs/architecture.md).\n */\n const resizerSpec: ResizerSpec = {\n columnId: column.id,\n width: columnWidths[column.id] ?? column.getSize(),\n minSize: column.columnDef.minSize ?? 20,\n maxSize: column.columnDef.maxSize ?? Number.MAX_SAFE_INTEGER,\n sizingEntry: columnSizing[column.id]\n };\n\n const dragged = reorder.drag.draggedId === column.id;\n const dropSide = reorder.drag.targetId === column.id ? reorder.drag.side : null;\n\n const ariaSort = sorted === \"asc\" ? \"ascending\" : sorted === \"desc\" ? \"descending\" : undefined;\n\n const handleSortClick = (event: MouseEvent) => {\n if (reorder.consumeClickSuppression()) {\n return;\n }\n\n if (!canSort) {\n return;\n }\n\n sorting?.toggle(sortSpec, sortSpec.canMultiSort && (isMultiSortEvent?.(event) ?? false));\n };\n\n const label = header.isPlaceholder\n ? null\n : flexRender(column.columnDef.header, header.getContext());\n\n return (\n <MantineTable.Th\n {...mergeElementProps(resolveElementProps(meta?.headerCellProps, header), {\n \"aria-colindex\": ariaColIndex,\n \"aria-sort\": canSort ? ariaSort : undefined,\n colSpan: colSpan ?? header.colSpan,\n \"data-align\": internal ? \"center\" : meta?.align,\n \"data-dragging\": dragged || undefined,\n \"data-drop-side\": dropSide ?? undefined,\n \"data-ledger-column-id\": column.id,\n \"data-pinned\": column.getIsPinned() || undefined,\n \"data-pinned-edge\": pinnedEdge(column),\n \"data-resizing\": resizing || undefined,\n \"data-sortable\": canSort || undefined,\n role: \"columnheader\",\n ...getStyles(\"headerCell\", { style: pinnedCellStyle(column) }),\n ...reorder.getHeaderProps(column.id)\n })}\n >\n {header.isPlaceholder\n ? null\n : internal\n // Injected headers (checkbox, expand-all) are controls, not text — the label\n // scaffolding's [data-truncate] span would clip them at the cell's content box.\n ? label\n : (\n <>\n {canSort\n ? (\n // A NATIVE button, reset in ledger's layer: Mantine's UnstyledButton ships an\n // unlayered font-size that defeats the layered `font: inherit` (styling.md).\n <button\n type=\"button\"\n onClick={handleSortClick}\n {...getStyles(\"headerLabel\")}\n data-align={meta?.align}\n >\n <span data-truncate onPointerEnter={syncTruncationTitle}>{label}</span>\n\n <span {...getStyles(\"sortIndicator\")} data-sorted={sorted || undefined}>\n {sorted === \"asc\" && <icons.sortAsc size={14} />}\n {sorted === \"desc\" && <icons.sortDesc size={14} />}\n {sorted === false && <icons.sortable size={14} />}\n {sorted !== false && sortCount > 1 && sortIndex >= 0 && <sup>{sortIndex + 1}</sup>}\n </span>\n </button>\n )\n : (\n <div {...getStyles(\"headerLabel\")} data-align={meta?.align}>\n <span data-truncate onPointerEnter={syncTruncationTitle}>{label}</span>\n </div>\n )}\n\n {meta?.filter !== undefined && (\n <div {...getStyles(\"headerActions\")} data-ledger-no-drag>\n <FilterPopover column={column} />\n </div>\n )}\n\n {canResize && (\n <Tooltip disabled={resizing} label={labels.resizeColumn} openDelay={500}>\n <div\n // A pointer-only affordance, hidden from assistive tech on purpose: it\n // takes no focus and answers no key, and the keyboard route to the same\n // `columnSizing` entry is the columns panel's width field\n // (docs/accessibility.md). Announcing an inoperable control would be worse\n // than announcing nothing; the hint rides a hover Tooltip for the mouse,\n // disabled mid-drag so it never chases the handle.\n aria-hidden\n data-ledger-no-drag\n data-ledger-resizer\n data-resizing={resizing || undefined}\n onClick={event => event.stopPropagation()}\n onDoubleClick={event => {\n const main = event.currentTarget.closest<HTMLElement>(\".ledger-main\");\n\n if (main) {\n autosizeColumn(\n table.setColumnSizing,\n { ...resizerSpec, hasFilter: meta?.filter !== undefined },\n main\n );\n }\n }}\n {...resize.getResizerProps(resizerSpec)}\n {...getStyles(\"resizer\")}\n />\n </Tooltip>\n )}\n </>\n )}\n </MantineTable.Th>\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Column, TableInstance } from \"./types\";\n\n/**\n * The width engine (docs/sizing.md): every visible leaf column resolves to an exact integer\n * pixel width, so the rendered width, the specified width, and the pinned-offset basis are one\n * number system — the browser never redistributes anything.\n *\n * Rules, in order:\n * - a column with an explicit width (user-resized `columnSizing` entry, else the author's\n * `size`, else `defaultColumn.size`) is fixed at that width, clamped to its declared min/max;\n * - a column without one is a grow column with basis `minSize ?? 80`; container surplus is\n * distributed proportionally to the bases (integer floor, remainder in display order), capped\n * by maxSize; when the container is too small every grow column falls back to its basis and the\n * table overflows into horizontal scroll;\n * - with no grow columns at all, surplus distributes proportionally over every column up to each\n * maxSize. Hard maximums win over filling the viewport.\n *\n * Author sizing comes from the raw-definition registry (`rawColumnSizing`), never from\n * `column.columnDef` — TanStack merges `size: 150, minSize: 20` defaults into every resolved\n * definition, which would make \"unsized\" unrepresentable.\n */\nimport { useCallback, useLayoutEffect, useMemo, useState } from \"react\";\n\nimport { rawColumnSizing } from \"./build-columns\";\n\n/**\n * Grow basis for columns that declare neither `size` nor `minSize`.\n */\nconst DEFAULT_FLEX_BASIS = 80;\n\nexport interface ColumnWidthSpec {\n id: string;\n size: number | undefined;\n minSize: number | undefined;\n maxSize: number | undefined;\n}\n\nexport interface ColumnWidths {\n /**\n * Resolved width per visible leaf column id, integer pixels.\n */\n byId: Record<string, number>;\n /**\n * Sum of all resolved widths — the exact table width.\n */\n total: number;\n}\n\nfunction finiteNumber(value: number | undefined): number | undefined {\n return value !== undefined && Number.isFinite(value) ? value : undefined;\n}\n\nfunction normalizedBound(value: number | undefined): number | undefined {\n const finite = finiteNumber(value);\n\n return finite === undefined ? undefined : Math.max(0, Math.round(finite));\n}\n\nfunction clampWidth(value: number, min: number | undefined, max: number | undefined): number {\n const rounded = Number.isFinite(value) ? Math.max(0, Math.round(value)) : 0;\n\n return Math.min(\n Math.max(rounded, normalizedBound(min) ?? 0),\n normalizedBound(max) ?? Number.MAX_SAFE_INTEGER\n );\n}\n\ninterface SurplusRecipient {\n id: string;\n weight: number;\n max: number | undefined;\n}\n\n/**\n * Weighted water-filling over integer pixels. Columns that hit maxSize leave the active set and\n * the remaining space is redistributed over columns that can still grow. If every column reaches\n * its cap, maxSize wins and the table intentionally stops short of the viewport.\n */\nfunction distributeSurplus(\n byId: Record<string, number>,\n recipients: SurplusRecipient[],\n surplus: number\n): void {\n let remaining = surplus;\n\n while (remaining > 0) {\n const active = recipients.filter(\n recipient => recipient.max === undefined || byId[recipient.id]! < recipient.max\n );\n\n if (active.length === 0) {\n return;\n }\n\n const positiveWeightTotal = active.reduce(\n (total, recipient) => total + Math.max(0, recipient.weight),\n 0\n );\n const equalWeight = positiveWeightTotal === 0;\n const weightTotal = equalWeight ? active.length : positiveWeightTotal;\n let distributed = 0;\n\n for (const recipient of active) {\n const current = byId[recipient.id]!;\n const capacity = recipient.max === undefined\n ? Infinity\n : recipient.max - current;\n const weight = equalWeight ? 1 : Math.max(0, recipient.weight);\n const share = Math.min(capacity, Math.floor((remaining * weight) / weightTotal));\n\n if (share > 0) {\n byId[recipient.id] = current + share;\n distributed += share;\n }\n }\n\n remaining -= distributed;\n\n if (remaining === 0) {\n return;\n }\n\n // Every proportional share rounded to zero. Hand the integer remainder out in display order;\n // this preserves the engine's established \"remainder to the first columns\" determinism.\n if (distributed === 0) {\n for (const recipient of active) {\n const current = byId[recipient.id]!;\n const capacity = recipient.max === undefined\n ? Infinity\n : recipient.max - current;\n\n if (capacity > 0) {\n byId[recipient.id] = current + 1;\n remaining -= 1;\n }\n\n if (remaining === 0) {\n return;\n }\n }\n }\n }\n}\n\nexport function resolveColumnWidths(\n columns: ColumnWidthSpec[],\n columnSizing: Record<string, number>,\n availableWidth: number\n): ColumnWidths {\n const byId: Record<string, number> = {};\n const growColumns: SurplusRecipient[] = [];\n\n for (const column of columns) {\n const sized = finiteNumber(columnSizing[column.id]) ?? finiteNumber(column.size);\n\n if (sized === undefined) {\n const basis = clampWidth(column.minSize ?? DEFAULT_FLEX_BASIS, column.minSize, column.maxSize);\n byId[column.id] = basis;\n growColumns.push({\n id: column.id,\n weight: basis,\n max: normalizedBound(column.maxSize)\n });\n } else {\n byId[column.id] = clampWidth(sized, column.minSize, column.maxSize);\n }\n }\n\n const baseTotal = columns.reduce((total, column) => total + (byId[column.id] ?? 0), 0);\n const targetWidth = Number.isFinite(availableWidth) ? Math.max(0, Math.round(availableWidth)) : 0;\n const surplus = targetWidth - baseTotal;\n\n if (surplus > 0) {\n const recipients = growColumns.length > 0\n ? growColumns\n : columns.map(column => {\n return {\n id: column.id,\n weight: byId[column.id] ?? 0,\n max: normalizedBound(column.maxSize)\n };\n });\n\n distributeSurplus(byId, recipients, surplus);\n }\n\n const total = columns.reduce((sum, column) => sum + (byId[column.id] ?? 0), 0);\n\n return { byId, total };\n}\n\n/**\n * Resolve `tableMinWidth` to pixels. Numbers are pixels; strings are resolved through the\n * body table's computed style (the browser turns rem/em into px there).\n */\nfunction minWidthPx(tableMinWidth: number | string | undefined, viewport: HTMLElement | null): number {\n if (tableMinWidth === undefined) {\n return 0;\n }\n\n if (typeof tableMinWidth === \"number\") {\n return tableMinWidth;\n }\n\n const tableElement = viewport?.querySelector(\"table\");\n\n if (!tableElement) {\n // eslint-disable-next-line unicorn/prefer-number-coercion -- parses CSS lengths (\"60rem\"); Number() would yield NaN\n return Number.parseFloat(tableMinWidth) || 0;\n }\n\n // eslint-disable-next-line unicorn/prefer-number-coercion -- parses the computed \"123px\" string; Number() would yield NaN\n return Number.parseFloat(getComputedStyle(tableElement).minWidth) || 0;\n}\n\nexport function useColumnWidths<TData extends RowData>(\n table: TableInstance<TData>,\n /**\n * Visible leaf columns in DISPLAY order (pinned-aware) — the same order the colgroup renders.\n */\n columns: Array<Column<TData, unknown>>,\n viewport: HTMLDivElement | null,\n tableMinWidth: number | string | undefined\n): ColumnWidths {\n const [availableWidth, setAvailableWidth] = useState(0);\n\n const measure = useCallback(() => {\n if (!viewport) {\n return;\n }\n\n const next = Math.max(viewport.clientWidth, minWidthPx(tableMinWidth, viewport));\n setAvailableWidth(previous => previous === next ? previous : next);\n }, [viewport, tableMinWidth]);\n\n /* Pre-paint measurement: the corrected widths land before the first frame is shown. */\n useLayoutEffect(() => {\n measure();\n\n if (!viewport) {\n return;\n }\n\n const observer = new ResizeObserver(measure);\n observer.observe(viewport);\n\n return () => observer.disconnect();\n }, [viewport, measure]);\n\n const { columnSizing } = table.state;\n const { defaultColumn } = table.options;\n\n const resolved = useMemo(\n () => {\n const specs = columns.map<ColumnWidthSpec>(column => {\n const raw = rawColumnSizing(column.columnDef);\n\n return {\n id: column.id,\n size: raw ? raw.size ?? defaultColumn?.size : column.columnDef.size,\n minSize: raw ? raw.minSize ?? defaultColumn?.minSize : column.columnDef.minSize,\n maxSize: raw ? raw.maxSize ?? defaultColumn?.maxSize : column.columnDef.maxSize\n };\n });\n\n return resolveColumnWidths(specs, columnSizing, availableWidth);\n },\n [columns, columnSizing, availableWidth, defaultColumn]\n );\n\n /* Stable identity while the numbers are unchanged — downstream memos depend on it. */\n const signature = JSON.stringify([resolved.total, Object.entries(resolved.byId)]);\n\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- `signature` fully encodes `resolved`\n return useMemo(() => resolved, [signature]);\n}\n","import type { FilterFn, RowData } from \"@tanstack/react-table\";\n\n/**\n * The canonical TanStack v9 feature set every ledger table runs on (docs/state.md). One static\n * object so `typeof ledgerFeatures` (`LedgerFeatures`) can pre-bind the `TFeatures` generic of\n * every re-exported type — consumers keep writing v8-shaped `ColumnDef<TData>` code.\n *\n * - Every stock feature is registered EXCEPT `columnResizingFeature`: ledger owns the resize\n * interaction end to end (`use-column-resize.ts`), so TanStack's drag machinery — and with it\n * the `columnResizing` state slice, `getIsResizing()`, and `getResizeHandler()` — is not\n * registered at all. Feature-gated APIs cannot lie about a pipeline that never runs.\n * - Row model factories are registered statically; the `manualX` translations decide at runtime\n * whether a model actually processes rows (client mode) or passes through (server mode).\n * - Every built-in fn ships registered under its conventional name. v9 resolves string ids —\n * `'auto'` included — only against registered functions, and ledger's contract is that every\n * TanStack capability on a raw `ColumnDef` keeps working; a few KB of fns is the price of\n * that promise.\n */\nimport {\n aggregationFn_count,\n aggregationFn_extent,\n aggregationFn_first,\n aggregationFn_last,\n aggregationFn_max,\n aggregationFn_mean,\n aggregationFn_median,\n aggregationFn_min,\n aggregationFn_sum,\n aggregationFn_unique,\n aggregationFn_uniqueCount,\n cellSpanningFeature,\n columnFacetingFeature,\n columnFilteringFeature,\n columnGroupingFeature,\n columnOrderingFeature,\n columnPinningFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createExpandedRowModel,\n createFacetedMinMaxValues,\n createFacetedRowModel,\n createFacetedUniqueValues,\n createFilteredRowModel,\n createGroupedRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n filterFn_arrHas,\n filterFn_arrIncludes,\n filterFn_arrIncludesAll,\n filterFn_arrIncludesSome,\n filterFn_between,\n filterFn_betweenInclusive,\n filterFn_empty,\n filterFn_endsWith,\n filterFn_equals,\n filterFn_equalsString,\n filterFn_equalsStringSensitive,\n filterFn_greaterThan,\n filterFn_greaterThanOrEqualTo,\n filterFn_includesString,\n filterFn_includesStringSensitive,\n filterFn_inDateRange,\n filterFn_inNumberRange,\n filterFn_lessThan,\n filterFn_lessThanOrEqualTo,\n filterFn_notEmpty,\n filterFn_startsWith,\n filterFn_weakEquals,\n globalFilteringFeature,\n rowAggregationFeature,\n rowExpandingFeature,\n rowPaginationFeature,\n rowPinningFeature,\n rowSelectionFeature,\n rowSortingFeature,\n sortFn_alphanumeric,\n sortFn_alphanumericCaseSensitive,\n sortFn_basic,\n sortFn_datetime,\n sortFn_text,\n sortFn_textCaseSensitive,\n tableFeatures,\n createColumnHelper as tanStackCreateColumnHelper\n} from \"@tanstack/react-table\";\n\nimport { ledgerFilterFns } from \"./filter-fns\";\n\nconst builtInFilterFns = {\n arrHas: filterFn_arrHas,\n arrIncludes: filterFn_arrIncludes,\n arrIncludesAll: filterFn_arrIncludesAll,\n arrIncludesSome: filterFn_arrIncludesSome,\n between: filterFn_between,\n betweenInclusive: filterFn_betweenInclusive,\n empty: filterFn_empty,\n endsWith: filterFn_endsWith,\n equals: filterFn_equals,\n equalsString: filterFn_equalsString,\n equalsStringSensitive: filterFn_equalsStringSensitive,\n greaterThan: filterFn_greaterThan,\n greaterThanOrEqualTo: filterFn_greaterThanOrEqualTo,\n inDateRange: filterFn_inDateRange,\n inNumberRange: filterFn_inNumberRange,\n includesString: filterFn_includesString,\n includesStringSensitive: filterFn_includesStringSensitive,\n lessThan: filterFn_lessThan,\n lessThanOrEqualTo: filterFn_lessThanOrEqualTo,\n notEmpty: filterFn_notEmpty,\n startsWith: filterFn_startsWith,\n weakEquals: filterFn_weakEquals\n};\n\nexport const ledgerFeatures = tableFeatures({\n cellSpanningFeature,\n columnFacetingFeature,\n columnFilteringFeature,\n columnGroupingFeature,\n columnOrderingFeature,\n columnPinningFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n globalFilteringFeature,\n rowAggregationFeature,\n rowExpandingFeature,\n rowPaginationFeature,\n rowPinningFeature,\n rowSelectionFeature,\n rowSortingFeature,\n expandedRowModel: createExpandedRowModel(),\n facetedMinMaxValues: createFacetedMinMaxValues(),\n facetedRowModel: createFacetedRowModel(),\n facetedUniqueValues: createFacetedUniqueValues(),\n filteredRowModel: createFilteredRowModel(),\n groupedRowModel: createGroupedRowModel(),\n paginatedRowModel: createPaginatedRowModel(),\n sortedRowModel: createSortedRowModel(),\n aggregationFns: {\n count: aggregationFn_count,\n extent: aggregationFn_extent,\n first: aggregationFn_first,\n last: aggregationFn_last,\n max: aggregationFn_max,\n mean: aggregationFn_mean,\n median: aggregationFn_median,\n min: aggregationFn_min,\n sum: aggregationFn_sum,\n unique: aggregationFn_unique,\n uniqueCount: aggregationFn_uniqueCount\n },\n filterFns: { ...builtInFilterFns, ...ledgerFilterFns },\n sortFns: {\n alphanumeric: sortFn_alphanumeric,\n alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n textCaseSensitive: sortFn_textCaseSensitive\n }\n});\n\nexport type LedgerFeatures = typeof ledgerFeatures;\n\n/**\n * TanStack's column helper, pre-bound to the canonical feature set — consumers keep the v8\n * calling shape (`createColumnHelper<Person>()`), never managing `TFeatures` themselves.\n */\nexport function createColumnHelper<TData extends RowData>() {\n return tanStackCreateColumnHelper<LedgerFeatures, TData>();\n}\n\n/**\n * The per-instance feature object: the canonical set, plus the consumer's `filterFns` registry\n * merged beneath ledger's reserved ids. Read once at mount (the `features` option wires code\n * modules, not reactive state).\n */\nexport function buildLedgerFeatures(\n consumerFilterFns: Record<string, FilterFn<any, any>> | undefined\n): LedgerFeatures {\n if (!consumerFilterFns) {\n return ledgerFeatures;\n }\n\n return {\n ...ledgerFeatures,\n filterFns: {\n ...builtInFilterFns,\n ...consumerFilterFns,\n ...ledgerFilterFns\n }\n };\n}\n","import type { DataTablePersistableSlice, DataTablePersistState } from \"./types\";\n\n/**\n * Opt-in state persistence (`persistState`). Hydration happens once, synchronously, so the first\n * render already shows the restored layout; writes are debounced and the latest pending value\n * flushes on real unmount. Storage content is a trust boundary — values are shape-checked before\n * use, and a stale or corrupt entry degrades to defaults instead of crashing the table.\n */\nimport { useEffect, useRef } from \"react\";\n\nimport { warnOnce } from \"./env\";\n\nconst STORAGE_PREFIX = \"ledger:\";\nconst WRITE_DEBOUNCE_MS = 250;\n\nconst DEFAULT_SLICES: readonly DataTablePersistableSlice[] = [\n \"columnSizing\",\n \"columnVisibility\",\n \"columnOrder\",\n \"columnPinning\"\n];\n\ntype PersistedState = Partial<Record<DataTablePersistableSlice, unknown>>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every(entry => typeof entry === \"string\");\n}\n\nfunction isRecordOf(value: unknown, guard: (entry: unknown) => boolean): boolean {\n return isRecord(value) && Object.values(value).every(entry => guard(entry));\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction isSafeInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value);\n}\n\nfunction isSortingState(value: unknown): boolean {\n if (!Array.isArray(value)) {\n return false;\n }\n\n return value.every(entry => isRecord(entry)\n && typeof entry.id === \"string\"\n && typeof entry.desc === \"boolean\");\n}\n\nfunction isColumnFiltersState(value: unknown): boolean {\n if (!Array.isArray(value)) {\n return false;\n }\n\n return value.every(entry => isRecord(entry)\n && typeof entry.id === \"string\"\n && Object.hasOwn(entry, \"value\"));\n}\n\nfunction isPaginationState(value: unknown): boolean {\n if (!isRecord(value)) {\n return false;\n }\n\n return isSafeInteger(value.pageIndex)\n && value.pageIndex >= 0\n && isSafeInteger(value.pageSize)\n && value.pageSize > 0;\n}\n\nfunction isColumnPinningState(value: unknown): boolean {\n if (!isRecord(value)) {\n return false;\n }\n\n return isStringArray(value.start) && isStringArray(value.end);\n}\n\n/**\n * Start wins an overlap, and each side holds a column once. A pinned id repeated within a side —\n * or claimed by both — would put the same column in the display order twice, which is a duplicate\n * `<col>`, a duplicate cell, and a duplicate React key. The reader is a trust boundary\n * (docs/state.md), so the shape is repaired rather than believed.\n */\nfunction normalizeColumnPinning(value: unknown): unknown {\n if (!isRecord(value) || !isStringArray(value.start) || !isStringArray(value.end)) {\n return value;\n }\n\n const start = new Set(value.start);\n\n return { end: [...new Set(value.end).difference(start)], start: [...start] };\n}\n\n/**\n * The slices whose *valid* shape still needs repairing. Deliberately not every slice: a guard says\n * whether the value can be used at all, and only pinning carries an invariant beyond its shape.\n */\nconst sliceNormalizers: Partial<Record<DataTablePersistableSlice, (value: unknown) => unknown>> = {\n columnPinning: normalizeColumnPinning\n};\n\n/**\n * Per-slice shape guards — storage may hold data written by an older app version.\n */\nconst sliceGuards: Record<DataTablePersistableSlice, (value: unknown) => boolean> = {\n sorting: isSortingState,\n columnFilters: isColumnFiltersState,\n globalFilter: value => typeof value === \"string\",\n pagination: isPaginationState,\n columnVisibility: value => isRecordOf(value, entry => typeof entry === \"boolean\"),\n columnPinning: isColumnPinningState,\n columnOrder: isStringArray,\n columnSizing: value => isRecordOf(value, entry => isFiniteNumber(entry) && entry >= 0),\n grouping: isStringArray\n};\n\nfunction resolveStorage(persist: DataTablePersistState): DataTablePersistState[\"storage\"] {\n if (persist.storage) {\n return persist.storage;\n }\n\n try {\n return typeof localStorage === \"undefined\" ? undefined : localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport function readPersistedState(persist: DataTablePersistState | undefined): PersistedState {\n if (!persist) {\n return {};\n }\n\n try {\n const raw = resolveStorage(persist)?.getItem(STORAGE_PREFIX + persist.key);\n\n if (!raw) {\n return {};\n }\n\n const parsed: unknown = JSON.parse(raw);\n\n if (!isRecord(parsed)) {\n return {};\n }\n\n const slices = persist.slices ?? DEFAULT_SLICES;\n const result: PersistedState = {};\n\n for (const slice of slices) {\n const value = parsed[slice];\n\n if (value !== undefined && sliceGuards[slice](value)) {\n result[slice] = sliceNormalizers[slice]?.(value) ?? value;\n }\n }\n\n return result;\n } catch {\n return {};\n }\n}\n\nfunction serializeSlices(\n slices: readonly DataTablePersistableSlice[],\n state: Record<DataTablePersistableSlice, unknown>\n): string | null {\n try {\n return JSON.stringify(Object.fromEntries(slices.map(slice => [slice, state[slice]])));\n } catch {\n warnOnce(\n \"persist-unserializable\",\n \"persistState skipped a write — a persisted slice holds a value JSON cannot represent (a BigInt, a circular reference, or a throwing toJSON).\"\n );\n\n return null;\n }\n}\n\nexport function usePersistWriter(\n persist: DataTablePersistState | undefined,\n state: Record<DataTablePersistableSlice, unknown>\n): void {\n const slices = persist?.slices ?? DEFAULT_SLICES;\n // Serialized in the render that produced the state, but never *throwing* in it: a filter value\n // may be a BigInt, may refer to itself, or may own a `toJSON` that throws, and any of those\n // would take the whole table down on a keystroke. `null` means \"this state cannot be written\",\n // which cancels the pending write rather than leaving the previous payload to stand in for it.\n const serialized = persist ? serializeSlices(slices, state) : \"\";\n const key = persist?.key;\n const storage = persist?.storage;\n const pendingWriteRef = useRef<(() => void) | null>(null);\n const unmountFlushTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!persist || !key || serialized === null) {\n pendingWriteRef.current = null;\n\n return;\n }\n\n const write = () => {\n if (pendingWriteRef.current !== write) {\n return;\n }\n\n try {\n resolveStorage(persist)?.setItem(STORAGE_PREFIX + key, serialized);\n } catch {\n // Quota/privacy-mode failures degrade to \"not persisted\", never to a crash.\n } finally {\n pendingWriteRef.current = null;\n }\n };\n\n pendingWriteRef.current = write;\n const timer = setTimeout(write, WRITE_DEBOUNCE_MS);\n\n return () => clearTimeout(timer);\n // The `storage` dependency re-targets a pending write when the backend swaps under the\n // same key (e.g. a consent flow upgrading in-memory storage to localStorage).\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- `persist` participates via `key`/`serialized`/`storage`; its object identity is irrelevant\n }, [key, serialized, storage]);\n\n useEffect(() => {\n if (unmountFlushTimer.current !== null) {\n clearTimeout(unmountFlushTimer.current);\n unmountFlushTimer.current = null;\n }\n\n return () => {\n // Defer one tick so React StrictMode's simulated unmount/remount can cancel the flush.\n unmountFlushTimer.current = setTimeout(() => {\n unmountFlushTimer.current = null;\n pendingWriteRef.current?.();\n }, 0);\n };\n }, []);\n}\n","import type { ExpandedState, RowSelectionState, SortDirection, SortingState } from \"@tanstack/react-table\";\n\nimport type { Row } from \"./types\";\n\n/**\n * The state a sort, a selection or an expansion toggle produces — TanStack v9's own updater\n * bodies, transcribed as pure functions.\n *\n * v9 computes half of each toggle *outside* the updater it hands the state setter: the next sort\n * direction, whether the row may be selected at all, whether it is currently expanded, the\n * display order a Shift range walks. Those reads go to the shared core, which carries whatever\n * render pass ran last — a pass React discarded included — while the updater's own `old` is\n * correctly the committed value. So the halves disagree, and six measured defects follow\n * (docs/architecture.md).\n *\n * The fix is the shape the resize handle already uses: what a toggle decides with is resolved by\n * the render that drew the control, and the write itself is this module plus the stable slice\n * setter. Nothing here reads `row.table` — only structural row properties (`id`, `subRows`,\n * `parentId`) and the rules its caller resolved.\n *\n * Kept verbatim on purpose, `Object.create(null)` maps included: row ids are opaque application\n * strings, and a plain object literal would let `__proto__` or `constructor` silently fail to\n * become an own key.\n */\n\nfunction emptyMap<T extends object>(): T {\n return Object.create(null) as T;\n}\n\nfunction hasOwnId(map: Record<string, boolean>, rowId: string): boolean {\n return map[rowId] === true;\n}\n\n// ------------------------------------------------------------------------------------------------\n// Sorting\n// ------------------------------------------------------------------------------------------------\n\n/**\n * Everything a sort click decides with, resolved by the render that drew the header.\n */\nexport interface SortToggleSpec {\n columnId: string;\n /**\n * `column.getCanMultiSort()` — whether this column may join an existing multi-sort.\n */\n canMultiSort: boolean;\n /**\n * `column.getNextSortingOrder(false)` and `column.getNextSortingOrder(true)`. Both are needed\n * because the cycle's removal step depends on `enableMultiRemove`, and whether the event is a\n * multi-sort event is only known when it arrives.\n */\n nextOrderSingle: SortDirection | false;\n nextOrderMulti: SortDirection | false;\n /**\n * `options.maxMultiSortColCount`, already defaulted.\n */\n maxMultiSortColCount: number;\n}\n\nexport function nextSorting(old: SortingState, spec: SortToggleSpec, multi: boolean): SortingState {\n const {\n columnId,\n canMultiSort,\n maxMultiSortColCount\n } = spec;\n const nextSortingOrder = multi && canMultiSort ? spec.nextOrderMulti : spec.nextOrderSingle;\n const existingIndex = old.findIndex(entry => entry.id === columnId);\n const existingSorting = existingIndex === -1 ? undefined : old[existingIndex];\n const nextDesc = nextSortingOrder === \"desc\";\n const isMultiMode = Boolean(old.length > 0 && canMultiSort && multi);\n\n let sortAction: \"add\" | \"remove\" | \"replace\" | \"toggle\";\n\n if (isMultiMode) {\n sortAction = existingSorting ? \"toggle\" : \"add\";\n } else {\n sortAction = existingSorting ? \"toggle\" : \"replace\";\n }\n\n if (sortAction === \"toggle\" && !nextSortingOrder) {\n sortAction = \"remove\";\n }\n\n if (sortAction === \"add\") {\n const newSorting = [...old, { desc: nextDesc, id: columnId }];\n newSorting.splice(0, newSorting.length - maxMultiSortColCount);\n\n return newSorting;\n }\n\n if (sortAction === \"toggle\") {\n return isMultiMode\n ? old.map(entry => entry.id === columnId ? { ...entry, desc: nextDesc } : entry)\n : [{ desc: nextDesc, id: columnId }];\n }\n\n if (sortAction === \"remove\") {\n return isMultiMode ? old.filter(entry => entry.id !== columnId) : [];\n }\n\n return [{ desc: nextDesc, id: columnId }];\n}\n\n// ------------------------------------------------------------------------------------------------\n// Selection\n// ------------------------------------------------------------------------------------------------\n\n/**\n * The three row predicates selection asks, resolved against the committed options rather than\n * against `row.table`. Each mirrors its v9 counterpart, `boolean | (row) => boolean` included.\n */\nexport interface SelectionRules {\n canSelect: (row: Row<any>) => boolean;\n canMultiSelect: (row: Row<any>) => boolean;\n canSelectSubRows: (row: Row<any>) => boolean;\n}\n\nexport function mutateRowIsSelected(\n selection: RowSelectionState,\n row: Row<any>,\n value: boolean,\n rules: SelectionRules,\n /**\n * Whether the write cascades into `subRows`. Not a constant: an ordinary row toggle cascades\n * only when the row accepts company, because a single-select row clears the map before it\n * writes itself — so cascading there would leave the last descendant selected instead of the\n * row that was clicked. A range and a select-all always cascade; only their deselect half\n * differs, and that is `respectCanSelectOnDeselect`.\n */\n options: { includeChildren: boolean; respectCanSelectOnDeselect?: boolean }\n): void {\n if (value) {\n if (!rules.canMultiSelect(row)) {\n for (const key of Object.keys(selection)) {\n delete selection[key];\n }\n }\n\n if (rules.canSelect(row)) {\n selection[row.id] = true;\n }\n } else if (!options.respectCanSelectOnDeselect || rules.canSelect(row)) {\n delete selection[row.id];\n }\n\n if (options.includeChildren && row.subRows.length > 0 && rules.canSelectSubRows(row)) {\n for (const subRow of row.subRows) {\n mutateRowIsSelected(selection, subRow as Row<any>, value, rules, options);\n }\n }\n}\n\nexport function nextRowSelection(\n old: RowSelectionState,\n row: Row<any>,\n value: boolean,\n rules: SelectionRules\n): RowSelectionState {\n const selection = Object.assign(emptyMap<RowSelectionState>(), old);\n mutateRowIsSelected(selection, row, value, rules, { includeChildren: rules.canMultiSelect(row) });\n\n return selection;\n}\n\n/**\n * The inclusive interval between two display-order positions. Non-selectable and\n * non-multi-selectable rows inside it are skipped, exactly as v9 skips them.\n */\nexport function nextRangeSelection(\n old: RowSelectionState,\n rows: Array<Row<any>>,\n range: { anchorIndex: number; rowIndex: number; value: boolean },\n rules: SelectionRules\n): RowSelectionState {\n const {\n anchorIndex,\n rowIndex,\n value\n } = range;\n const selection = Object.assign(emptyMap<RowSelectionState>(), old);\n const start = Math.min(anchorIndex, rowIndex);\n const end = Math.max(anchorIndex, rowIndex);\n\n for (let index = start; index <= end; index += 1) {\n const rangeRow = rows[index];\n\n if (rangeRow && rules.canSelect(rangeRow) && rules.canMultiSelect(rangeRow)) {\n mutateRowIsSelected(selection, rangeRow, value, rules, { includeChildren: true });\n }\n }\n\n return selection;\n}\n\nexport function nextPageSelection(\n old: RowSelectionState,\n pageRows: Array<Row<any>>,\n value: boolean,\n rules: SelectionRules\n): RowSelectionState {\n const selection = Object.assign(emptyMap<RowSelectionState>(), old);\n\n for (const row of pageRows) {\n mutateRowIsSelected(selection, row, value, rules, { includeChildren: true, respectCanSelectOnDeselect: true });\n }\n\n return selection;\n}\n\n/**\n * Select-all over every row, not just the page. Descent is blocked by any ancestor whose\n * `enableSubRowSelection` says so, which is why the ancestor verdict is walked and cached per\n * pass the way v9 walks it.\n */\nexport function nextAllSelection(\n old: RowSelectionState,\n flatRows: Array<Row<any>>,\n rowsById: Record<string, Row<any>>,\n value: boolean,\n rules: SelectionRules\n): RowSelectionState {\n const selection = Object.assign(emptyMap<RowSelectionState>(), old);\n\n if (!value) {\n for (const row of flatRows) {\n if (rules.canSelect(row)) {\n delete selection[row.id];\n }\n }\n\n return selection;\n }\n\n const cache = new Map<string, boolean>();\n\n const reachable = (row: Row<any>): boolean => {\n if (!rules.canSelect(row)) {\n return false;\n }\n\n const visited: string[] = [];\n let selectable = true;\n let currentId = row.parentId;\n\n while (currentId !== undefined) {\n const known = cache.get(currentId);\n\n if (known !== undefined) {\n selectable = known;\n\n break;\n }\n\n visited.push(currentId);\n\n const parent = rowsById[currentId];\n\n if (!parent || !rules.canSelectSubRows(parent)) {\n selectable = false;\n\n break;\n }\n\n currentId = parent.parentId;\n }\n\n for (const id of visited) {\n cache.set(id, selectable);\n }\n\n return selectable;\n };\n\n for (const row of flatRows) {\n if (reachable(row)) {\n selection[row.id] = true;\n }\n }\n\n return selection;\n}\n\n// ------------------------------------------------------------------------------------------------\n// Expansion\n// ------------------------------------------------------------------------------------------------\n\n/**\n * `expanded` is `true` (everything) or a map. Expanding out of `true` has to materialize the map\n * first, which is why the expandable row ids are part of the call.\n */\nexport function nextExpanded(\n old: ExpandedState,\n rowId: string,\n targetExpanded: boolean,\n expandableRowIds: () => string[]\n): ExpandedState {\n const exists = old === true ? true : hasOwnId(old, rowId);\n let oldExpanded: Record<string, boolean>;\n\n if (old === true) {\n oldExpanded = emptyMap<Record<string, boolean>>();\n\n for (const id of expandableRowIds()) {\n oldExpanded[id] = true;\n }\n } else {\n oldExpanded = Object.assign(emptyMap<Record<string, boolean>>(), old);\n }\n\n if (!exists && targetExpanded) {\n oldExpanded[rowId] = true;\n\n return oldExpanded;\n }\n\n if (exists && !targetExpanded) {\n const rest = emptyMap<Record<string, boolean>>();\n\n for (const [id, value] of Object.entries(oldExpanded)) {\n if (id !== rowId && value) {\n rest[id] = true;\n }\n }\n\n return rest;\n }\n\n return old;\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type {\n DataTableEditCommit,\n DataTableEditingCell,\n LedgerCellEditor\n} from \"./types\";\nimport type { CommittedTable } from \"./use-committed-table\";\n\n/**\n * The cell-mode editing session (docs/architecture.md — \"Editing sessions live in the controller,\n * not in the editors\"). Everything an editor for one cell shows, and everything the commit needs\n * to decide with, lives here: an editor is unmounted by a hidden column or a virtual scroll at any\n * moment, and a session is not. A mounted editor is a view of this plus a keyboard surface.\n */\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\n\nimport { editErrorMessage, normalizeEdit } from \"./edit-meta\";\nimport { isPromiseLike, useEventCallback } from \"./utils\";\n\nexport interface UseCellEditingInput<TData extends RowData> {\n editingCell: DataTableEditingCell | null;\n setEditingCell: (cell: DataTableEditingCell | null) => void;\n /**\n * Rows, definitions and the gate as the render that reached the screen left them. Everything a\n * commit decides with comes from here rather than from the cell's own table, which is the shared\n * core and carries whatever pass ran last (see `use-committed-table.ts`).\n */\n committed: CommittedTable;\n onEditCommit: ((change: DataTableEditCommit<TData>) => void | Promise<void>) | undefined;\n}\n\nexport interface CellEditingSession {\n active: (rowId: string, columnId: string) => boolean;\n start: (cell: DataTableEditingCell) => void;\n stop: (options?: { commit?: boolean }) => void;\n clear: () => void;\n commit: () => boolean | Promise<boolean>;\n cancel: () => void;\n read: (rowId: string, columnId: string, source: unknown) => unknown;\n /**\n * Commits and moves to the row's next (or previous) editable cell — the row as the screen has\n * it. Answered here rather than by the editor, which would have to walk the shared core.\n */\n moveTo: (backwards: boolean) => void;\n firstEditable: (rowId: string, skipCheckbox: boolean) => string | null;\n write: (rowId: string, columnId: string, value: unknown) => void;\n pending: (rowId: string, columnId: string) => boolean;\n error: (rowId: string, columnId: string) => string | null;\n register: (rowId: string, columnId: string, editor: LedgerCellEditor) => () => void;\n}\n\ninterface CellStore {\n rowId: string | null;\n columnId: string | null;\n /**\n * The pending value; null while the session holds nothing the application has not seen.\n */\n draft: { value: unknown } | null;\n /**\n * What this session wrote, against what the data read when it went out. While it stands it is\n * what the cell holds; the effect below retires it for good once the data moves past it.\n */\n written: { value: unknown; source: unknown } | null;\n error: string | null;\n /**\n * The session has sent, or discarded, what it holds. A new value reopens it.\n */\n settled: boolean;\n /**\n * Eligibility was lost during this session. It latches: a gate that reopens before an in-flight\n * write settles is the *next* session's eligibility, not a reprieve for this one.\n */\n gateLost: boolean;\n /**\n * The automatic reconciliation has already answered this session's gate closing.\n */\n reconciled: boolean;\n /**\n * The write currently out, and whether the data has moved since it left. A record is only true\n * while the data has not moved past it, and the moving can happen *during* the request —\n * including out and back again, which comparing at settle time could never see.\n */\n writing: { source: unknown; moved: boolean } | null;\n}\n\nfunction closedStore(): CellStore {\n return {\n columnId: null,\n draft: null,\n error: null,\n gateLost: false,\n reconciled: false,\n rowId: null,\n settled: false,\n writing: null,\n written: null\n };\n}\n\nexport function useCellEditing<TData extends RowData>({\n editingCell,\n setEditingCell,\n committed,\n onEditCommit\n}: UseCellEditingInput<TData>): CellEditingSession {\n const store = useRef<CellStore>(closedStore());\n /**\n * Bumped whenever a session starts or ends without the slice moving — a gate shutting under a\n * controlled application that declines to close it, or an explicit start on the cell already\n * named. Whether an editor may be on screen is part of the render output, so a change in it has\n * to be a change in state; a ref would leave the last render standing.\n */\n const [epoch, setEpoch] = useState(0);\n /**\n * One session, one token: a settled request may only act on the session that issued it.\n */\n const sessionRef = useRef(0);\n const pendingCommit = useRef<{ promise: Promise<boolean>; session: number } | null>(null);\n const pendingRef = useRef(false);\n /**\n * The editors on screen, each with the cell it belongs to — see `register`.\n */\n const editors = useRef(new Map<LedgerCellEditor, DataTableEditingCell>());\n /**\n * Only the latest navigation request may win after an async commit settles.\n */\n const requestRef = useRef(0);\n /**\n * The cell that actually reached the screen — see the layout effect.\n */\n const renderedRef = useRef(editingCell);\n /**\n * The armed unmount commit, with the session and cell whose departure armed it.\n */\n const unmountCommit = useRef<{\n session: number;\n target: DataTableEditingCell;\n timer: ReturnType<typeof setTimeout> | null;\n } | null>(null);\n\n const disarmUnmountCommit = () => {\n const armed = unmountCommit.current;\n\n if (armed === null) {\n return;\n }\n\n unmountCommit.current = null;\n\n if (armed.timer !== null) {\n clearTimeout(armed.timer);\n }\n };\n\n const redraw = useCallback(() => {\n for (const editor of editors.current.keys()) {\n editor.redraw();\n }\n }, []);\n\n /**\n * How many editors for `target` are on screen right now.\n */\n const mountedFor = (target: DataTableEditingCell): number => {\n let count = 0;\n\n for (const owner of editors.current.values()) {\n if (owner.rowId === target.rowId && owner.columnId === target.columnId) {\n count += 1;\n }\n }\n\n return count;\n };\n\n const isSession = (rowId: string, columnId: string) => store.current.rowId === rowId && store.current.columnId === columnId;\n const isSessionRef = useRef(isSession);\n\n /**\n * What the cell holds as far as the application is concerned: the value this session wrote while\n * the data has not moved past it, otherwise the data itself.\n */\n const settledValue = (source: unknown): unknown => {\n const record = store.current.written;\n\n return record && Object.is(record.source, source) ? record.value : source;\n };\n\n const settledValueRef = useRef(settledValue);\n\n /**\n * Whether the cell may still be edited right now — the gate, re-read against the commit.\n */\n const stillEditable = (rowId: string, columnId: string): boolean => committed.canEdit(rowId, columnId);\n\n /**\n * Asks for the session to close. Deliberately not a navigation request: a commit closing the\n * cell it just wrote is the very thing a `start` waiting on that commit is waiting *for*, and\n * cancelling the move it is about to make would strand it. Only explicit navigation — another\n * `start`, or a `stop` — invalidates a pending one.\n */\n const requestClose = useEventCallback(() => setEditingCell(null));\n\n /**\n * Ends whatever session the store holds and opens the one for `target`, or none. Every session\n * boundary goes through here — the render one below, and the in-place restart in `start` — so\n * that a session ends whole: a boundary that disowned only some of what the last one held would\n * leave the rest of it speaking for its successor. A departure that has not fired yet belongs\n * to the session ending here, and a write still out belongs to nobody: its settlement finds a\n * token that no longer matches and touches nothing, so the flag it would have cleared has to be\n * cleared now or the next session opens permanently pending.\n */\n const beginSession = (target: DataTableEditingCell | null) => {\n disarmUnmountCommit();\n sessionRef.current += 1;\n pendingCommit.current = null;\n pendingRef.current = false;\n store.current = target === null\n ? closedStore()\n : {\n ...closedStore(),\n columnId: target.columnId,\n rowId: target.rowId\n };\n };\n\n /**\n * Reconciles the session with the cell that actually reached the screen. Committed in a layout\n * effect, never during render: React may throw a tree away, and a session opened for a cell\n * nobody saw would take the commits meant for the one on screen.\n */\n useLayoutEffect(() => {\n renderedRef.current = editingCell;\n\n const owner = store.current;\n const moved = owner.rowId !== (editingCell?.rowId ?? null) || owner.columnId !== (editingCell?.columnId ?? null);\n\n // Judged against what the store holds, not against a mirror of the prop: a table that renders\n // with `editingCell` already set has a session to open on its very first pass, and comparing\n // mirrors would call that \"unmoved\" and never key the store at all.\n if (!moved) {\n return;\n }\n\n beginSession(editingCell);\n });\n\n const setError = (message: string | null) => {\n store.current.error = message;\n redraw();\n };\n\n const setPending = (pending: boolean) => {\n pendingRef.current = pending;\n redraw();\n };\n\n /**\n * Ends the session as a cancellation: what it held is discarded, and the close is requested.\n */\n const markGateLost = () => {\n if (store.current.gateLost) {\n return;\n }\n\n store.current.gateLost = true;\n setEpoch(token => token + 1);\n };\n\n /**\n * Ends a session whose eligibility is gone. Idempotent per session, which is what makes the\n * automatic path safe to reach from the effect, from a settling write, and from an editor\n * leaving the screen because the gate took it away — an application that ignores the close\n * would otherwise be asked once for each. A command is never this: an Escape, a `stopEditing`,\n * or a `startEditing` that has to leave this cell first is always a fresh request, because an\n * owner that declined the last one still has the cell on screen. Reported back, so that a\n * command finding the session already reconciled can ask again itself.\n */\n const closeLostSession = (): boolean => {\n if (store.current.reconciled) {\n return false;\n }\n\n store.current.reconciled = true;\n store.current.draft = null;\n store.current.error = null;\n store.current.settled = true;\n redraw();\n requestClose();\n\n return true;\n };\n\n const cancel = useEventCallback(() => {\n if (pendingRef.current) {\n return;\n }\n\n store.current.draft = null;\n store.current.error = null;\n store.current.settled = true;\n redraw();\n requestClose();\n });\n\n const commit = useEventCallback((): boolean | Promise<boolean> => {\n const { rowId, columnId } = store.current;\n\n if (rowId === null || columnId === null) {\n return true;\n }\n\n const inFlight = pendingCommit.current;\n\n if (inFlight && inFlight.session === sessionRef.current) {\n return inFlight.promise;\n }\n\n if (store.current.settled) {\n if (store.current.gateLost) {\n // This session was cancelled, not finished, so nothing waiting to move may proceed on\n // the strength of it. Reconciliation has already discarded what it held and asked once\n // for the close; this is a command, so it asks again.\n requestClose();\n\n return false;\n }\n\n // Nothing new to send. Still a request to leave, though: an application that ignored the\n // first one keeps this session open, and asking again is how it is closed.\n requestClose();\n\n return true;\n }\n\n const row = committed.row(rowId);\n\n if (!row) {\n // The row is not in the table — a target that has not arrived, or one the data no longer\n // holds. Nothing about that is a gate closing, so the session is not cancelled and nothing\n // it holds is discarded; but there is nothing to write either, and an explicit stop still\n // has to be able to close a session waiting on a row that never came.\n store.current.settled = true;\n requestClose();\n\n return true;\n }\n\n // Eligibility is re-read here, not trusted from when the session opened: `enableEditing` can\n // switch off, `meta.edit` can be removed, and `edit.enabled(row)` can turn false meanwhile.\n // Committing then would push a value through a gate the application has just shut — and\n // unvalidated, since a closed gate is exactly what `validate` no longer guards. The session\n // is cancelled, which is not the same as finished: nothing waiting to move may do so on it.\n if (!committed.canEdit(rowId, columnId)) {\n markGateLost();\n\n if (!closeLostSession()) {\n requestClose();\n }\n\n return false;\n }\n\n const source = committed.value(rowId, columnId);\n const previousValue = settledValue(source);\n const value = store.current.draft ? store.current.draft.value : previousValue;\n\n if (Object.is(value, previousValue)) {\n store.current.settled = true;\n requestClose();\n\n return true;\n }\n\n const normalized = normalizeEdit(committed.edit(columnId));\n\n try {\n if (normalized?.validate) {\n const validationError = normalized.validate(value, row);\n\n if (validationError !== null) {\n setError(validationError);\n\n return false;\n }\n }\n } catch (error) {\n setError(editErrorMessage(error));\n\n return false;\n }\n\n let result: void | Promise<void>;\n\n try {\n result = onEditCommit?.({\n column: committed.column(columnId),\n previousValue,\n row,\n value\n } as DataTableEditCommit<TData>);\n } catch (error) {\n setError(editErrorMessage(error));\n\n return false;\n }\n\n if (!isPromiseLike(result)) {\n store.current.written = { source, value };\n store.current.draft = null;\n store.current.settled = true;\n requestClose();\n\n return true;\n }\n\n const session = sessionRef.current;\n store.current.writing = { moved: false, source };\n setPending(true);\n\n // The in-flight slot is released inside the handlers rather than in a `finally`: the\n // not-carried branch below commits again, and a settled request must not still be standing\n // there for its own successor to join.\n const promise: Promise<boolean> = Promise.resolve(result).then(\n () => {\n if (session !== sessionRef.current) {\n return false;\n }\n\n pendingCommit.current = null;\n // A custom editor is not disabled while the request is out, so the user can type straight\n // past it. What this write carried is what the next edit departs from; a value typed since\n // is one it never carried.\n const carried = !store.current.draft || Object.is(store.current.draft.value, value);\n // Unless the data moved while the request was out — then what the application holds is\n // its own, and this write has nothing left to be true about.\n store.current.written = store.current.writing?.moved === true ? null : { source, value };\n store.current.writing = null;\n store.current.settled = carried;\n\n if (carried) {\n store.current.draft = null;\n }\n\n setPending(false);\n\n // The gate may have shut while this write was out — and a gate that reopened before it\n // landed does not undo that. The write stands, but the session it belonged to is over, so\n // nothing waiting to move may do so on the strength of it.\n if (store.current.gateLost || !stillEditable(rowId, columnId)) {\n markGateLost();\n closeLostSession();\n\n return false;\n }\n\n if (!carried) {\n // Still on screen: the cell does not close, and whoever was waiting to leave it is told\n // it is not safe to. Gone from the screen: nobody can commit it by hand any more, and an\n // unmount commits rather than discards (docs/editing.md), so this write — which did\n // succeed — is followed by the one it outran. That successor carries the latest value,\n // so it settles `carried` and recurses no further.\n return mountedFor({ columnId, rowId }) > 0 ? false : commit();\n }\n\n requestClose();\n\n return true;\n },\n (error: unknown) => {\n if (session !== sessionRef.current) {\n return false;\n }\n\n pendingCommit.current = null;\n store.current.writing = null;\n setPending(false);\n setError(editErrorMessage(error));\n\n // A gate that shut while the request was out is answered now that it has landed.\n if (store.current.gateLost || !stillEditable(rowId, columnId)) {\n markGateLost();\n closeLostSession();\n }\n\n return false;\n }\n );\n\n pendingCommit.current = { promise, session };\n\n return promise;\n });\n\n /**\n * Losing eligibility mid-session cancels it, and the loss latches: reopening the gate is the\n * next session's eligibility. Automatic reconciliation is idempotent per session — an explicit\n * Escape or `stopEditing` is always a fresh request, because an application that ignored the\n * last one has to be asked again. It also retires the write record once the data moves past it,\n * permanently, so data returning to what the write departed from cannot resurrect it.\n */\n useEffect(() => {\n const { rowId, columnId } = store.current;\n\n if (rowId === null || columnId === null) {\n return;\n }\n\n // The table-level gate is answered first, and without a row: a session whose row has not\n // arrived still loses its gate when editing is switched off or the mode's commit handler is\n // taken away, and must not be found waiting when either comes back.\n if (committed.tableGate()) {\n if (committed.row(rowId) === null) {\n // The row is not in the table: a target that has not arrived, or one the data no longer\n // holds. Neither is an application closing a gate, so the session waits for it.\n return;\n }\n\n const source = committed.value(rowId, columnId);\n const record = store.current.written;\n\n if (record && !Object.is(record.source, source)) {\n store.current.written = null;\n redraw();\n }\n\n // The same watch, for the write still out: it has no record to retire yet, so the movement\n // has to be remembered until it does.\n if (store.current.writing && !Object.is(store.current.writing.source, source)) {\n store.current.writing.moved = true;\n }\n\n if (committed.canEdit(rowId, columnId)) {\n return;\n }\n }\n\n markGateLost();\n\n // The in-flight write passed the gate before it shut; its settlement completes the cancel.\n if (pendingRef.current) {\n return;\n }\n\n closeLostSession();\n });\n\n const clear = useEventCallback(() => {\n if (renderedRef.current !== null) {\n requestClose();\n }\n });\n\n const stop = useEventCallback((options?: { commit?: boolean }) => {\n // An explicit stop overrules a move still waiting on a commit.\n requestRef.current += 1;\n\n if (options?.commit ?? true) {\n void Promise.resolve(commit()).catch(() => false);\n } else {\n cancel();\n }\n });\n\n const start = useEventCallback((target: DataTableEditingCell) => {\n const request = ++requestRef.current;\n const rendered = renderedRef.current;\n\n if (!rendered || (rendered.rowId === target.rowId && rendered.columnId === target.columnId)) {\n if (isSession(target.rowId, target.columnId) && store.current.gateLost) {\n // The session on this cell is over — its gate shut, and a controlled application declined\n // to close it. An explicit start is not that session coming back: it is the next one, so\n // it gets a new token and nothing the old one held. The slice already names this cell, so\n // no render would arrive to do it for us.\n beginSession(target);\n setEpoch(token => token + 1);\n }\n\n setEditingCell(target);\n\n return;\n }\n\n // Not named `committed`: that is the snapshot reader this whole module decides with, and a\n // local shadowing it inside the one function that also commits is a trap for the next reader.\n const outcome = commit();\n\n if (typeof outcome === \"boolean\") {\n if (outcome && requestRef.current === request) {\n setEditingCell(target);\n }\n\n return;\n }\n\n void Promise.resolve(outcome).then(\n success => {\n if (success && requestRef.current === request) {\n setEditingCell(target);\n }\n },\n // Custom editors may still reject despite the boolean-result contract; stay put.\n () => false\n );\n });\n\n /**\n * An editor registers while it is on screen. Its departure arms the unmount commit, deferred one\n * tick so a remount of the same cell — StrictMode's simulated unmount, or the virtualizer\n * re-mounting a row still in view — cancels it; only a real departure commits, and once nothing\n * is mounted any failure degrades to discard because there is nowhere left to report it.\n *\n * Everything here is decided per target: an editor for one cell must not cancel another cell's\n * departure, and the write that departure sends must not clear a cell that has since come back\n * on screen with something new in it.\n */\n const register = useCallback((rowId: string, columnId: string, editor: LedgerCellEditor) => {\n const target = { columnId, rowId };\n const armed = unmountCommit.current;\n\n if (armed && armed.session === sessionRef.current && armed.target.rowId === rowId && armed.target.columnId === columnId) {\n disarmUnmountCommit();\n }\n\n editors.current.set(editor, target);\n\n return () => {\n editors.current.delete(editor);\n\n if (mountedFor(target) > 0) {\n return;\n }\n\n // An editor the gate took off the screen did not depart — the session it belonged to ended,\n // and it has nothing left to commit on the way out.\n if (store.current.gateLost) {\n return;\n }\n\n const rendered = renderedRef.current;\n\n if (rendered?.rowId !== rowId || rendered.columnId !== columnId) {\n return;\n }\n\n // The record identifies itself, so a tick that fires late can only retire its own: two\n // departures in one tick would otherwise have the first one clear the second's record and\n // leave a live timer nothing can cancel.\n const record: { session: number; target: DataTableEditingCell; timer: ReturnType<typeof setTimeout> | null } = {\n session: sessionRef.current,\n target,\n timer: null\n };\n const { session } = record;\n\n record.timer = setTimeout(() => {\n if (unmountCommit.current === record) {\n unmountCommit.current = null;\n }\n\n // The tick waited, and the session may have moved on: a switch commits the cell being\n // left and opens the next one in the same render, so this departure can find a different\n // cell in its place. Read the owner *before* reaching for a commit, which always speaks\n // for whatever session is current — otherwise this closes the cell that replaced it.\n if (session !== sessionRef.current || store.current.rowId !== rowId || store.current.columnId !== columnId) {\n return;\n }\n\n // A session the gate cancelled has nothing left to commit on the way out, and its close\n // has been asked for: this editor did not depart, it was taken off the screen. The\n // cleanup that armed this tick tests the same thing, but it runs at layout time — before\n // the reconciliation that latches the loss.\n if (store.current.gateLost) {\n return;\n }\n\n const settle = () => {\n // Only if this is still the session that departed, and nothing has taken the cell back\n // on screen meanwhile — a remounted editor may be holding a value this write never saw,\n // and a failure it can show.\n if (session !== sessionRef.current || mountedFor(target) > 0) {\n return;\n }\n\n // Nothing is mounted, so a failure — a `validate` rejection, a throw, a rejected\n // promise — has nowhere left to report itself and degrades to discard\n // (docs/editing.md). Discarded rather than merely closed: an application that declines\n // the close would otherwise see the draft and the message come back with the column.\n store.current.draft = null;\n store.current.error = null;\n store.current.settled = true;\n clear();\n };\n\n const result = commit();\n\n if (isPromiseLike(result)) {\n void Promise.resolve(result).then(settle, settle);\n } else {\n settle();\n }\n }, 0);\n\n unmountCommit.current = record;\n };\n }, [commit, clear]);\n\n // Stable identities all the way out: this surface goes into `meta.ledger`, which the render\n // layer memoizes against — a fresh object or a fresh arrow here would re-render every cell in\n // the table on every render. Each of these reads nothing but refs.\n // `source` comes from the caller — the cell of the render doing the drawing, which is the right\n // one for a render and cannot be a discarded pass's: an editor redraws only after it has\n // rendered, and that render is what resolved the value it is holding.\n const read = useCallback((rowId: string, columnId: string, source: unknown) => {\n if (!isSessionRef.current(rowId, columnId)) {\n return source;\n }\n\n return store.current.draft ? store.current.draft.value : settledValueRef.current(source);\n }, []);\n\n const write = useCallback((rowId: string, columnId: string, value: unknown) => {\n if (!isSessionRef.current(rowId, columnId)) {\n return;\n }\n\n store.current.draft = { value };\n store.current.error = null;\n // A new value is a new edit: the session is only still open past a settled commit because the\n // application declined to close it, and what it holds now no write has carried.\n store.current.settled = false;\n redraw();\n }, [redraw]);\n\n const pending = useCallback((rowId: string, columnId: string) => isSessionRef.current(rowId, columnId) && pendingRef.current, []);\n\n const active = useCallback(\n // Asked during render, so a cell the store has not been keyed to yet is a session about to\n // open, which is live by definition; only the one being tracked can have lost its gate. Keyed\n // to the epoch: the answer lives in a ref, so this identity changing is what carries a\n // session starting or ending into the render layer's memo.\n (rowId: string, columnId: string) => isSessionRef.current(rowId, columnId) ? !store.current.gateLost : true,\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- the epoch is the point: see above\n [epoch]\n );\n const error = useCallback((rowId: string, columnId: string) => isSessionRef.current(rowId, columnId) ? store.current.error : null, []);\n\n /**\n * The row's next editable cell in display order, skipping instant columns — a change there is\n * the commit and hosts no editor for a caret to land in (docs/editing.md). Resolved from the\n * render that reached the screen: the order, the gate and each column's editing kind all come\n * from there, so a render nobody saw cannot decide where the caret goes, or that there is\n * nowhere to go.\n */\n const adjacentEditable = (rowId: string, columnId: string | null, backwards: boolean): string | null => {\n const order = committed.visibleColumnIds();\n const step = backwards ? -1 : 1;\n const from = columnId === null ? backwards ? order.length : -1 : order.indexOf(columnId);\n\n for (let index = from + step; index >= 0 && index < order.length; index += step) {\n const candidate = order[index];\n\n if (candidate !== undefined && committed.canEdit(rowId, candidate) && !committed.isInstant(candidate)) {\n return candidate;\n }\n }\n\n return null;\n };\n\n /**\n * Tab / Shift+Tab: commit, and only then move (docs/editing.md keyboard map). The neighbour is\n * resolved *after* the commit succeeds, never before it is sent — an async write leaves the\n * keyboard free, and a real render landing while it is out can hide the column the caret was\n * headed for, shut its gate, or move it somewhere else entirely.\n */\n const moveTo = useEventCallback((backwards: boolean) => {\n const { rowId } = store.current;\n const from = store.current.columnId;\n\n if (rowId === null || from === null) {\n return;\n }\n\n const settle = (succeeded: boolean) => {\n if (!succeeded) {\n return;\n }\n\n const target = adjacentEditable(rowId, from, backwards);\n\n if (target === null) {\n return;\n }\n\n start({ columnId: target, rowId });\n };\n\n const result = commit();\n\n if (isPromiseLike(result)) {\n // Custom editors may still reject despite the boolean-result contract; stay put.\n void Promise.resolve(result).then(settle, () => undefined);\n } else {\n settle(result);\n }\n });\n\n /**\n * The row's first editable cell — where F2 enters (docs/editing.md#keyboard-and-lifecycle).\n * `skipInstant` is the mode: cell mode has no editor to open on an instant column, row mode\n * does.\n */\n const firstEditable = useEventCallback((rowId: string, skipInstant: boolean): string | null => {\n // On screen first: `canEdit` will answer for a row that is filtered out or on another page —\n // a session may legitimately name one — but F2 acts on the row the user is looking at, and\n // opening an editor nobody can see is not that.\n if (!committed.onScreen(rowId)) {\n return null;\n }\n\n const order = committed.visibleColumnIds();\n\n return order.find(columnId => committed.canEdit(rowId, columnId) && (!skipInstant || !committed.isInstant(columnId))) ?? null;\n });\n\n return useMemo(\n () => {\n return {\n active,\n cancel,\n clear,\n commit,\n error,\n firstEditable,\n moveTo,\n pending,\n read,\n register,\n start,\n stop,\n write\n };\n },\n [active, cancel, clear, commit, error, firstEditable, moveTo, pending, read, register, start, stop, write]\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { EditGate } from \"./edit-meta\";\nimport type { Cell, Column, Row, TableInstance } from \"./types\";\n\n/**\n * What the last committed render resolved, kept where a later render cannot rewrite it.\n *\n * TanStack v9's `useTable` calls `table_setOptions` during render (see its source), so the one\n * shared core instance carries whatever the most recent render pass wrote — including a pass React\n * threw away, which happens whenever a transition renders and a sibling suspends. Everything the\n * core derives from those options follows: `getRow` and the row models, `getAllLeafColumns` and\n * every `columnDef` on them, and `options.meta.ledger`. The wrapper `useTable` returns is safe (its\n * `options` is that render's own object), but its methods delegate to the core, so reaching through\n * one at event time reaches the last render rather than the last commit.\n *\n * So ledger resolves its own answers from here instead: rows, columns and the editing gate as the\n * render that reached the screen left them. Mirrored in an insertion effect — the commit phase, and\n * before every layout effect, so a session boundary or an editor registration already sees it.\n *\n * The boundary this does *not* claim: the TanStack objects handed to the application (`row`,\n * `column` in a commit payload) are the ones that render resolved, not reconstructions — and\n * nothing here fixes the upstream mutation itself, only ledger's own reliance on it.\n */\nimport { useCallback, useMemo, useRef } from \"react\";\n\nimport { canEditWith, normalizeEdit } from \"./edit-meta\";\n\ntype ColumnEdit = NonNullable<Cell<any, unknown>[\"column\"][\"columnDef\"][\"meta\"]>[\"edit\"];\n\nexport type CaptureCommitted<TData extends RowData> = (table: TableInstance<TData>, gate: EditGate) => void;\n\nexport interface CommittedTable {\n /**\n * The row as the committed render resolved it — `original` included, which is what a commit\n * departs from.\n */\n row: (rowId: string) => Row<any> | null;\n /**\n * That row's value for a column, through the committed accessor.\n */\n value: (rowId: string, columnId: string) => unknown;\n /**\n * The committed `meta.edit`, never `cell.column.columnDef.meta` — the core rewrites its\n * definitions on every render pass, committed or not.\n */\n edit: (columnId: string) => ColumnEdit;\n /**\n * Whether the committed definitions hold this column at all. A column that left is a layout\n * change; a column whose gate shut is an application closing one, and row mode tells them apart\n * (docs/editing.md#row-mode).\n */\n has: (columnId: string) => boolean;\n /**\n * Every leaf column of the committed definitions, in their own order — the order\n * `row.getAllCells()` walks. Hidden ones included: a column the columns panel hid still holds a\n * draft, and still commits it (docs/editing.md).\n */\n columnIds: () => string[];\n /**\n * The leaf columns that render, in **display** order — start + center + end, the order the\n * header groups and each row's cells are drawn in. `getVisibleLeafColumns` alone ignores\n * pinning (docs/architecture.md), and a keyboard move that used it would step sideways past a\n * pinned column and back.\n */\n visibleColumnIds: () => string[];\n canEdit: (rowId: string, columnId: string) => boolean;\n /**\n * The row is one the committed render actually put on screen — after filtering, pagination and\n * pinning. `row` deliberately reaches further back (a session may name a row that is filtered\n * out, or has not arrived), so anything that means \"the row the user is looking at\" asks this.\n */\n onScreen: (rowId: string) => boolean;\n /**\n * The committed definition declares an instant-apply control — which the keyboard entry\n * points need, because what an instant column *is* depends on the mode (docs/editing.md).\n */\n isInstant: (columnId: string) => boolean;\n /**\n * Whether editing is possible at all: the table switch is on *and* the live mode has a handler\n * to send an edit to. Both are table-level facts, so this is answered without a row — which is\n * what lets a session whose row has not arrived still lose its gate, and keeps \"the row is not\n * here\" apart from \"the application closed the gate\" when they happen together.\n */\n tableGate: () => boolean;\n /**\n * The committed TanStack column, for the payload handed to the application.\n */\n column: (columnId: string) => Column<any, unknown> | null;\n}\n\ninterface Snapshot {\n displayRowIds: Set<string>;\n visibleColumnIds: string[];\n rows: Record<string, Row<any>>;\n coreRows: Record<string, Row<any>>;\n columns: Map<string, Column<any, unknown>>;\n columnIds: string[];\n enableEditing: boolean;\n hasCommitHandler: boolean;\n}\n\nconst EMPTY: Snapshot = {\n displayRowIds: new Set(),\n visibleColumnIds: [],\n columnIds: [],\n columns: new Map(),\n coreRows: {},\n enableEditing: false,\n hasCommitHandler: false,\n rows: {}\n};\n\n/**\n * Returns the readers and the one function that fills them. Taking the snapshot is deliberately\n * the caller's move: the table instance only exists further down `useDataTable`, while the session\n * controllers that read this are built before it — so the readers are handed out first and the\n * capture happens in the same insertion effect that mirrors the instance itself.\n */\nexport function useCommittedTable<TData extends RowData>(): readonly [CommittedTable, CaptureCommitted<TData>] {\n const snapshot = useRef<Snapshot>(EMPTY);\n\n const capture = useCallback<CaptureCommitted<TData>>((table, gate) => {\n const columns = new Map<string, Column<any, unknown>>();\n const columnIds: string[] = [];\n\n for (const column of table.getAllLeafColumns() as Array<Column<any, unknown>>) {\n columns.set(column.id, column);\n columnIds.push(column.id);\n }\n\n // What the body drew, in the same terms the keyboard navigation uses: pinned rows are on\n // screen alongside the page's own, and the row model alone would miss them.\n const displayRows = table.options.enableRowPinning === true\n ? [...table.getTopRows(), ...table.getCenterRows(), ...table.getBottomRows()]\n : table.getRowModel().rows;\n\n snapshot.current = {\n displayRowIds: new Set(displayRows.map(row => row.id)),\n visibleColumnIds: [\n ...table.getStartVisibleLeafColumns(),\n ...table.getCenterVisibleLeafColumns(),\n ...table.getEndVisibleLeafColumns()\n ].map(column => column.id),\n columnIds,\n columns,\n // The same two models `table_getRow(id, true)` consults, in the same order, read here where\n // the options behind them are still the ones this commit rendered from.\n coreRows: table.getCoreRowModel().rowsById as Record<string, Row<any>>,\n enableEditing: gate.enableEditing,\n hasCommitHandler: gate.hasCommitHandler,\n rows: table.getPrePaginatedRowModel().rowsById as Record<string, Row<any>>\n };\n }, []);\n\n // Stable identities: this goes to the session controllers, which memoize against it.\n const row = useCallback((rowId: string) => snapshot.current.rows[rowId] ?? snapshot.current.coreRows[rowId] ?? null, []);\n const column = useCallback((columnId: string) => snapshot.current.columns.get(columnId) ?? null, []);\n const has = useCallback((columnId: string) => snapshot.current.columns.has(columnId), []);\n const columnIds = useCallback(() => snapshot.current.columnIds, []);\n const onScreen = useCallback((rowId: string) => snapshot.current.displayRowIds.has(rowId), []);\n const visibleColumnIds = useCallback(() => snapshot.current.visibleColumnIds, []);\n const edit = useCallback((columnId: string) => snapshot.current.columns.get(columnId)?.columnDef.meta?.edit, []);\n const isInstant = useCallback((columnId: string) => normalizeEdit(snapshot.current.columns.get(columnId)?.columnDef.meta?.edit)?.kind === \"instant\", []);\n const tableGate = useCallback(() => snapshot.current.enableEditing && snapshot.current.hasCommitHandler, []);\n\n const value = useCallback((rowId: string, columnId: string) => {\n const found = snapshot.current.rows[rowId] ?? snapshot.current.coreRows[rowId] ?? null;\n\n // The committed column's accessor over the committed row, rather than `row.getValue` — which\n // resolves the column through `row.table`, and that is the shared core. Upstream caches a\n // row's values after the first read, so in most orders the two agree; depending on that is\n // depending on having read the value already, which nothing here can promise.\n return found === null ? undefined : snapshot.current.columns.get(columnId)?.accessorFn?.(found.original, found.index);\n }, []);\n\n const canEdit = useCallback((rowId: string, columnId: string) => {\n const found = snapshot.current.rows[rowId] ?? snapshot.current.coreRows[rowId] ?? null;\n\n if (!found) {\n return false;\n }\n\n return canEditWith(found, snapshot.current.columns.get(columnId)?.columnDef.meta?.edit, {\n enableEditing: snapshot.current.enableEditing,\n hasCommitHandler: snapshot.current.hasCommitHandler\n });\n }, []);\n\n const committed = useMemo(\n () => {\n return {\n canEdit,\n column,\n columnIds,\n edit,\n has,\n isInstant,\n onScreen,\n row,\n tableGate,\n value,\n visibleColumnIds\n };\n },\n [canEdit, column, columnIds, edit, has, isInstant, onScreen, row, tableGate, value, visibleColumnIds]\n );\n\n return [committed, capture] as const;\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { DataTableEditCommit, LedgerCellEditor, LedgerInstantEditingController } from \"./types\";\nimport type { CommittedTable } from \"./use-committed-table\";\n\n/**\n * The instant-apply controls' transient edits (docs/editing.md). An instant column never enters\n * edit mode — a change *is* the commit — so there is no session to open, hold a draft in, or\n * close. What a commit leaves behind still outlives the control that sent it: a write still out,\n * the failure it came back with, and the value the application now holds. Hiding the column, a\n * responsive breakpoint, or a virtual scroll unmounts that control at any moment, and none of\n * those are the write landing — so it lives here, and the control is a view of it.\n *\n * Addressed by target rather than by session: unlike cell mode, any number of controls can have\n * a write out at once, and each one's pending, failure and record are its own. Nested by row and\n * then column, never a joined key: row and column ids are opaque application strings, and any\n * separator is one an id may contain.\n */\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\n\nimport { editErrorMessage, normalizeEdit } from \"./edit-meta\";\nimport { isPromiseLike, useEventCallback } from \"./utils\";\n\nexport interface UseInstantEditingInput<TData extends RowData> {\n /**\n * Rows, definitions and the gate as the render that reached the screen left them — never the\n * cell's own table, which is the shared core (see `use-committed-table.ts`).\n */\n committed: CommittedTable;\n onEditCommit: ((change: DataTableEditCommit<TData>) => void | Promise<void>) | undefined;\n}\n\ninterface InstantTarget {\n /**\n * The write currently out. `moved` records that the data left what the write departed from\n * while it was still in flight — including leaving and coming back, which comparing once at\n * settle time could never see. `lost` records that the gate shut behind it: the write passed\n * before that and will still land, but the failure it may come back with has nowhere left to be\n * shown, and a gate that reopens is not a reprieve for it.\n */\n request: { token: number; value: unknown; source: unknown; moved: boolean; lost: boolean } | null;\n /**\n * What this target wrote, against what the data read when it went out. While it stands it is\n * what the cell holds — which is what the next commit departs from, so an application whose\n * data has not caught up is not asked to make the same change twice.\n */\n written: { value: unknown; source: unknown } | null;\n error: string | null;\n editors: Set<LedgerCellEditor>;\n}\n\ntype TargetStore = Map<string, Map<string, InstantTarget>>;\n\nfunction findTarget(store: TargetStore, rowId: string, columnId: string): InstantTarget | undefined {\n return store.get(rowId)?.get(columnId);\n}\n\n/**\n * The gate has shut on this target. There is no session to cancel — an instant commit is over\n * the moment it is sent — but the failure it was showing has nowhere left to be shown, and a\n * write still out must not bring one back when the gate reopens. Reports whether anything a\n * control shows changed.\n */\nfunction loseGate(target: InstantTarget): boolean {\n let touched = false;\n\n if (target.error !== null) {\n target.error = null;\n touched = true;\n }\n\n if (target.request) {\n target.request.lost = true;\n }\n\n return touched;\n}\n\nfunction redraw(target: InstantTarget): void {\n for (const editor of target.editors) {\n editor.redraw();\n }\n}\n\n/**\n * What the cell holds as far as the application is concerned.\n */\nfunction effectiveValue(target: InstantTarget | undefined, source: unknown): unknown {\n const record = target?.written;\n\n return record && Object.is(record.source, source) ? record.value : source;\n}\n\nexport function useInstantEditing<TData extends RowData>({\n committed,\n onEditCommit\n}: UseInstantEditingInput<TData>): LedgerInstantEditingController {\n const targets = useRef<TargetStore>(new Map());\n /**\n * One write, one token: only the request still standing for a target may act on it.\n */\n const tokenRef = useRef(0);\n\n const openTarget = (rowId: string, columnId: string): InstantTarget => {\n let columns = targets.current.get(rowId);\n\n if (!columns) {\n columns = new Map();\n targets.current.set(rowId, columns);\n }\n\n let target = columns.get(columnId);\n\n if (!target) {\n target = {\n editors: new Set(),\n error: null,\n request: null,\n written: null\n };\n columns.set(columnId, target);\n }\n\n return target;\n };\n\n /**\n * A target that has nothing left to remember and nothing on screen is not a target.\n */\n const dropIfEmpty = (rowId: string, columnId: string, target: InstantTarget) => {\n if (target.editors.size > 0 || target.request || target.written || target.error !== null) {\n return;\n }\n\n const columns = targets.current.get(rowId);\n\n columns?.delete(columnId);\n\n if (columns?.size === 0) {\n targets.current.delete(rowId);\n }\n };\n\n const settle = (rowId: string, columnId: string, token: number, message: string | null) => {\n const target = findTarget(targets.current, rowId, columnId);\n const request = target?.request;\n\n // Only the request still standing here may act: anything else was superseded, or belongs to a\n // target the data no longer holds.\n if (!target || !request || request.token !== token) {\n return;\n }\n\n target.request = null;\n\n if (message === null) {\n // Unless the data moved while the request was out — then what the application holds is its\n // own, and this write has nothing left to be true about.\n if (!request.moved) {\n target.written = { source: request.source, value: request.value };\n }\n } else if (!request.lost) {\n target.error = message;\n }\n\n redraw(target);\n dropIfEmpty(rowId, columnId, target);\n };\n\n const commit = useEventCallback((rowId: string, columnId: string, value: unknown): boolean | Promise<boolean> => {\n const row = committed.row(rowId);\n\n if (!row) {\n return false;\n }\n\n // Eligibility is re-read here, not trusted from the render that put this control on screen:\n // `edit.enabled` is application code, and nothing makes it answer the same way twice, so a\n // click can be the first thing to learn that the gate is shut. Both editing modes' commits\n // re-read it for exactly this reason (docs/architecture.md) — a change is a commit, and the\n // one path that skipped the check would write through a gate the application had closed, and\n // unvalidated besides, since a closed gate is what `validate` no longer guards. Asked before\n // anything is opened, so that a change which does not pass leaves nothing behind at all.\n if (!committed.canEdit(rowId, columnId)) {\n const shut = findTarget(targets.current, rowId, columnId);\n\n if (shut) {\n if (loseGate(shut)) {\n redraw(shut);\n }\n\n dropIfEmpty(rowId, columnId, shut);\n }\n\n return false;\n }\n\n const target = openTarget(rowId, columnId);\n\n // One write at a time per target: the control is disabled while its own is out, and a second\n // request would race the first to describe the same cell. Other targets are unaffected —\n // there is no shared session for them to join.\n if (target.request) {\n return false;\n }\n\n const source = committed.value(rowId, columnId);\n // What the application last knew, which after a write it has not fed back is that write —\n // not the data, which would ask it to make the same change twice.\n const previousValue = effectiveValue(target, source);\n\n target.error = null;\n\n const normalized = normalizeEdit(committed.edit(columnId));\n\n try {\n if (normalized?.validate) {\n const validationError = normalized.validate(value, row);\n\n if (validationError !== null) {\n target.error = validationError;\n redraw(target);\n\n return false;\n }\n }\n } catch (error) {\n target.error = editErrorMessage(error);\n redraw(target);\n\n return false;\n }\n\n let result: void | Promise<void>;\n\n try {\n result = onEditCommit?.({\n column: committed.column(columnId),\n previousValue,\n row,\n value\n } as DataTableEditCommit<TData>);\n } catch (error) {\n target.error = editErrorMessage(error);\n redraw(target);\n\n return false;\n }\n\n if (!isPromiseLike(result)) {\n target.written = { source, value };\n redraw(target);\n\n return true;\n }\n\n const token = ++tokenRef.current;\n target.request = {\n lost: false,\n moved: false,\n source,\n token,\n value\n };\n redraw(target);\n\n return Promise.resolve(result).then(\n () => {\n settle(rowId, columnId, token, null);\n\n return true;\n },\n (error: unknown) => {\n settle(rowId, columnId, token, editErrorMessage(error));\n\n return false;\n }\n );\n });\n\n /**\n * Reconciles every target with the table it lives in. Two things move under a transient edit:\n * the data can leave what a write departed from — the record retires for good, so data that\n * later returns to it cannot bring the value back with it — and the gate can shut, which takes\n * the control off the screen and with it any failure it was showing.\n *\n * Passive, not layout: nothing has to be keyed before a control can be used. No dependency\n * array, because what it watches is `enableEditing`, the column definitions and every target's\n * own data at once — nothing a list describes.\n */\n useEffect(() => {\n // Iterated live: `dropIfEmpty` deletes from these maps as it goes, which a Map iterator is\n // defined to tolerate — an entry removed before it is reached is simply not visited.\n for (const [rowId, columns] of targets.current) {\n for (const [columnId, target] of columns) {\n const row = committed.row(rowId);\n let touched = false;\n\n if (row) {\n const source = committed.value(rowId, columnId);\n\n if (target.written && !Object.is(target.written.source, source)) {\n target.written = null;\n touched = true;\n }\n\n // The same watch, for the write still out: it has no record to retire yet, so the\n // movement has to be remembered until it does.\n if (target.request && !Object.is(target.request.source, source)) {\n target.request.moved = true;\n }\n }\n\n // A row the table does not hold has not arrived, or the data no longer holds it. Neither\n // is an application shutting a gate; the table-level one — the switch and the mode's\n // commit handler — is, either way, and is answered without needing the row at all.\n const eligible = committed.tableGate() && (row === null || committed.canEdit(rowId, columnId));\n\n if (!eligible) {\n touched = loseGate(target) || touched;\n }\n\n if (touched) {\n redraw(target);\n }\n\n dropIfEmpty(rowId, columnId, target);\n }\n }\n });\n\n // Stable identities all the way out: this surface goes into `meta.ledger`, which the render\n // layer memoizes against. Each of these reads nothing but refs.\n const value = useCallback(\n (rowId: string, columnId: string, source: unknown) => effectiveValue(findTarget(targets.current, rowId, columnId), source),\n []\n );\n const pending = useCallback((rowId: string, columnId: string) => Boolean(findTarget(targets.current, rowId, columnId)?.request), []);\n const error = useCallback((rowId: string, columnId: string) => findTarget(targets.current, rowId, columnId)?.error ?? null, []);\n\n /**\n * A control registers while it is on screen, so the target it belongs to can tell it to draw\n * what it now holds. Bound to the controller and the cell, not to the component's lifetime: in\n * hook mode the table can be swapped for another instance while React keeps this control.\n */\n const register = useCallback((rowId: string, columnId: string, editor: LedgerCellEditor) => {\n openTarget(rowId, columnId).editors.add(editor);\n\n return () => {\n const target = findTarget(targets.current, rowId, columnId);\n\n if (!target) {\n return;\n }\n\n target.editors.delete(editor);\n dropIfEmpty(rowId, columnId, target);\n };\n }, []);\n\n return useMemo(\n () => {\n return {\n commit,\n error,\n pending,\n register,\n value\n };\n },\n [commit, error, pending, register, value]\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { ColumnDef } from \"./types\";\n\n/**\n * Breakpoint-driven column presence (`meta.hiddenFrom` / `meta.visibleFrom`, the host's own\n * `Box` vocabulary): a hidden column is removed from the definitions before TanStack sees\n * them, so the width engine, the colgroup, and the columns panel all follow — column state\n * keyed by id (`columnVisibility`, persistence) is untouched and reapplies when the column\n * returns.\n *\n * Breakpoint values resolve from Mantine's published CSS variables\n * (`--mantine-breakpoint-*`), falling back to the stock scale — no theme-context dependency,\n * so hook mode works wherever `useDataTable` does. Without `matchMedia` (SSR, jsdom) every\n * column stays visible.\n */\nimport { useEffect, useMemo, useState } from \"react\";\n\nconst STOCK_BREAKPOINTS: Record<string, string> = {\n xs: \"36em\",\n sm: \"48em\",\n md: \"62em\",\n lg: \"75em\",\n xl: \"88em\"\n};\n\nfunction breakpointValue(breakpoint: string): string {\n if (typeof document !== \"undefined\") {\n const fromTheme = getComputedStyle(document.documentElement)\n .getPropertyValue(`--mantine-breakpoint-${breakpoint}`)\n .trim();\n\n if (fromTheme !== \"\") {\n return fromTheme;\n }\n }\n\n return STOCK_BREAKPOINTS[breakpoint] ?? breakpoint;\n}\n\nfunction collectBreakpoints<TData extends RowData>(columns: Array<ColumnDef<TData, any>>, into: Set<string>): void {\n for (const column of columns) {\n if (\"columns\" in column && Array.isArray(column.columns)) {\n collectBreakpoints(column.columns, into);\n continue;\n }\n\n if (column.meta?.hiddenFrom) {\n into.add(column.meta.hiddenFrom);\n }\n\n if (column.meta?.visibleFrom) {\n into.add(column.meta.visibleFrom);\n }\n }\n}\n\nfunction filterColumns<TData extends RowData>(\n columns: Array<ColumnDef<TData, any>>,\n matches: Record<string, boolean>\n): Array<ColumnDef<TData, any>> {\n const result: Array<ColumnDef<TData, any>> = [];\n\n for (const column of columns) {\n if (\"columns\" in column && Array.isArray(column.columns)) {\n const children = filterColumns(column.columns, matches);\n\n // A group whose every child is off-breakpoint disappears with them.\n if (children.length > 0) {\n result.push(children === column.columns\n ? column\n // The ledger alias re-attaches `enableResizing`, which the group's TanStack-typed\n // `columns` slot does not carry — the assertion re-enters the alias.\n : { ...column, columns: children } as ColumnDef<TData, any>);\n }\n\n continue;\n }\n\n const { hiddenFrom, visibleFrom } = column.meta ?? {};\n\n // Host semantics: hiddenFrom hides AT AND ABOVE the breakpoint, visibleFrom shows only\n // there. An unknown match (no matchMedia) resolves to visible.\n if (hiddenFrom && matches[hiddenFrom] === true) {\n continue;\n }\n\n if (visibleFrom && matches[visibleFrom] === false) {\n continue;\n }\n\n result.push(column);\n }\n\n return result;\n}\n\nexport function useResponsiveColumns<TData extends RowData>(\n columns: Array<ColumnDef<TData, any>>\n): Array<ColumnDef<TData, any>> {\n // Serialized, not joined: a breakpoint is any CSS length the author writes, and the ones with\n // commas in them are ordinary (`clamp(30em, 50vw, 60em)`). A separator inside a value would\n // split one breakpoint into several nonsense media queries, none of which ever match.\n const breakpointsKey = useMemo(() => {\n const used = new Set<string>();\n collectBreakpoints(columns, used);\n\n return used.size === 0 ? \"\" : JSON.stringify([...used].toSorted());\n }, [columns]);\n\n const [matches, setMatches] = useState<Record<string, boolean>>({});\n\n useEffect(() => {\n if (breakpointsKey === \"\" || typeof matchMedia !== \"function\") {\n setMatches(previous => Object.keys(previous).length === 0 ? previous : {});\n\n return;\n }\n\n const queries = (JSON.parse(breakpointsKey) as string[]).map(breakpoint => {\n const query = matchMedia(`(min-width: ${breakpointValue(breakpoint)})`);\n const apply = () => setMatches(previous => previous[breakpoint] === query.matches\n ? previous\n : { ...previous, [breakpoint]: query.matches });\n\n apply();\n query.addEventListener(\"change\", apply);\n\n return { query, apply };\n });\n\n return () => {\n for (const { query, apply } of queries) {\n query.removeEventListener(\"change\", apply);\n }\n };\n }, [breakpointsKey]);\n\n return useMemo(() => {\n if (breakpointsKey === \"\") {\n return columns;\n }\n\n const filtered = filterColumns(columns, matches);\n\n // Identity-preserving when nothing is filtered out, so downstream memos stay cold.\n return filtered.length === columns.length && filtered.every((column, index) => column === columns[index])\n ? columns\n : filtered;\n }, [columns, matches, breakpointsKey]);\n}\n","import type { ExpandedState, RowData, RowSelectionState } from \"@tanstack/react-table\";\n\nimport type { SelectionRules } from \"./toggle-fns\";\nimport type { Row, TableInstance } from \"./types\";\nimport type { SliceSetter } from \"./use-slice\";\n\n/**\n * Selection and expansion, answered from the render that reached the screen.\n *\n * Both features decide half of a toggle outside the updater they hand the state setter, and that\n * half reads the shared core (`toggle-fns.ts`). So the controls call these controllers instead:\n * the row objects, the display order and the rules all come from a snapshot taken in an\n * **insertion effect** — the commit phase — and the write goes through the stable slice setter,\n * whose own updater still resolves against the committed value.\n *\n * The controllers are stable for the life of the instance, which is what lets a cell reach one\n * through whatever route it has (a context field, `meta.ledger`) without that route deciding\n * anything.\n */\nimport { useCallback, useMemo, useRef } from \"react\";\n\nimport {\n nextAllSelection,\n nextExpanded,\n nextPageSelection,\n nextRangeSelection,\n nextRowSelection\n} from \"./toggle-fns\";\n\nexport interface LedgerSelectionController {\n /**\n * One checkbox. `range` is the modifier the event carried — a Shift range departs from the\n * last row this table toggled and covers the display order on screen.\n */\n toggle: (row: Row<any>, checked: boolean, range: boolean) => void;\n toggleAll: (scope: \"page\" | \"all\", value: boolean) => void;\n}\n\nexport interface LedgerExpansionController {\n /**\n * `expanded` and `canExpand` are the drawing render's answers — what the chevron shows is what\n * clicking it departs from.\n */\n toggle: (rowId: string, expanded: boolean, canExpand: boolean) => void;\n toggleAll: (value: boolean, canSomeExpand: boolean) => void;\n}\n\ninterface RowSnapshot {\n /**\n * `getRowsInDisplayOrder()` — what a Shift range walks and what `getDisplayIndex` counts.\n */\n displayOrder: Array<Row<any>>;\n pageRows: Array<Row<any>>;\n /**\n * The pre-grouped flat rows a select-all over every row visits.\n */\n flatRows: Array<Row<any>>;\n rowsById: Record<string, Row<any>>;\n /**\n * Resolved on demand: only an `expanded === true` table has to materialize the map, and a\n * per-commit walk of every row would be O(rows) on a table sized for virtualization.\n */\n expandableRowIds: () => string[];\n rules: SelectionRules;\n rangeEnabled: boolean;\n}\n\nconst ALWAYS = () => true;\n\nconst EMPTY: RowSnapshot = {\n displayOrder: [],\n expandableRowIds: () => [],\n flatRows: [],\n pageRows: [],\n rangeEnabled: true,\n rowsById: {},\n rules: {\n canMultiSelect: ALWAYS,\n canSelect: ALWAYS,\n canSelectSubRows: ALWAYS\n }\n};\n\n/**\n * `boolean | (row) => boolean | undefined`, resolved once against the committed options.\n */\nfunction rule(option: unknown): (row: Row<any>) => boolean {\n if (typeof option === \"function\") {\n return row => (option as (row: Row<any>) => boolean)(row) === true;\n }\n\n return () => option !== false;\n}\n\nexport type CaptureRows<TData extends RowData> = (table: TableInstance<TData>) => void;\n\nexport function useRowCommands<TData extends RowData>(\n setRowSelection: SliceSetter<RowSelectionState>,\n setExpanded: SliceSetter<ExpandedState>\n): readonly [LedgerSelectionController, LedgerExpansionController, CaptureRows<TData>] {\n const snapshot = useRef<RowSnapshot>(EMPTY);\n /**\n * The Shift anchor. v9 keeps it on the core instance (`_lastSelectedRowId`), which is the one\n * object a discarded render also writes.\n */\n const anchorId = useRef<string | null>(null);\n\n const capture = useCallback<CaptureRows<TData>>(table => {\n const { options } = table;\n const canExpand = (row: Row<any>): boolean => options.getRowCanExpand?.(row as never) ?? ((options.enableExpanding ?? true) && row.subRows.length > 0);\n const rowModelRows = table.getRowModel().rowsById as Record<string, Row<any>>;\n\n // Every read here is an identity check on a memoized answer, so a commit costs O(1). The\n // display order in particular is memoized upstream on the three things that move it — the\n // pre-paginated rows, `paginateExpandedRows`, and `expanded` in the mode that interleaves\n // descendants — so an unrelated state tick never walks the rows (a guardrail test pins it).\n snapshot.current = {\n displayOrder: table.getRowsInDisplayOrder() as Array<Row<any>>,\n expandableRowIds: () => Object.values(rowModelRows).filter(row => canExpand(row)).map(row => row.id),\n flatRows: table.getPreGroupedRowModel().flatRows as Array<Row<any>>,\n pageRows: table.getRowModel().rows as Array<Row<any>>,\n rangeEnabled: options.enableRowRangeSelection !== false,\n rowsById: table.getCoreRowModel().rowsById as Record<string, Row<any>>,\n rules: {\n canMultiSelect: rule(options.enableMultiRowSelection),\n canSelect: rule(options.enableRowSelection),\n canSelectSubRows: rule(options.enableSubRowSelection)\n }\n };\n }, []);\n\n const selection = useMemo<LedgerSelectionController>(\n () => {\n return {\n toggle: (row, checked, range) => {\n const {\n displayOrder,\n rules,\n rangeEnabled\n } = snapshot.current;\n\n if (!rules.canSelect(row)) {\n return;\n }\n\n const anchor = anchorId.current;\n const anchorIndex = anchor === null ? -1 : displayOrder.findIndex(candidate => candidate.id === anchor);\n const rowIndex = displayOrder.findIndex(candidate => candidate.id === row.id);\n const rangeRow = displayOrder[rowIndex];\n\n // Both endpoints must still be in the order on screen and both must accept company,\n // or the interaction falls back to an ordinary toggle — v9's own conditions.\n const asRange\n = range\n && rangeEnabled\n && anchorIndex !== -1\n && rowIndex !== -1\n && rangeRow !== undefined\n && rules.canMultiSelect(displayOrder[anchorIndex] as Row<any>)\n && rules.canMultiSelect(row);\n\n if (asRange) {\n setRowSelection(previous => nextRangeSelection(\n previous,\n displayOrder,\n {\n anchorIndex,\n rowIndex,\n value: checked\n },\n rules\n ));\n } else {\n setRowSelection(previous => nextRowSelection(previous, row, checked, rules));\n }\n\n anchorId.current = row.id;\n },\n toggleAll: (scope, value) => {\n const {\n pageRows,\n flatRows,\n rowsById,\n rules\n } = snapshot.current;\n anchorId.current = null;\n\n setRowSelection(previous => scope === \"page\"\n ? nextPageSelection(previous, pageRows, value, rules)\n : nextAllSelection(previous, flatRows, rowsById, value, rules));\n }\n };\n },\n [setRowSelection]\n );\n\n const expansion = useMemo<LedgerExpansionController>(\n () => {\n return {\n toggle: (rowId, expanded, canExpand) => {\n const target = !expanded;\n\n if (target && !canExpand) {\n return;\n }\n\n setExpanded(previous => nextExpanded(previous, rowId, target, snapshot.current.expandableRowIds));\n },\n toggleAll: (value, canSomeExpand) => {\n if (value && !canSomeExpand) {\n return;\n }\n\n setExpanded(() => value ? true : Object.create(null) as ExpandedState);\n }\n };\n },\n [setExpanded]\n );\n\n return [selection, expansion, capture] as const;\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type {\n DataTableRowEditCommit,\n LedgerRowEditingController,\n LedgerRowEditor,\n Row\n} from \"./types\";\nimport type { CommittedTable } from \"./use-committed-table\";\n\n/**\n * The row-mode editing session (docs/editing.md#row-mode). The third of the three sessions, and\n * the same shape as the other two: everything the row's editors show, and everything its atomic\n * commit decides with, lives here rather than in the editors — a hidden column or a virtual\n * scroll unmounts an editor at any moment, and a session is not (docs/architecture.md).\n *\n * What is particular to row mode: one commit covers every editable column at once, so the drafts\n * are a store rather than a single value, and the baseline the commit departs from is snapshotted\n * when the row opens — a responsive breakpoint can take a column out of the definitions before\n * commit time, leaving no cell to read a previous value from.\n */\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\n\nimport { editErrorMessage, normalizeEdit } from \"./edit-meta\";\nimport { useEventCallback } from \"./utils\";\n\nexport interface UseRowEditingInput<TData extends RowData> {\n editingRowId: string | null;\n setEditingRowId: (rowId: string | null) => void;\n /**\n * Rows, definitions and the gate as the render that reached the screen left them. Everything a\n * commit decides with comes from here rather than from the cell's own table, which is the shared\n * core and carries whatever pass ran last (see `use-committed-table.ts`).\n */\n committed: CommittedTable;\n onRowEditCommit: ((change: DataTableRowEditCommit<TData>) => void | Promise<void>) | undefined;\n}\n\n/**\n * The controller's surface minus `id`, which is the slice itself and belongs to whoever owns it.\n * Declared as the public contract minus that one key so the two cannot drift apart.\n */\nexport type RowEditingSession = Omit<LedgerRowEditingController, \"id\">;\n\nexport function useRowEditing<TData extends RowData>({\n committed,\n editingRowId,\n onRowEditCommit,\n setEditingRowId\n}: UseRowEditingInput<TData>): RowEditingSession {\n // Drafts live here, not in editors: a virtualized editing row that scrolls out unmounts its\n // editors, and the pending values must survive until the atomic commit.\n const rowDrafts = useRef<{\n rowId: string | null;\n values: Map<string, unknown>;\n /**\n * Every editable column's value as the row's edit began, or null while the row itself is\n * not in the table yet — see `openRowDrafts`.\n */\n baseline: Map<string, unknown> | null;\n /**\n * What this session has already written, per column, against the value the data held when\n * it went out — see `previousRowValue`.\n */\n committed: Map<string, { value: unknown; source: unknown }>;\n /**\n * Eligibility was lost during this session. It latches: a gate that reopens before an\n * in-flight write settles is the *next* session's eligibility, not a reprieve for this one.\n */\n gateLost: boolean;\n /**\n * The automatic reconciliation has already answered this session's gate closing.\n */\n reconciled: boolean;\n /**\n * The write currently out, per column, and whether the data has moved since it left. A record\n * is only true while the data has not moved past it, and the moving can happen *during* the\n * request — including out and back again, which comparing at settle time could never see.\n */\n writing: Map<string, { source: unknown; moved: boolean }> | null;\n }>({\n rowId: null,\n values: new Map(),\n baseline: new Map(),\n committed: new Map(),\n gateLost: false,\n reconciled: false,\n writing: null\n });\n const rowEditors = useRef(new Map<string, LedgerRowEditor>());\n /**\n * Bumped whenever a row session starts or ends without the slice moving — a gate shutting under\n * a controlled application that declines to close it, or an explicit start on the row already\n * named. Whether an editor may be on screen is part of the render output, so a change in it has\n * to be a change in state; a ref would leave the last render standing.\n */\n const [rowSessionEpoch, setRowSessionEpoch] = useState(0);\n /**\n * What the row's editors show that is not a value: a write still out, and the reason the last\n * one failed. Session state, not editor state — an editor is unmounted by a hidden column or a\n * virtual scroll at any moment, and one that came back knowing neither would take input during\n * a write and let the user send a second one, while a rejection arriving with no editor mounted\n * would have had nowhere to go at all.\n */\n const rowPresentation = useRef<{\n pending: boolean;\n /**\n * `columnId: null` is the row's own failure — a rejected commit belongs to no cell, and which\n * column shows it is decided when an editor renders (`rowErrorColumnId`).\n */\n error: { columnId: string | null; message: string } | null;\n }>({\n error: null,\n pending: false\n });\n const rowFocusColumn = useRef<string | null>(null);\n const editingRowRef = useRef(editingRowId);\n /**\n * One editing session, one token. An async commit captures it and may only act on what it\n * finds afterwards if the token still matches: cancelling the row, finishing it, or opening\n * another one all end the session, and a settled request from the previous one must not close\n * the editor that replaced it (nor report its error onto that editor's first field).\n */\n const rowSessionRef = useRef(0);\n /**\n * The in-flight row commit, so repeated `stopEditing({ commit: true })` calls wait on one\n * result instead of firing `onRowEditCommit` again — the single-flight guarantee cell mode\n * already makes (docs/editing.md). It carries its owner: a request belonging to a session\n * that has ended is not a request the next row may join, or its own write would never be sent.\n */\n const rowPendingCommit = useRef<{ session: number; rowId: string; promise: Promise<boolean> } | null>(null);\n const rowStartRequestRef = useRef(0);\n\n /**\n * Ends the session: whatever is in flight stops owning the row, and stops speaking for it.\n */\n const endRowSession = () => {\n rowSessionRef.current += 1;\n rowPendingCommit.current = null;\n };\n\n /**\n * Every editable value of `rowId` as it stands now, or null while that row is not in the\n * table: an application can name the row it wants edited before the fetch carrying it lands,\n * and \"this row has no previous values\" is a different answer from \"there is no row to ask\".\n */\n const snapshotEditableValues = (rowId: string): Map<string, unknown> | null => {\n if (committed.row(rowId) === null) {\n return null;\n }\n\n const baseline = new Map<string, unknown>();\n\n for (const columnId of committed.columnIds()) {\n if (committed.canEdit(rowId, columnId)) {\n baseline.set(columnId, committed.value(rowId, columnId));\n }\n }\n\n return baseline;\n };\n\n /**\n * Opens the draft store on a row. The baseline is snapshotted now, while every editable\n * column still exists: a responsive breakpoint removes a column from the definitions before\n * TanStack ever sees it, so by commit time its cell is gone and there is nothing left to read\n * a previous value from. A row the table does not hold yet leaves the baseline unrecorded for\n * the effect below to take once it arrives.\n */\n const openRowDrafts = (rowId: string | null) => {\n rowDrafts.current = {\n rowId,\n values: new Map(),\n baseline: rowId === null ? new Map() : snapshotEditableValues(rowId),\n committed: new Map(),\n gateLost: false,\n reconciled: false,\n writing: null\n };\n rowPresentation.current = { error: null, pending: false };\n };\n\n /**\n * The drafts held for `rowId`. A read, never a write: editors read their draft while\n * rendering, and a render can be thrown away (a transition that suspends), so re-keying the\n * store from here would let an abandoned render erase the values on screen. The effect below\n * is the store's only keyer. A caller asking about another row gets nothing, which is the\n * truth.\n */\n const draftsFor = (rowId: string | null): Map<string, unknown> => rowDrafts.current.rowId === rowId ? rowDrafts.current.values : new Map();\n\n /**\n * What the application last knew this column to hold — the value the row is editing away from.\n * A session can outlive its own writes: a controlled application may decline to close the row,\n * and the data it feeds back arrives whenever it arrives. Until then `source` — what the cell\n * read when the write went out — still matches, and the value written is the newer truth. Once\n * the data moves, it wins: it may be our write applied, normalised, or somebody else's.\n */\n const previousRowValue = (columnId: string, source: unknown): unknown => {\n const written = rowDrafts.current.committed.get(columnId);\n\n return written && Object.is(written.source, source) ? written.value : source;\n };\n\n /**\n * Takes back the pending values a write actually carried, leaving anything typed since. What it\n * carried is recorded as committed instead; a draft left standing over it would go on beating\n * the data the application feeds back — including a value it normalized on the way in.\n */\n const consumeCommittedRowDrafts = (rowId: string, sent: Record<string, unknown>) => {\n if (rowDrafts.current.rowId !== rowId) {\n return;\n }\n\n for (const [columnId, value] of rowDrafts.current.values) {\n if (Object.hasOwn(sent, columnId) && Object.is(value, sent[columnId])) {\n rowDrafts.current.values.delete(columnId);\n }\n }\n };\n\n /**\n * Records a write that went through, so the next commit departs from it rather than from data\n * that has not caught up. The entry is retired by `reconcileRowEligibility` the moment the data\n * moves — see `previousRowValue`.\n */\n const recordRowCommit = (rowId: string, values: Record<string, unknown>, sources: Map<string, unknown>) => {\n if (rowDrafts.current.rowId !== rowId) {\n return;\n }\n\n const { writing } = rowDrafts.current;\n\n for (const [columnId, value] of Object.entries(values)) {\n // A column whose data moved while the request was out has nothing for this write to still\n // be true about: what the application holds there is its own.\n if (writing?.get(columnId)?.moved === true) {\n rowDrafts.current.committed.delete(columnId);\n\n continue;\n }\n\n rowDrafts.current.committed.set(columnId, { value, source: sources.get(columnId) });\n }\n\n rowDrafts.current.writing = null;\n };\n\n /**\n * Whether the row holds a value the write that just settled never carried. A custom editor is\n * not disabled while a request is out, so the user can type straight past it; leaving on that\n * write's word would drop what they typed.\n */\n const hasUncommittedRowEdits = (rowId: string, sent: Record<string, unknown>): boolean => {\n if (rowDrafts.current.rowId !== rowId) {\n return false;\n }\n\n for (const [columnId, value] of rowDrafts.current.values) {\n if (!Object.hasOwn(sent, columnId) || !Object.is(value, sent[columnId])) {\n return true;\n }\n }\n\n return false;\n };\n\n /**\n * Throws the whole pending edit away — what cancelling means. The mounted editors are put back\n * alongside the store because the row can stay on screen: a controlled application may decline\n * to close it, and an editor still showing a value the store no longer holds is one nothing\n * would commit. What they show once the store is empty is the store's answer again — the value\n * the session has written, or the data — so they are only asked to draw themselves anew.\n */\n const discardRowEdits = (rowId: string | null) => {\n if (rowId === null || rowDrafts.current.rowId !== rowId) {\n return;\n }\n\n rowDrafts.current.values.clear();\n rowPresentation.current.error = null;\n\n for (const editor of rowEditors.current.values()) {\n editor.redraw();\n }\n };\n\n /**\n * Asks for the row edit to end. A request, not the ending itself: `editingRowId` is a\n * controlled slice, and an application may answer `onEditingRowIdChange` by leaving the prop\n * exactly where it was. The row then stays on screen, and a row on screen is one the user can\n * still type into — so the session, its ownership of an in-flight commit, and the draft store\n * all stay with it until a render says otherwise.\n */\n const finishRowEditing = useEventCallback(() => {\n rowFocusColumn.current = null;\n setEditingRowId(null);\n });\n\n /**\n * Reconciles the session with the row that actually reached the screen. Every change of\n * `editingRowId` lands here, ledger's own requests included, because it is a controlled\n * slice: `startRowEditing` and `finishRowEditing` can only ask, and an application may move\n * the edit itself, answer with a different row, or decline to move it at all. Committing the\n * boundary anywhere else would leave the session speaking for a row nobody is editing.\n *\n * It is a layout effect and not a render-phase check because ending a session is a real side\n * effect — it invalidates an in-flight commit's ownership — and React may render a tree it\n * never commits (a transition that suspends). Refs are shared between the current tree and\n * the work-in-progress one, so a render for a row the user never saw would otherwise strand\n * the row still on screen: its commit disowned, its editors pending forever. Layout, not\n * passive: the drafts store has to be keyed before anything can be typed into it.\n *\n * No dependency array on purpose. The comparison is against what was committed last time,\n * which no dependency list describes.\n */\n useLayoutEffect(() => {\n const moved = editingRowRef.current !== editingRowId;\n\n if (moved) {\n endRowSession();\n\n if (editingRowId !== null) {\n // A `startRowEditing` still waiting on a commit was going to open a row, and the edit\n // has landed on a different one — that request is overruled. Landing on *no* row is the\n // ordinary end of the very commit it is waiting for, and must not cancel it.\n rowStartRequestRef.current += 1;\n }\n\n editingRowRef.current = editingRowId;\n }\n\n if (moved || rowDrafts.current.rowId !== editingRowId) {\n // The second test also catches the first pass, where the ref already agrees with the prop\n // but the store has never been keyed: a controlled row open from the very first render\n // still needs its baseline, and the table instance only exists once the hook body has run.\n openRowDrafts(editingRowId);\n } else if (editingRowId !== null && rowDrafts.current.baseline === null) {\n // The row was not in the table when the edit opened. Data arriving later is the first\n // chance to record what the user is editing away from; anything typed meanwhile stays.\n rowDrafts.current.baseline = snapshotEditableValues(editingRowId);\n }\n });\n\n /**\n * Reconciles the row being edited with the table it lives in. Three things can move under an\n * open row, and only one of them ends it:\n *\n * - the data moves past a value this session wrote — the overlay entry retires for good, so\n * data that later returns to what the write departed from cannot bring our value back with\n * it (`previousRowValue` tests the same thing, for the reads that happen before this runs);\n * - a column's gate shuts (`meta.edit` removed, `edit.enabled(row)` turning false) — its\n * pending value goes now rather than at commit time, so a gate that reopens cannot bring back\n * a draft nothing was showing;\n * - a column simply leaves the definitions, a responsive breakpoint crossing — nothing shut,\n * the layout changed, and its draft still commits against the baseline (docs/editing.md).\n *\n * So the row ends when the table switch is off, or when the gate shut on a column this session\n * was editing and none is left editable. A row the table does not hold yet has not arrived,\n * which is not the same as a row that may not be edited.\n *\n */\n const markRowGateLost = () => {\n if (rowDrafts.current.gateLost) {\n return;\n }\n\n rowDrafts.current.gateLost = true;\n setRowSessionEpoch(epoch => epoch + 1);\n };\n\n /**\n * Cancels the session: what it holds is discarded — it never passed a gate — and the close is\n * asked for.\n */\n const cancelLostRowSession = (rowId: string) => {\n rowDrafts.current.reconciled = true;\n discardRowEdits(rowId);\n finishRowEditing();\n };\n\n /**\n * Ends a session whose eligibility is gone, once nothing is still out on its behalf. Returns\n * whether it ended the row: a session that stops because the gate shut was cancelled, not\n * finished, so nothing waiting on a commit may move on the strength of it.\n */\n const endLostRowSession = (rowId: string): boolean => {\n if (!rowDrafts.current.gateLost) {\n return false;\n }\n\n // The write already out passed the gate before it shut; its settlement calls this again and\n // completes the cancel. The loss is recorded either way, so a gate reopening cannot undo it.\n if (rowPendingCommit.current) {\n return false;\n }\n\n // Once per session. This runs after every render, and an application that ignores the close\n // would otherwise be asked again on each one — reconciliation, not nagging. An explicit stop\n // or start goes its own way and is always a fresh request.\n if (rowDrafts.current.reconciled) {\n return false;\n }\n\n cancelLostRowSession(rowId);\n\n return true;\n };\n\n const reconcileRowEligibility = useEventCallback((): boolean => {\n const rowId = editingRowRef.current;\n\n if (rowId === null) {\n return false;\n }\n\n // The table-level gate — the switch and the mode's commit handler — is answered before the row\n // is even looked for. A session opened on a row whose data has not arrived would otherwise\n // survive it closing, and one that reopened before the data landed would find the old session\n // waiting.\n if (!committed.tableGate()) {\n markRowGateLost();\n }\n\n const row = committed.row(rowId);\n\n if (!row) {\n // Not in the table: a row that has not arrived, or one the data no longer holds. Neither is\n // a gate closing, so the session stands — but a switch that shut above still ends it.\n return endLostRowSession(rowId);\n }\n\n const { baseline } = rowDrafts.current;\n let editable = false;\n let gateShut = false;\n\n for (const columnId of committed.columnIds()) {\n const source = committed.value(rowId, columnId);\n const written = rowDrafts.current.committed.get(columnId);\n\n if (written && !Object.is(written.source, source)) {\n rowDrafts.current.committed.delete(columnId);\n }\n\n // The same watch, for a write still out: it has no record to retire yet, so the movement\n // has to be remembered until it does.\n const writing = rowDrafts.current.writing?.get(columnId);\n\n if (writing && !Object.is(writing.source, source)) {\n writing.moved = true;\n }\n\n if (committed.canEdit(rowId, columnId)) {\n editable = true;\n\n // The last effective previous this session saw for the column, refreshed while it is\n // here to be seen: `previousValues` means what the application last knew, and a column\n // whose definition later disappears has nothing else left to answer with. Recording it\n // on every sighting also gives the session its membership — which is how a gate shutting\n // on a column it was editing is told apart from a breakpoint taking one away.\n baseline?.set(columnId, previousRowValue(columnId, source));\n } else {\n gateShut ||= baseline?.has(columnId) ?? false;\n rowDrafts.current.values.delete(columnId);\n }\n }\n\n // What keeps a row editing: a cell it can edit now, or values it still owes a commit for a\n // column whose *definition* left — a breakpoint crossing, which shut no gate. A gate really\n // shutting on a column this session was editing ends it, and so does a session that never had\n // anything to edit at all (no `meta.edit`, or no handler for the mode).\n if (!(editable || (!gateShut && (baseline?.size ?? 0) > 0))) {\n markRowGateLost();\n }\n\n return endLostRowSession(rowId);\n });\n\n /**\n * Passive, not layout: nothing has to be keyed before the user can type, and this must not race\n * the session boundary above. No dependency array, because what it watches is `enableEditing`,\n * the column definitions and the row's own data at once — nothing a list describes.\n */\n useEffect(() => {\n reconcileRowEligibility();\n });\n\n /**\n * Whether the request issued under `session` still speaks for `rowId`. Sessions end the moment\n * the rendered row changes, so the two tests agree by construction; the row id is spelled out\n * because acting on another row's editors is precisely what a stale settlement must not do.\n */\n const isCurrentRowSession = (session: number, rowId: string) => rowSessionRef.current === session && editingRowRef.current === rowId;\n\n /**\n * The column currently showing the row's failure: the one it names, or for a row-level failure\n * the first editable column with an editor on screen, in the row's own cell order. Resolved on\n * every read rather than fixed when the failure is reported, so a message follows the screen\n * when the column under it is hidden or scrolls away.\n */\n const rowErrorColumnId = (rowId: string): string | null => {\n const { error } = rowPresentation.current;\n\n if (!error) {\n return null;\n }\n\n if (error.columnId !== null) {\n return error.columnId;\n }\n\n return committed\n .columnIds()\n .find(columnId => committed.canEdit(rowId, columnId) && rowEditors.current.has(columnId)) ?? null;\n };\n\n // Stable, and reads nothing but refs — so `registerRowEditor` can close over it directly rather\n // than through a mirror written during render, which is the very thing this round forbade.\n const redrawRowEditors = useCallback(() => {\n for (const editor of rowEditors.current.values()) {\n editor.redraw();\n }\n }, []);\n\n /**\n * Only a row-level failure is projected onto whoever is on screen, so only that has to be\n * redrawn when the registry changes; everything else an editor shows it already reads for\n * itself as it renders.\n */\n const redrawRowLevelError = useCallback(() => {\n if (rowPresentation.current.error?.columnId === null) {\n redrawRowEditors();\n }\n }, [redrawRowEditors]);\n\n const setRowPending = (pending: boolean) => {\n rowPresentation.current.pending = pending;\n redrawRowEditors();\n };\n\n /**\n * Records a failure on the session, so it outlives the editors: one that is unmounted when the\n * message arrives shows it when it comes back. `columnId: null` is the row's own — a rejected\n * commit belongs to no cell.\n */\n const reportRowError = (rowId: string, columnId: string | null, message: string) => {\n rowPresentation.current.error = { columnId, message };\n redrawRowEditors();\n\n const shown = rowErrorColumnId(rowId);\n\n if (shown !== null) {\n rowEditors.current.get(shown)?.focus();\n }\n };\n\n const commitRow = useEventCallback((): boolean | Promise<boolean> => {\n const rowId = editingRowRef.current;\n\n if (rowId === null) {\n return true;\n }\n\n // Idempotent while pending: a second Enter, a blur behind it, or the application calling\n // `stopEditing` again all join the request already in flight rather than issuing another\n // write. Only the owner may join — a request left over from a row the controller has moved\n // on from would otherwise stand in for this row's write, which would then never be sent.\n const inFlight = rowPendingCommit.current;\n\n if (inFlight && inFlight.session === rowSessionRef.current && inFlight.rowId === rowId) {\n return inFlight.promise;\n }\n\n // Eligibility is re-read here, not trusted from when the session opened: `enableEditing` can\n // switch off, `meta.edit` can be removed, and `edit.enabled(row)` — application code, which\n // nothing makes answer the same way twice — can turn false with no render in between, which\n // makes this commit the first thing to learn of it. The same reconciliation the effect runs,\n // so the table-level switch, a gate closing on a column this session was editing, and a\n // breakpoint merely taking a column away are told apart exactly once, in one place.\n //\n // A session cancelled that way did not finish: what it held never passed a gate and is\n // discarded rather than promoted (a draft whose column also left the definitions has no cell\n // left to test it against, and the baseline path below would otherwise reconstruct and send\n // it), and nothing waiting to move may proceed on the strength of it.\n const cancelledNow = reconcileRowEligibility();\n\n if (rowDrafts.current.gateLost) {\n if (!cancelledNow) {\n // Reconciliation is once per session; a command is not. An owner that declined the close\n // still has this row on screen, so it is asked again.\n cancelLostRowSession(rowId);\n }\n\n return false;\n }\n\n const row = committed.row(rowId);\n\n if (!row) {\n // The row left the data set mid-edit — there is nothing to commit onto.\n finishRowEditing();\n return true;\n }\n\n rowPresentation.current.error = null;\n redrawRowEditors();\n\n // Every editable column, not just the visible ones (docs/api.md: \"every editable column,\n // drafts merged in\"). Hiding a column mid-edit — the columns panel, or a responsive\n // breakpoint crossing on a window resize — must not silently drop the value typed into it,\n // still less make `changed` false and discard the whole commit.\n const presentColumnIds = committed.columnIds();\n const editableColumnIds = presentColumnIds.filter(columnId => committed.canEdit(rowId, columnId));\n const drafts = draftsFor(rowId);\n const values: Record<string, unknown> = {};\n const previousValues: Record<string, unknown> = {};\n // What the data itself reads, so a write that goes through can later be told apart from the\n // data catching up with it.\n const sources = new Map<string, unknown>();\n let changed = false;\n\n for (const columnId of editableColumnIds) {\n const source = committed.value(rowId, columnId);\n const previous = previousRowValue(columnId, source);\n const value = drafts.has(columnId) ? drafts.get(columnId) : previous;\n sources.set(columnId, source);\n values[columnId] = value;\n previousValues[columnId] = previous;\n changed ||= !Object.is(value, previous);\n }\n\n // Drafts whose column produced no entry above fall into two very different cases.\n for (const [columnId, value] of drafts) {\n if (Object.hasOwn(values, columnId)) {\n continue;\n }\n\n if (committed.has(columnId)) {\n // The column is still here, it simply stopped being editable mid-edit — `meta.edit`\n // removed, or `edit.enabled(row)` now false for this row. Committing that draft would\n // push a value through a gate the application just closed, and unvalidated besides (the\n // validation pass below only walks editable cells). The pending value is dropped, not\n // promoted. (The reconciliation at the entry to `commitRow` has usually done this\n // already; a column whose gate shut between the two is why it is still tested here.)\n drafts.delete(columnId);\n\n continue;\n }\n\n // The other case: the column left the definitions entirely — a responsive breakpoint\n // crossing removes it before TanStack ever sees it, so there is no cell to read. The value\n // the user typed is still theirs and commits against the baseline captured at edit start.\n // Its `validate` cannot run, because the definition that carried it is gone.\n const source = rowDrafts.current.baseline?.get(columnId);\n const previous = previousRowValue(columnId, source);\n sources.set(columnId, source);\n values[columnId] = value;\n previousValues[columnId] = previous;\n changed ||= !Object.is(value, previous);\n }\n\n // First validation failure focuses its editor and blocks the whole row.\n for (const columnId of editableColumnIds) {\n const normalized = normalizeEdit(committed.edit(columnId));\n\n if (!normalized?.validate) {\n continue;\n }\n\n let message: string | null;\n\n try {\n message = normalized.validate(values[columnId], row);\n } catch (error) {\n message = editErrorMessage(error);\n }\n\n if (message !== null) {\n reportRowError(rowId, columnId, message);\n\n return false;\n }\n }\n\n if (!changed) {\n finishRowEditing();\n return true;\n }\n\n let result: void | Promise<void>;\n\n try {\n // Single erasure, the same boundary the render layer crosses: the committed resolver speaks\n // the erased shape, and v9's `in out` generics make Row invariant in TData.\n result = onRowEditCommit?.({\n row: row as Row<TData>,\n values,\n previousValues\n });\n } catch (error) {\n reportRowError(rowId, null, editErrorMessage(error));\n return false;\n }\n\n if (result && typeof result.then === \"function\") {\n const session = rowSessionRef.current;\n rowDrafts.current.writing = new Map(\n [...sources].map(([columnId, source]) => [columnId, { moved: false, source }])\n );\n setRowPending(true);\n\n const pending = Promise.resolve(result).then(\n () => {\n // Everything below touches the editors on screen, so a request whose session has\n // ended stops here: its row was cancelled or replaced, and the editors it would\n // close or un-pend belong to whoever came next. It reports failure, because the\n // caller waiting on it wanted to leave *that* row and that row is already gone —\n // navigating on its word would move an edit the controller has since redirected.\n if (!isCurrentRowSession(session, rowId)) {\n return false;\n }\n\n rowPendingCommit.current = null;\n recordRowCommit(rowId, values, sources);\n consumeCommittedRowDrafts(rowId, values);\n setRowPending(false);\n\n // The gate may have shut while this write was out; the test was held off until the\n // write it let through had landed. If it did shut, the row has just been cancelled —\n // it did not finish here, and a switch waiting on this commit must not open a row\n // nobody may edit.\n if (reconcileRowEligibility()) {\n return false;\n }\n\n if (hasUncommittedRowEdits(rowId, values)) {\n // Typed straight past the request while it was out. The write did go through, but\n // this row is not finished — and whoever was waiting to leave it must not.\n return false;\n }\n\n finishRowEditing();\n\n return true;\n },\n (error: unknown) => {\n if (!isCurrentRowSession(session, rowId)) {\n return false;\n }\n\n rowPendingCommit.current = null;\n rowDrafts.current.writing = null;\n setRowPending(false);\n reportRowError(rowId, null, editErrorMessage(error));\n reconcileRowEligibility();\n\n return false;\n }\n );\n\n rowPendingCommit.current = {\n session,\n rowId,\n promise: pending\n };\n\n return pending;\n }\n\n recordRowCommit(rowId, values, sources);\n consumeCommittedRowDrafts(rowId, values);\n finishRowEditing();\n return true;\n });\n\n /**\n * Focuses a mounted editor of the row being edited. A column not yet on screen — hidden, or\n * scrolled out of the virtual window — is left to `shouldFocus` when its editor mounts.\n */\n const focusRowColumn = (columnId: string | undefined) => {\n if (columnId !== undefined) {\n rowEditors.current.get(columnId)?.focus();\n }\n };\n\n const startRowEditing = useEventCallback((rowId: string, startOptions?: { focusColumnId?: string }) => {\n if (editingRowRef.current === rowId) {\n rowFocusColumn.current = startOptions?.focusColumnId ?? rowFocusColumn.current;\n\n if (rowDrafts.current.gateLost) {\n // The session on this row is over — its gate shut, and a controlled application declined\n // to close it. An explicit start is not that session coming back: it is the next one, so\n // it gets a new token and a fresh baseline, and nothing the old one held survives. The\n // slice already names this row, so no render would arrive to do it for us.\n endRowSession();\n openRowDrafts(rowId);\n setRowSessionEpoch(epoch => epoch + 1);\n }\n\n // A live session focuses the column asked for: the editors are already mounted, and the\n // slice is not moving, so nothing else would.\n redrawRowEditors();\n focusRowColumn(startOptions?.focusColumnId);\n\n return;\n }\n\n // Like `finishRowEditing`, a request: the session boundary is taken by the effect above,\n // once a render has actually put this row on screen.\n const begin = () => {\n rowFocusColumn.current = startOptions?.focusColumnId ?? null;\n setEditingRowId(rowId);\n };\n\n if (editingRowRef.current === null) {\n begin();\n return;\n }\n\n // Another row is mid-edit: commit it first (commit, never discard); only success moves on,\n // and only the latest start request may win after an async commit settles.\n const request = ++rowStartRequestRef.current;\n const outcome = commitRow();\n\n if (typeof outcome === \"boolean\") {\n if (outcome) {\n begin();\n }\n\n return;\n }\n\n void outcome.then(success => {\n if (success && rowStartRequestRef.current === request) {\n begin();\n }\n });\n });\n\n const stopRowEditing = useEventCallback((stopOptions?: { commit?: boolean }) => {\n if (stopOptions?.commit ?? true) {\n void commitRow();\n } else {\n discardRowEdits(editingRowRef.current);\n finishRowEditing();\n }\n });\n\n const shouldFocusRowColumn = useCallback((columnId: string) => rowFocusColumn.current === columnId, []);\n\n /**\n * Whether this row has a live editing session. The slice naming a row is not enough: its gate\n * may have shut while a controlled application declined to close it, and a session whose\n * eligibility is gone must not put an interactive editor back on screen when the gate reopens.\n */\n const rowSessionActive = useCallback(\n // Asked during render, so it cannot consult the committed mirror — that still names the row\n // this one is replacing. A row the store has not been keyed to yet is a session about to\n // open, which is live by definition; only the one being tracked can have lost its gate.\n //\n // Keyed to the epoch: the answer lives in a ref, so this identity changing is what carries a\n // session starting or ending into the render layer's memo.\n (rowId: string) => rowDrafts.current.rowId === rowId ? !rowDrafts.current.gateLost : true,\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- the epoch is the point: see above\n [rowSessionEpoch]\n );\n\n const registerRowEditor = useCallback((columnId: string, editor: LedgerRowEditor) => {\n rowEditors.current.set(columnId, editor);\n redrawRowLevelError();\n\n return () => {\n if (rowEditors.current.get(columnId) !== editor) {\n return;\n }\n\n rowEditors.current.delete(columnId);\n redrawRowLevelError();\n };\n }, [redrawRowLevelError]);\n\n /**\n * The store is what a row editor shows, rather than a value it copies at mount: what the row\n * holds moves under it — the application feeds a write back, normalizes it, or another writer\n * changes it — and an editor with its own copy would go on showing a value the row left behind.\n * Editors name the row they belong to instead of reading it from a shared mutable ref, because\n * two rows' editors can be on screen at once while React reconciles a switch.\n */\n const rowDraftsApi = useRef({\n pending: (rowId: string) => rowDrafts.current.rowId === rowId && rowPresentation.current.pending,\n error: (rowId: string, columnId: string) => {\n if (rowDrafts.current.rowId !== rowId || rowErrorColumnId(rowId) !== columnId) {\n return null;\n }\n\n return rowPresentation.current.error?.message ?? null;\n },\n read: (rowId: string, columnId: string, source: unknown) => {\n if (rowDrafts.current.rowId !== rowId) {\n return source;\n }\n\n return rowDrafts.current.values.has(columnId)\n ? rowDrafts.current.values.get(columnId)\n : previousRowValue(columnId, source);\n },\n write: (rowId: string, columnId: string, value: unknown) => {\n if (rowDrafts.current.rowId !== rowId) {\n return;\n }\n\n rowDrafts.current.values.set(columnId, value);\n\n // Typing answers the complaint the field is showing, and only that one: another column's\n // message is still true, and its editor is not the one being redrawn.\n if (rowErrorColumnId(rowId) === columnId) {\n rowPresentation.current.error = null;\n }\n }\n }).current;\n\n // Stable identities all the way out: this surface goes into `meta.ledger`, which the render\n // layer memoizes against — a fresh object or a fresh arrow here would re-render every cell in\n // the table on every render. Each of these reads nothing but refs.\n return useMemo(\n () => {\n return {\n active: rowSessionActive,\n commit: commitRow,\n drafts: rowDraftsApi,\n register: registerRowEditor,\n shouldFocus: shouldFocusRowColumn,\n start: startRowEditing,\n stop: stopRowEditing\n };\n },\n [rowSessionActive, commitRow, rowDraftsApi, registerRowEditor, shouldFocusRowColumn, startRowEditing, stopRowEditing]\n );\n}\n","import type { Updater } from \"@tanstack/react-table\";\n\n/**\n * One state slice of the table, following the canonical React controlled/uncontrolled contract\n * (docs/state.md): controlled `value` / uncontrolled `defaultValue` / observer `onChange`\n * receiving the resolved value. TanStack hands us `Updater`s; they are resolved here so consumer\n * callbacks never see a function.\n */\nimport { useUncontrolled } from \"@mantine/hooks\";\nimport { functionalUpdate } from \"@tanstack/react-table\";\nimport { useCallback, useInsertionEffect, useRef } from \"react\";\n\nexport type SliceSetter<T> = (updater: Updater<T>) => void;\n\nexport interface UseSliceInput<T> {\n value: T | undefined;\n defaultValue: T | undefined;\n onChange: ((value: T) => void) | undefined;\n /**\n * Internal notification for every resolved set attempt, including no-op values that React does\n * not render. Used by debounced controls to observe an external reset to the current value.\n */\n onSet?: (value: T) => void;\n fallback: T;\n}\n\nexport function useSlice<T>({\n value,\n defaultValue,\n onChange,\n onSet,\n fallback\n}: UseSliceInput<T>): readonly [T, SliceSetter<T>] {\n const [current, setCurrent, controlled] = useUncontrolled<T>({\n value,\n defaultValue,\n finalValue: fallback,\n onChange\n });\n\n /**\n * What actually reached the screen, and the handlers of the render that put it there. Mirrored\n * in an effect rather than during render: refs are shared between the current tree and a\n * work-in-progress one, so a transition React renders and then throws away — a sibling\n * suspends — would otherwise leave updaters resolving against a value nobody ever saw, and\n * calling the abandoned render's `onChange`. Insertion phase, so that a layout effect setting\n * a slice already sees this render's values; `useEventCallback` mirrors its handler the same\n * way, for the same reason.\n */\n const committedRef = useRef(current);\n const setCurrentRef = useRef(setCurrent);\n const onSetRef = useRef(onSet);\n const controlledRef = useRef(controlled);\n\n /**\n * The value already asked for and not yet seen on screen, so updaters resolve against each\n * other rather than against a snapshot the last one has already moved past. How long it may\n * stand depends on who owns the state.\n */\n const requestedRef = useRef<{ value: T; controlled: boolean } | null>(null);\n\n useInsertionEffect(() => {\n const previous = committedRef.current;\n committedRef.current = current;\n\n // What ends a request depends on who owns the state, because only one of them can answer one.\n //\n // Controlled: the owner is the authority, and `value` moving *is* it answering — to what was\n // asked for, to a normalization of it, or to something else entirely. Any move ends the\n // request, and the next updater departs from the answer. Only silence leaves one standing,\n // because silence is a refusal and a deferral at once and nothing tells them apart; `set`\n // bounds that with a microtask.\n //\n // Uncontrolled: the value is ours, so only a commit that actually carries it ends the\n // request. React renders lanes it has not been asked to flush yet — an urgent update commits\n // without the transition queued behind it — and an update still sitting in that queue is one\n // React will apply, so it goes on counting until it does.\n //\n // A slice that has changed hands drops it either way: what the last owner asked for is\n // nothing the new one agreed to.\n const request = requestedRef.current;\n\n if (request\n && (request.controlled !== controlled\n || Object.is(current, request.value)\n || (controlled && !Object.is(current, previous)))) {\n requestedRef.current = null;\n }\n\n setCurrentRef.current = setCurrent;\n onSetRef.current = onSet;\n controlledRef.current = controlled;\n });\n\n const set = useCallback<SliceSetter<T>>(updater => {\n // A request the other owner made says nothing about this one's value.\n const requested = requestedRef.current?.controlled === controlledRef.current ? requestedRef.current : null;\n const next = functionalUpdate(updater, requested ? requested.value : committedRef.current);\n\n // Uncontrolled state always takes the update. React renders it when it chooses — a\n // transition renders on a task of its own — so the value stands until the render carrying it\n // commits, and the insertion effect above is what ends it.\n //\n // A controlled owner may instead answer by leaving `value` exactly where it was, and nothing\n // tells that refusal apart from an acceptance it has deferred: both look like silence. So\n // there the value stands for the event that asked for it and no longer, dropped by a\n // microtask queued when the burst starts. An owner deferring inside a transition therefore\n // sees the next event depart from what is on screen rather than from what it has not applied\n // — building on a value it may never take is the worse of the two mistakes.\n if (requested === null && controlledRef.current) {\n queueMicrotask(() => {\n requestedRef.current = null;\n });\n }\n\n requestedRef.current = { controlled: controlledRef.current, value: next };\n onSetRef.current?.(next);\n setCurrentRef.current(next);\n }, []);\n\n return [current, set] as const;\n}\n","import type {\n ColumnFiltersState,\n ColumnOrderState,\n ColumnPinningState,\n ColumnSizingState,\n ExpandedState,\n GroupingState,\n PaginationState,\n RowData,\n RowPinningState,\n RowSelectionState,\n SortingState,\n TableOptions,\n TableState,\n Updater\n} from \"@tanstack/react-table\";\n\nimport type { LedgerInternalMeta, LedgerSortingController } from \"./ledger-commands\";\nimport type { LedgerFeatures } from \"./ledger-features\";\nimport type {\n DataTableEditingCell,\n TableInstance,\n UseDataTableOptions\n} from \"./types\";\n\n/**\n * The behavior core (docs/api.md): assembles the canonical v9 feature set (plus consumer\n * `filterFns`), translates `*Mode: \"server\"` into TanStack's manual flags, injects the\n * selection/expander columns, normalizes every state slice into the controlled/uncontrolled\n * trio, and carries ledger-private state through `table.options.meta.ledger`. Returns the bare\n * TanStack table instance.\n */\nimport { functionalUpdate, useTable } from \"@tanstack/react-table\";\nimport { useCallback, useEffect, useInsertionEffect, useMemo, useRef, useState } from \"react\";\n\nimport { buildColumns, EXPANDER_COLUMN_ID, SELECTION_COLUMN_ID } from \"./build-columns\";\nimport { isDev, warnOnce } from \"./env\";\nimport { ledgerFilterFns } from \"./filter-fns\";\nimport { buildLedgerFeatures } from \"./ledger-features\";\nimport { readPersistedState, usePersistWriter } from \"./persist\";\nimport { nextSorting } from \"./toggle-fns\";\nimport { useCellEditing } from \"./use-cell-editing\";\nimport { useCommittedTable } from \"./use-committed-table\";\nimport { useInstantEditing } from \"./use-instant-editing\";\nimport { useResponsiveColumns } from \"./use-responsive-columns\";\nimport { useRowCommands } from \"./use-row-commands\";\nimport { useRowEditing } from \"./use-row-editing\";\nimport { useSlice } from \"./use-slice\";\n\n/* Stable fallbacks — a fresh identity per render would defeat TanStack's memoization. */\nconst NO_SORTING: SortingState = [];\nconst NO_COLUMN_FILTERS: ColumnFiltersState = [];\nconst NO_ROW_SELECTION: RowSelectionState = {};\nconst NO_EXPANDED: ExpandedState = {};\nconst NO_VISIBILITY: Record<string, boolean> = {};\nconst NO_PINNING: ColumnPinningState = { start: [], end: [] };\nconst NO_COLUMN_ORDER: ColumnOrderState = [];\nconst NO_COLUMN_SIZING: ColumnSizingState = {};\nconst NO_GROUPING: GroupingState = [];\nconst NO_ROW_PINNING: RowPinningState = { top: [], bottom: [] };\nconst DEFAULT_PAGINATION: PaginationState = { pageIndex: 0, pageSize: 20 };\n\nexport function useDataTable<TData extends RowData>(options: UseDataTableOptions<TData>): TableInstance<TData> {\n const {\n data,\n columns,\n getRowId,\n enableSorting = true,\n enableMultiSort = true,\n enableSortingRemoval = true,\n enableColumnFilters = true,\n enableGlobalFilter = false,\n enablePagination = false,\n enableRowSelection = false,\n enableMultiRowSelection = true,\n enableColumnResizing = false,\n enableColumnPinning = true,\n enableColumnOrdering = false,\n enableHiding = true,\n enableEditing = true,\n enableGrouping = false,\n enableRowPinning = false,\n enableCellSpanning = true,\n getSubRows,\n renderDetailPanel,\n selectionColumn,\n expanderColumn,\n sortingMode = \"client\",\n filterMode = \"client\",\n paginationMode = \"client\",\n rowCount,\n editTrigger = \"double-click\",\n editMode = \"cell\",\n onEditCommit,\n onRowEditCommit,\n enableActiveRow = false,\n enableRowOrdering = false,\n onRowReorder,\n rowDragColumn,\n persistState,\n defaultColumn,\n tableOptions\n } = options;\n\n /* ---- the feature set: canonical modules + the consumer's filterFns, fixed at mount ---- */\n const [features] = useState<LedgerFeatures>(() => buildLedgerFeatures(options.filterFns));\n\n if (isDev && options.filterFns) {\n for (const filterFnId of Object.keys(ledgerFilterFns)) {\n if (Object.hasOwn(options.filterFns, filterFnId)) {\n warnOnce(\n `filterFns.${filterFnId}`,\n `filterFns.${filterFnId} is reserved by ledger and has been overridden.`\n );\n }\n }\n }\n\n /* ---- persistence hydrates uncontrolled slices, once, synchronously ---- */\n const [persisted] = useState(() => readPersistedState(persistState));\n const filterSetListeners = useRef({\n columnFilters: new Set<(value: ColumnFiltersState) => void>(),\n globalFilter: new Set<(value: string) => void>()\n });\n\n /* ---- state slices: controlled x / uncontrolled defaultX / observer onXChange ---- */\n const [sorting, setSorting] = useSlice({\n value: options.sorting,\n defaultValue: (persisted.sorting as SortingState | undefined) ?? options.defaultSorting,\n onChange: options.onSortingChange,\n fallback: NO_SORTING\n });\n const [columnFilters, setColumnFilters] = useSlice({\n value: options.columnFilters,\n defaultValue: (persisted.columnFilters as ColumnFiltersState | undefined) ?? options.defaultColumnFilters,\n onChange: options.onColumnFiltersChange,\n onSet: value => {\n for (const listener of filterSetListeners.current.columnFilters) {\n listener(value);\n }\n },\n fallback: NO_COLUMN_FILTERS\n });\n const [globalFilter, setGlobalFilter] = useSlice({\n value: options.globalFilter,\n defaultValue: (persisted.globalFilter as string | undefined) ?? options.defaultGlobalFilter,\n onChange: options.onGlobalFilterChange,\n onSet: value => {\n for (const listener of filterSetListeners.current.globalFilter) {\n listener(value);\n }\n },\n fallback: \"\"\n });\n const [pagination, setPagination] = useSlice({\n value: options.pagination,\n defaultValue: (persisted.pagination as PaginationState | undefined) ?? options.defaultPagination,\n onChange: options.onPaginationChange,\n fallback: DEFAULT_PAGINATION\n });\n const [rowSelection, setRowSelection] = useSlice({\n value: options.rowSelection,\n defaultValue: options.defaultRowSelection,\n onChange: options.onRowSelectionChange,\n fallback: NO_ROW_SELECTION\n });\n const [expanded, setExpanded] = useSlice({\n value: options.expanded,\n defaultValue: options.defaultExpanded,\n onChange: options.onExpandedChange,\n fallback: NO_EXPANDED\n });\n const [columnVisibility, setColumnVisibility] = useSlice({\n value: options.columnVisibility,\n defaultValue: (persisted.columnVisibility as Record<string, boolean> | undefined) ?? options.defaultColumnVisibility,\n onChange: options.onColumnVisibilityChange,\n fallback: NO_VISIBILITY\n });\n const [columnPinning, setColumnPinning] = useSlice({\n value: options.columnPinning,\n defaultValue: (persisted.columnPinning as ColumnPinningState | undefined) ?? options.defaultColumnPinning,\n onChange: options.onColumnPinningChange,\n fallback: NO_PINNING\n });\n const [columnOrder, setColumnOrder] = useSlice({\n value: options.columnOrder,\n defaultValue: (persisted.columnOrder as ColumnOrderState | undefined) ?? options.defaultColumnOrder,\n onChange: options.onColumnOrderChange,\n fallback: NO_COLUMN_ORDER\n });\n const [columnSizing, setColumnSizing] = useSlice({\n value: options.columnSizing,\n defaultValue: (persisted.columnSizing as ColumnSizingState | undefined) ?? options.defaultColumnSizing,\n onChange: options.onColumnSizingChange,\n fallback: NO_COLUMN_SIZING\n });\n const [grouping, setGrouping] = useSlice({\n value: options.grouping,\n defaultValue: (persisted.grouping as GroupingState | undefined) ?? options.defaultGrouping,\n onChange: options.onGroupingChange,\n fallback: NO_GROUPING\n });\n const [rowPinning, setRowPinning] = useSlice({\n value: options.rowPinning,\n defaultValue: options.defaultRowPinning,\n onChange: options.onRowPinningChange,\n fallback: NO_ROW_PINNING\n });\n const [editingCell, setEditingCell] = useSlice<DataTableEditingCell | null>({\n value: options.editingCell,\n defaultValue: undefined,\n onChange: options.onEditingCellChange,\n fallback: null\n });\n const [editingRowId, setEditingRowId] = useSlice<string | null>({\n value: options.editingRowId,\n defaultValue: undefined,\n onChange: options.onEditingRowIdChange,\n fallback: null\n });\n const [activeRowId, setActiveRowSlice] = useSlice<string | null>({\n value: options.activeRowId,\n defaultValue: options.defaultActiveRowId,\n onChange: options.onActiveRowIdChange,\n fallback: null\n });\n const setActiveRowId = useCallback(\n (id: string | null) => setActiveRowSlice(id),\n [setActiveRowSlice]\n );\n const setNormalizedGlobalFilter = useCallback((updater: Updater<unknown>) => {\n setGlobalFilter(previous => {\n const next = functionalUpdate(updater, previous);\n\n return typeof next === \"string\" ? next : \"\";\n });\n }, [setGlobalFilter]);\n\n /* ---- editing controller (docs/editing.md) ---- */\n // Rows, definitions and the gate as the render that reached the screen left them: everything the\n // editing paths decide with is resolved from here, never from the shared core, which carries\n // whatever pass ran last — a discarded one included (see `use-committed-table.ts`).\n const [committed, captureCommitted] = useCommittedTable<TData>();\n\n // The cell session lives in its own module: everything an editor shows, and everything its\n // commit decides with, has to outlive an editor that a hidden column or a virtual scroll can\n // unmount at any moment (docs/architecture.md).\n const cellSession = useCellEditing<TData>({\n committed,\n editingCell,\n onEditCommit,\n setEditingCell\n });\n\n // An instant column commits on change instead of opening an editor, but what a commit leaves\n // behind — a write still out, its failure, the value the application now holds — outlives the\n // control just as a session outlives its editor (docs/architecture.md).\n const instantSession = useInstantEditing<TData>({\n committed,\n onEditCommit\n });\n\n /* ---- row editing controller (editMode: \"row\", docs/editing.md#row-mode) ---- */\n // In its own module for the reason the other two sessions are: what the row's editors show, and\n // what its atomic commit decides with, has to outlive editors a hidden column or a virtual\n // scroll can unmount at any moment (docs/architecture.md).\n const rowSession = useRowEditing<TData>({\n committed,\n editingRowId,\n onRowEditCommit,\n setEditingRowId\n });\n\n if (isDev && editMode === \"row\") {\n if (options.editingCell !== undefined || options.onEditingCellChange) {\n warnOnce(\"row-mode-editing-cell\", \"editingCell is a cell-mode slice — editMode: \\\"row\\\" tracks editingRowId instead.\");\n }\n\n if (onEditCommit) {\n warnOnce(\"row-mode-on-edit-commit\", \"onEditCommit never fires under editMode: \\\"row\\\" — use onRowEditCommit.\");\n }\n }\n\n const [selectionCommands, expansionCommands, captureRows] = useRowCommands<TData>(setRowSelection, setExpanded);\n const sortingCommands = useMemo<LedgerSortingController>(\n () => {\n return {\n toggle: (spec, multi) => setSorting(previous => nextSorting(previous, spec, multi))\n };\n },\n [setSorting]\n );\n\n const subscribeColumnFilters = useCallback((listener: (value: ColumnFiltersState) => void) => {\n const listeners = filterSetListeners.current.columnFilters;\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n }, []);\n const subscribeGlobalFilter = useCallback((listener: (value: string) => void) => {\n const listeners = filterSetListeners.current.globalFilter;\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n }, []);\n\n const selectAllScope: \"page\" | \"all\"\n = enablePagination || paginationMode === \"server\" ? \"page\" : \"all\";\n\n /* ---- columns: breakpoint filter + injected row-drag/selection/expander + meta.filter wiring ---- */\n const responsiveColumns = useResponsiveColumns(columns);\n const withExpander = Boolean(renderDetailPanel || getSubRows);\n // The static row-ordering gate (docs/rows.md#row-ordering): without a handler nothing could\n // apply a move — row order is data order — and tree data has no flat order to move within.\n const withRowDrag = enableRowOrdering && onRowReorder !== undefined && !getSubRows;\n\n if (isDev && enableRowOrdering && getSubRows) {\n warnOnce(\"row-ordering-tree\", \"enableRowOrdering supports flat data only — getSubRows disables it (docs/rows.md#row-ordering).\");\n }\n\n const processedColumns = useMemo(\n () => buildColumns({\n columns: responsiveColumns,\n withRowDrag,\n withSelection: Boolean(enableRowSelection),\n withExpander,\n rowDragColumn,\n selectionColumn,\n expanderColumn\n }),\n [responsiveColumns, withRowDrag, enableRowSelection, withExpander, rowDragColumn, selectionColumn, expanderColumn]\n );\n\n // The live half of the gate: while something else controls the visible order, a \"reorder\"\n // has no data-order meaning — the handles disable and say why (labels.rowOrderingUnavailable).\n const rowOrderable = withRowDrag\n && sorting.length === 0\n && columnFilters.length === 0\n && !globalFilter\n && grouping.length === 0;\n\n const ledger: LedgerInternalMeta<TData> = useMemo(\n () => {\n return {\n columns: processedColumns,\n sorting: sortingCommands,\n selection: selectionCommands,\n expansion: expansionCommands,\n editing: {\n mode: editMode,\n cell: editingCell,\n active: cellSession.active,\n start: cellSession.start,\n stop: cellSession.stop,\n clear: cellSession.clear,\n commit: cellSession.commit,\n cancel: cellSession.cancel,\n moveTo: cellSession.moveTo,\n drafts: {\n error: cellSession.error,\n pending: cellSession.pending,\n read: cellSession.read,\n write: cellSession.write\n },\n register: cellSession.register,\n firstEditable: cellSession.firstEditable,\n instant: instantSession,\n // The slice is the hook's, the session is the controller's — spread so the two cannot\n // drift out of the shape `LedgerRowEditingController` declares.\n row: { id: editingRowId, ...rowSession }\n },\n filtering: {\n subscribeColumnFilters,\n subscribeGlobalFilter\n },\n editTrigger,\n enableEditing,\n onEditCommit,\n onRowEditCommit,\n renderDetailPanel,\n selectAllScope,\n activeRow: {\n enabled: enableActiveRow,\n id: activeRowId,\n set: setActiveRowId\n },\n enableColumnOrdering,\n enableColumnResizing,\n enablePagination,\n rowOrdering: {\n enabled: withRowDrag,\n orderable: rowOrderable,\n onRowReorder\n }\n };\n },\n [\n sortingCommands,\n selectionCommands,\n expansionCommands,\n processedColumns,\n editingCell,\n cellSession,\n instantSession,\n editMode,\n editingRowId,\n rowSession,\n subscribeColumnFilters,\n subscribeGlobalFilter,\n editTrigger,\n enableEditing,\n onEditCommit,\n onRowEditCommit,\n renderDetailPanel,\n selectAllScope,\n enableActiveRow,\n activeRowId,\n setActiveRowId,\n enableColumnOrdering,\n enableColumnResizing,\n enablePagination,\n withRowDrag,\n rowOrderable,\n onRowReorder\n ]\n );\n\n /* Injected columns are always pinned to the start, invisibly merged over the consumer's slice. */\n const mergedColumnPinning = useMemo<ColumnPinningState>(() => {\n const internal: string[] = [];\n\n if (enableRowSelection) {\n internal.push(SELECTION_COLUMN_ID);\n }\n\n if (withExpander) {\n internal.push(EXPANDER_COLUMN_ID);\n }\n\n const start = columnPinning.start.filter(id => !internal.includes(id));\n\n return { start: [...internal, ...start], end: columnPinning.end };\n }, [columnPinning, enableRowSelection, withExpander]);\n\n /* ---- dev guard rails (docs/state.md) ---- */\n if (isDev && (enableRowSelection || withExpander) && !getRowId) {\n warnOnce(\n \"missing-get-row-id\",\n \"Row selection/expansion is enabled without getRowId — index-based row ids corrupt state across refetches.\"\n );\n }\n\n const churn = useRef({\n renders: 0,\n columnChanges: 0,\n previousColumns: columns\n });\n\n if (isDev) {\n const tracker = churn.current;\n tracker.renders += 1;\n\n if (columns !== tracker.previousColumns) {\n tracker.columnChanges += 1;\n tracker.previousColumns = columns;\n }\n\n if (tracker.renders >= 10 && tracker.columnChanges >= tracker.renders - 2) {\n warnOnce(\n \"columns-identity\",\n \"`columns` has a new identity on almost every render — memoize it, or the table re-initializes continuously.\"\n );\n }\n }\n\n /* ---- client/server translation + auto-reset policy (docs/state.md) ---- */\n const manualSorting = sortingMode === \"server\";\n const manualFiltering = filterMode === \"server\";\n const serverPagination = paginationMode === \"server\";\n /**\n * v9 runs the paginated row model unless the factory is absent or `manualPagination` is set\n * (`getRowModel` → `getPrePaginatedRowModel`). The factory is part of the canonical feature\n * set and features are read once at mount, so the switch that stays reactive is this one:\n * with pagination off every row has to reach the body, which is the same short-circuit the\n * server mode takes. It is inert elsewhere — `paginateExpandedRows` defaults to `true`, so\n * the expanded row model is unaffected, and the upstream page-reset default it also gates is\n * meaningless while there are no pages.\n */\n const bypassPaginatedRowModel = serverPagination || !enablePagination;\n\n const shouldAutoResetPageIndex\n = tableOptions?.autoResetAll ?? tableOptions?.autoResetPageIndex ?? true;\n const previousResetInputs = useRef({\n columnFilters,\n globalFilter,\n sorting\n });\n\n useEffect(() => {\n const previous = previousResetInputs.current;\n const inputsChanged\n = previous.columnFilters !== columnFilters\n || previous.globalFilter !== globalFilter\n || previous.sorting !== sorting;\n previousResetInputs.current = {\n columnFilters,\n globalFilter,\n sorting\n };\n\n if (!serverPagination || !shouldAutoResetPageIndex || !inputsChanged) {\n return;\n }\n\n setPagination(previous => previous.pageIndex === 0 ? previous : { ...previous, pageIndex: 0 });\n }, [\n columnFilters,\n globalFilter,\n sorting,\n serverPagination,\n setPagination,\n shouldAutoResetPageIndex\n ]);\n\n // ---- reset targets ----\n // TanStack's slice reset APIs restore `table.initialState`. The live state remains fully\n // controlled; this object exists only to preserve ledger's `defaultX`/fallback contract.\n // Persisted values stay excluded so reset remains useful after hydration.\n const resetInitialState: Partial<TableState<LedgerFeatures>> = {\n sorting: options.defaultSorting ?? NO_SORTING,\n columnFilters: options.defaultColumnFilters ?? NO_COLUMN_FILTERS,\n globalFilter: options.defaultGlobalFilter ?? \"\",\n pagination: options.defaultPagination ?? DEFAULT_PAGINATION,\n rowSelection: options.defaultRowSelection ?? NO_ROW_SELECTION,\n expanded: options.defaultExpanded ?? NO_EXPANDED,\n columnVisibility: options.defaultColumnVisibility ?? NO_VISIBILITY,\n columnPinning: options.defaultColumnPinning ?? NO_PINNING,\n columnOrder: options.defaultColumnOrder ?? NO_COLUMN_ORDER,\n columnSizing: options.defaultColumnSizing ?? NO_COLUMN_SIZING,\n grouping: options.defaultGrouping ?? NO_GROUPING,\n rowPinning: options.defaultRowPinning ?? NO_ROW_PINNING\n };\n\n /* ---- assemble: tableOptions is the base layer, ledger-managed keys override (docs/state.md) ---- */\n const managed = {\n data,\n columns: processedColumns,\n features,\n ...getRowId && { getRowId },\n ...defaultColumn && { defaultColumn },\n initialState: resetInitialState,\n state: {\n sorting,\n columnFilters,\n globalFilter,\n pagination,\n rowSelection,\n expanded,\n columnVisibility,\n columnPinning: mergedColumnPinning,\n columnOrder,\n columnSizing,\n grouping,\n rowPinning\n },\n onSortingChange: setSorting,\n onColumnFiltersChange: setColumnFilters,\n onGlobalFilterChange: setNormalizedGlobalFilter,\n onPaginationChange: setPagination,\n onRowSelectionChange: setRowSelection,\n onExpandedChange: setExpanded,\n onColumnVisibilityChange: setColumnVisibility,\n onColumnPinningChange: setColumnPinning,\n onColumnOrderChange: setColumnOrder,\n onColumnSizingChange: setColumnSizing,\n onGroupingChange: setGrouping,\n onRowPinningChange: setRowPinning,\n enableSorting,\n enableMultiSort,\n enableSortingRemoval,\n enableColumnFilters,\n enableGlobalFilter,\n enableRowSelection,\n enableMultiRowSelection,\n enableColumnPinning,\n enableHiding,\n enableGrouping,\n enableRowPinning,\n enableCellSpanning,\n enableExpanding: withExpander || enableGrouping,\n ...getSubRows && { getSubRows },\n ...renderDetailPanel && { getRowCanExpand: () => true },\n manualSorting,\n manualFiltering,\n manualPagination: bypassPaginatedRowModel,\n ...serverPagination && rowCount !== undefined && { rowCount },\n ...serverPagination && {\n // `autoResetAll` outranks `autoResetPageIndex` inside TanStack. Consume it here so the\n // deterministic server reset remains authoritative, while preserving its only other\n // upstream effects through the feature-specific options.\n autoResetAll: undefined,\n autoResetExpanded: tableOptions?.autoResetAll ?? tableOptions?.autoResetExpanded,\n autoResetSorting: tableOptions?.autoResetAll ?? tableOptions?.autoResetSorting,\n autoResetPageIndex: false\n },\n meta: { ...tableOptions?.meta, ledger }\n } satisfies Partial<TableOptions<LedgerFeatures, TData>>;\n\n if (isDev && tableOptions) {\n for (const key of Object.keys(tableOptions)) {\n const isConsumedPaginationPolicy = serverPagination\n && (key === \"autoResetAll\" || key === \"autoResetExpanded\" || key === \"autoResetSorting\" || key === \"autoResetPageIndex\");\n\n if (key !== \"meta\" && !isConsumedPaginationPolicy && Object.hasOwn(managed, key)) {\n warnOnce(\n `tableOptions.${key}`,\n `tableOptions.${key} is managed by ledger and has been overridden — use the first-class option instead.`\n );\n }\n }\n }\n\n const table = useTable<LedgerFeatures, TData>({ ...tableOptions, ...managed } as TableOptions<LedgerFeatures, TData>);\n\n /**\n * What the editing paths and the row commands answer from. v9's `useTable` returns a fresh\n * wrapper whenever options or state change — `useMemo(() => ({ ...table, options, state }))` —\n * so neither that wrapper nor the shared core beneath it can be read at event time: a\n * transition React renders and then throws away leaves the core holding options nothing on\n * screen is using, and a commit would then be gated by an `enableEditing` the user never saw.\n *\n * Taken in the insertion phase, which is the commit — a render React throws away never reaches\n * one, so it never gets to say what the editing paths saw — and before every layout effect, so\n * a session boundary or an editor registration already sees this render's answers.\n */\n useInsertionEffect(() => {\n captureCommitted(table, {\n enableEditing,\n hasCommitHandler: Boolean(editMode === \"row\" ? onRowEditCommit : onEditCommit)\n });\n captureRows(table);\n });\n\n usePersistWriter(persistState, {\n sorting,\n columnFilters,\n globalFilter,\n pagination,\n columnVisibility,\n columnPinning,\n columnOrder,\n columnSizing,\n grouping\n });\n\n return table;\n}\n","import type { GetStylesApi } from \"@mantine/core\";\n\nimport type { DataTableFactory } from \"./data-table\";\n\n/**\n * Keeps one identity for the Styles API for as long as it resolves the same answers.\n *\n * Mantine's `useStyles` re-resolves theme, `classNames`, `styles`, `vars`, `attributes` and the\n * props those read on every render, and returns a fresh getter each time. Neither obvious thing to\n * do with that getter works: handing it to a context rebuilds the context value on every render, so\n * nothing below stays memoized; pinning it behind a ref keeps the identity but freezes the answers,\n * so a real `styles.row` change never reaches a memoized row — and writing that ref during render\n * lets a transition React throws away restyle the tree on screen.\n *\n * The way out is to compare what the getter *resolves* rather than the getter itself. Two getters\n * that answer identically for every selector are interchangeable, so the committed one is kept and\n * nothing below re-renders. The moment an answer differs, this render's getter is returned, and\n * because it goes into a context value that identity change reaches even a `React.memo`ed row.\n *\n * The comparison covers each selector's `className`, `style` and attributes, plus the provenance a\n * per-call option is resolved against — `getStyles(selector, { style })` merges that style through\n * `resolveStyle(style, theme)`, which the answers alone would not reveal (docs/styling.md).\n *\n * Committed in an insertion effect, never during render: a render React discards must not be able\n * to say what the tree on screen is styled with.\n */\nimport {\n useMantineClassNamesPrefix,\n useMantineIsHeadless,\n useMantineStylesTransform,\n useMantineTheme,\n useMantineWithStaticClasses\n} from \"@mantine/core\";\nimport { useInsertionEffect, useRef } from \"react\";\n\ntype Styles = GetStylesApi<DataTableFactory>;\n\ntype Selector = Parameters<Styles>[0];\n\n/**\n * One selector's resolved props: whatever `attributes` put there, plus `className` and `style`.\n */\ntype Answer = Record<string, unknown>;\n\ntype Answers = Partial<Record<Selector, Answer>>;\n\n/**\n * Own string keys, compared by identity. Never serialized: `attributes` carries whatever the\n * application put in it — event handlers, objects that refer to themselves — and writing answers\n * down as text would silently drop a replaced handler and throw on the rest.\n */\nfunction sameShallow(previous: unknown, next: unknown): boolean {\n if (Object.is(previous, next)) {\n return true;\n }\n\n if (typeof previous !== \"object\" || typeof next !== \"object\" || previous === null || next === null) {\n return false;\n }\n\n const previousKeys = Object.keys(previous);\n\n if (previousKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n return previousKeys.every(key => Object.hasOwn(next, key) && Object.is((previous as Answer)[key], (next as Answer)[key]));\n}\n\nfunction sameAnswer(previous: Answer, next: Answer): boolean {\n const previousKeys = Object.keys(previous);\n\n if (previousKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n return previousKeys.every(key => {\n if (!Object.hasOwn(next, key)) {\n return false;\n }\n\n // Mantine builds a fresh `style` object on every render, so identity says nothing there; one\n // level of its own keys does. Everything else is compared by identity, which is what makes a\n // replaced handler a real change — and what makes an object-valued attribute conservatively\n // count as one.\n return key === \"style\"\n ? sameShallow(previous[key], next[key])\n : Object.is(previous[key], next[key]);\n });\n}\n\nfunction resolveAnswers(getStyles: Styles, selectors: readonly Selector[]): Answers {\n const answers: Answers = {};\n\n for (const selector of selectors) {\n answers[selector] = getStyles(selector) as Answer;\n }\n\n return answers;\n}\n\nfunction sameAnswers(previous: Answers, next: Answers, selectors: readonly Selector[]): boolean {\n return selectors.every(selector => {\n const before = previous[selector];\n const after = next[selector];\n\n return before !== undefined && after !== undefined && sameAnswer(before, after);\n });\n}\n\nexport function useStylesRevision(getStyles: Styles, selectors: readonly Selector[]): Styles {\n // The inputs the returned getter closes over that its own answers do not expose: a per-call\n // `options.style` is resolved against the theme, and the rest decide how class names are built.\n const provenance = [\n useMantineTheme(),\n useMantineClassNamesPrefix(),\n useMantineWithStaticClasses(),\n useMantineIsHeadless(),\n useMantineStylesTransform()\n ];\n const answers = resolveAnswers(getStyles, selectors);\n const committed = useRef<{ answers: Answers; provenance: unknown[]; getStyles: Styles }>({\n answers,\n getStyles,\n provenance\n });\n\n const unchanged\n = committed.current.provenance.every((value, index) => Object.is(value, provenance[index]))\n && sameAnswers(committed.current.answers, answers, selectors);\n const revision = unchanged ? committed.current.getStyles : getStyles;\n\n useInsertionEffect(() => {\n committed.current = {\n answers,\n getStyles: revision,\n provenance\n };\n });\n\n return revision;\n}\n","import type {\n BoxProps,\n ElementProps,\n Factory,\n MantineColor,\n MantineSpacing,\n StylesApiProps,\n TableTrProps\n} from \"@mantine/core\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport type { Virtualizer } from \"@tanstack/react-virtual\";\nimport type { ComponentProps, JSX, MouseEvent, KeyboardEvent as ReactKeyboardEvent, ReactNode, Ref } from \"react\";\n\nimport type { DataTableContextValue } from \"./context\";\nimport type { DataAttributes, DataTableElementProps } from \"./element-props\";\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { VirtualizationConfig } from \"./table-body\";\nimport type {\n Column,\n DataTableHandle,\n DataTableScrollOptions,\n HeaderGroup,\n Row,\n TableInstance,\n UseDataTableOptions\n} from \"./types\";\nimport type { ColumnWindowView } from \"./use-column-window\";\n\n/**\n * The root component (docs/api.md): a generic Mantine factory with full Styles API,\n * adaptive sizing (the root is a flex column that fills its parent; the ScrollArea is the only\n * elastic region), CSS-variable column geometry, infinite loading, pinned-edge shadows, the\n * built-in pagination bar, and the imperative handle.\n *\n * Sugar mode (`data`/`columns` inline) and hook mode (`table`) render through the same core;\n * the split components below keep the hook call unconditional.\n */\nimport {\n Box,\n Button,\n createVarsResolver,\n EmptyState,\n genericFactory,\n getThemeColor,\n LoadingOverlay,\n Table as MantineTable,\n ScrollArea,\n useProps,\n useStyles,\n VisuallyHidden\n} from \"@mantine/core\";\nimport { useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from \"react\";\n\nimport { isInternalColumn } from \"./build-columns\";\nimport { DataTableColumnsPanel } from \"./columns-panel\";\nimport { DataTableProvider } from \"./context\";\nimport { mergeElementProps } from \"./element-props\";\nimport { warnOnce } from \"./env\";\nimport { resolveIcons } from \"./icons\";\nimport { resolveLabels } from \"./labels\";\nimport { ledgerCommands } from \"./ledger-commands\";\nimport { DataTablePagination, DEFAULT_PAGE_SIZE_OPTIONS, PaginationBar } from \"./pagination-bar\";\nimport { RowReorderScope, useRowReorder } from \"./row-reorder\";\nimport { DataTableSearch } from \"./search\";\nimport { DataTableSelectionBar } from \"./selection-bar\";\nimport { buildDisplayRows, countDisplayRows, TableBody } from \"./table-body\";\nimport { TableFooter, tableHasFooter, visibleFooterGroups } from \"./table-footer\";\nimport { TableHeader } from \"./table-header\";\nimport { useColumnWidths } from \"./use-column-widths\";\nimport { DEFAULT_COLUMN_OVERSCAN, useColumnWindow } from \"./use-column-window\";\nimport { useDataTable } from \"./use-data-table\";\nimport { useStylesRevision } from \"./use-styles-revision\";\nimport { columnAfterVar, columnStartVar, columnWidthVar, toPx, useEventCallback } from \"./utils\";\n\n// ------------------------------------------------------------------------------------------------\n// Styles API surface\n// ----------------------------------------------------------------------------------------------\n\nexport type DataTableStylesNames\n = | \"root\"\n | \"main\"\n | \"header\"\n | \"scroller\"\n | \"footer\"\n | \"table\"\n | \"thead\"\n | \"tbody\"\n | \"tfoot\"\n | \"headerRow\"\n | \"headerCell\"\n | \"headerLabel\"\n | \"headerActions\"\n | \"sortIndicator\"\n | \"resizer\"\n | \"filterPopover\"\n | \"row\"\n | \"cell\"\n | \"selectionCell\"\n | \"expanderCell\"\n | \"detailPanel\"\n | \"cellEditor\"\n | \"instantCell\"\n | \"instantSpinner\"\n | \"rowDragCell\"\n | \"rowDragOverlay\"\n | \"footerRow\"\n | \"footerCell\"\n | \"empty\"\n | \"loaderRow\"\n | \"loaderRowContent\"\n | \"paginationBar\";\n\nexport interface DataTableCssVariables {\n root: \"--ledger-striped-color\" | \"--ledger-hover-color\" | \"--ledger-border-color\";\n}\n\n/**\n * Static kebab-case classes — the styling contract's public selector map (docs/styling.md).\n */\nconst classes: Record<DataTableStylesNames, string> = {\n root: \"ledger-root\",\n main: \"ledger-main\",\n header: \"ledger-header\",\n scroller: \"ledger-scroller\",\n footer: \"ledger-footer\",\n table: \"ledger-table\",\n thead: \"ledger-thead\",\n tbody: \"ledger-tbody\",\n tfoot: \"ledger-tfoot\",\n headerRow: \"ledger-header-row\",\n headerCell: \"ledger-header-cell\",\n headerLabel: \"ledger-header-label\",\n headerActions: \"ledger-header-actions\",\n sortIndicator: \"ledger-sort-indicator\",\n resizer: \"ledger-resizer\",\n filterPopover: \"ledger-filter-popover\",\n row: \"ledger-row\",\n cell: \"ledger-cell\",\n selectionCell: \"ledger-selection-cell\",\n expanderCell: \"ledger-expander-cell\",\n detailPanel: \"ledger-detail-panel\",\n cellEditor: \"ledger-cell-editor\",\n instantCell: \"ledger-instant-cell\",\n instantSpinner: \"ledger-instant-spinner\",\n rowDragCell: \"ledger-row-drag-cell\",\n rowDragOverlay: \"ledger-row-drag-overlay\",\n footerRow: \"ledger-footer-row\",\n footerCell: \"ledger-footer-cell\",\n empty: \"ledger-empty\",\n loaderRow: \"ledger-loader-row\",\n loaderRowContent: \"ledger-loader-row-content\",\n paginationBar: \"ledger-pagination-bar\"\n};\n\n/**\n * Every selector the Styles API answers for — the comparison set behind the style revision\n * (`use-styles-revision.ts`). Constant, so the cost is per render and never per row.\n */\nconst STYLE_SELECTORS = Object.keys(classes) as DataTableStylesNames[];\n\n/**\n * Stable identity for an unoccupied pinned zone — a fresh `[]` would re-run the announcement.\n */\nconst NO_ARIA_ROWS: never[] = [];\n\n// Mantine styles the EmptyState title as a headline (bright, 600) for full-page empties with\n// description and actions; a bare table caption reads better dimmed.\nconst EMPTY_STATE_STYLES = {\n title: { color: \"var(--mantine-color-dimmed)\", fontWeight: 500 }\n} as const;\n\n// ------------------------------------------------------------------------------------------------\n// Props\n// ----------------------------------------------------------------------------------------------\n\nexport interface DataTableBaseProps<TData extends RowData>\n extends BoxProps,\n StylesApiProps<DataTableFactory>,\n ElementProps<\"div\"> {\n /**\n * Root element ref (React 19 ref-as-prop; genericFactory components receive it here).\n */\n ref?: Ref<HTMLDivElement>;\n\n // Mantine Table appearance (forwarded names; striped/hover are rendered by ledger itself\n // through the --ledger-row-bg pipeline so pinned cells always cover them)\n striped?: boolean | \"odd\" | \"even\";\n stripedColor?: MantineColor;\n highlightOnHover?: boolean;\n highlightOnHoverColor?: MantineColor;\n withTableBorder?: boolean;\n withColumnBorders?: boolean;\n withRowBorders?: boolean;\n borderColor?: MantineColor;\n verticalSpacing?: MantineSpacing;\n horizontalSpacing?: MantineSpacing;\n tabularNums?: boolean;\n\n /* Layout */\n tableMinWidth?: number | string;\n\n /* Scale */\n /**\n * Row virtualization ([virtualization.md](../docs/virtualization.md)): the body renders a\n * measured window of rows between two spacer rows.\n */\n virtualizedRows?: boolean | { estimateHeight?: number; overscan?: number };\n /**\n * Column virtualization ([virtualization.md](../docs/virtualization.md#column-virtualization)):\n * the center zone renders a windowed slice of columns between two spacer cols; pinned columns\n * stay mounted. Widths are the width engine's exact pixels, so there is nothing to estimate.\n */\n virtualizedColumns?: boolean | { overscan?: number };\n onEndReached?: () => void;\n endReachedOffset?: number;\n loadingMore?: boolean;\n /**\n * The last `onEndReached` load failed — replaces the trailing loader row with the message\n * (`true` uses `labels.loadMoreError`) and a retry button that fires `onEndReached` again.\n */\n loadMoreError?: boolean | ReactNode;\n\n /* State presentation */\n loading?: boolean;\n emptyState?: ReactNode;\n /**\n * Loading the data failed — shows an error panel over the body (`true` uses `labels.error`;\n * a node replaces the message). Takes precedence over the empty state.\n */\n error?: boolean | ReactNode;\n /**\n * Renders a retry button in the error panel.\n */\n onRetry?: () => void;\n\n /* Chrome */\n /**\n * Renders the column header region. Turning it off takes the header's own affordances with\n * it — sort controls, filter popovers, resize handles, drag reordering — so name the table\n * some other way ([accessibility.md](../docs/accessibility.md)).\n */\n withColumnHeaders?: boolean;\n withPaginationBar?: boolean;\n pageSizeOptions?: number[];\n\n /* Row interaction */\n /**\n * A literal primary click on the row. Pointer-only by definition — reach for `onRowActivate`\n * when the intent is \"the user chose this row\", so the keyboard reaches it too.\n */\n onRowClick?: (row: Row<TData>, event: MouseEvent) => void;\n /**\n * The row was activated, whatever the input device: a primary click, or `Enter` on the\n * current row while `enableActiveRow` is on ([rows.md](../docs/rows.md#active-row)).\n */\n onRowActivate?: (row: Row<TData>, event: MouseEvent | ReactKeyboardEvent) => void;\n onRowDoubleClick?: (row: Row<TData>, event: MouseEvent) => void;\n onRowContextMenu?: (row: Row<TData>, event: MouseEvent) => void;\n\n /* DOM escape hatches (docs/styling.md#dom-props) */\n /**\n * DOM props for every data row — static, or per row. Synthetic rows (detail panels, loader\n * and skeleton rows) have no `Row` subject and never receive them.\n */\n rowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, Row<TData>>;\n /**\n * DOM props for every header row — static, or per header group (grouped columns render one\n * row per level).\n */\n headerRowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, HeaderGroup<TData>>;\n /**\n * DOM props for every footer row — static, or per footer group.\n */\n footerRowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, HeaderGroup<TData>>;\n /**\n * DOM props for the internal scroll viewport — `onScroll`, `data-*`, extra styles. Host\n * vocabulary: `ScrollArea.viewportProps`. ledger owns its scroll listener, its overscroll\n * behavior and (with `enableActiveRow`) its keyboard handling; those compose rather than\n * being replaced.\n */\n viewportProps?: Omit<ComponentProps<\"div\">, \"ref\"> & DataAttributes;\n\n labels?: Partial<DataTableLabels>;\n\n /**\n * Replacements for the chrome's glyphs, merged over the defaults per slot — `lucide-react`\n * components slot in as-is (docs/styling.md#icons).\n */\n icons?: Partial<DataTableIcons>;\n\n /**\n * Imperative handle: `{ table, viewport, scrollToRow, scrollToIndex, scrollToColumn, startEditing, stopEditing }`.\n */\n handleRef?: Ref<DataTableHandle<TData>>;\n}\n\n/**\n * Data source — a discriminated pair: a hook-mode instance XOR inline behavior options.\n */\nexport type DataTableProps<TData extends RowData = RowData> = DataTableBaseProps<TData>\n & (\n | ({ table: TableInstance<TData> } & { data?: never; columns?: never })\n | ({ table?: never } & UseDataTableOptions<TData>)\n );\n\nexport type DataTableFactory = Factory<{\n props: DataTableProps;\n ref: HTMLDivElement;\n stylesNames: DataTableStylesNames;\n vars: DataTableCssVariables;\n signature: <TData extends RowData>(props: DataTableProps<TData>) => JSX.Element;\n staticComponents: {\n Search: typeof DataTableSearch;\n ColumnsPanel: typeof DataTableColumnsPanel;\n Pagination: typeof DataTablePagination;\n SelectionBar: typeof DataTableSelectionBar;\n };\n}>;\n\nconst defaultProps = {\n striped: false,\n highlightOnHover: false,\n withTableBorder: false,\n withColumnBorders: false,\n withRowBorders: true,\n verticalSpacing: \"xs\",\n horizontalSpacing: \"xs\",\n tabularNums: false,\n virtualizedRows: false,\n virtualizedColumns: false,\n endReachedOffset: 240,\n loadingMore: false,\n loading: false,\n withColumnHeaders: true,\n withPaginationBar: true,\n pageSizeOptions: DEFAULT_PAGE_SIZE_OPTIONS\n} satisfies Partial<DataTableProps>;\n\nfunction leafCol(column: { id: string }) {\n return <col key={column.id} style={{ width: `var(${columnWidthVar(column.id)})` }} />;\n}\n\nconst varsResolver = createVarsResolver<DataTableFactory>(\n (theme, {\n stripedColor,\n highlightOnHoverColor,\n borderColor\n }) => {\n return {\n root: {\n \"--ledger-striped-color\": stripedColor ? getThemeColor(stripedColor, theme) : undefined,\n \"--ledger-hover-color\": highlightOnHoverColor\n ? getThemeColor(highlightOnHoverColor, theme)\n : undefined,\n // The frame border around header + body lives outside both tables (docs/styling.md).\n \"--ledger-border-color\": borderColor ? getThemeColor(borderColor, theme) : undefined\n }\n };\n }\n);\n\n// ------------------------------------------------------------------------------------------------\n// Option-key partition — sugar mode splits behavior options from presentation props\n// ----------------------------------------------------------------------------------------------\n\nconst OPTION_KEYS = [\n \"data\",\n \"columns\",\n \"getRowId\",\n \"enableSorting\",\n \"enableMultiSort\",\n \"enableSortingRemoval\",\n \"enableColumnFilters\",\n \"enableGlobalFilter\",\n \"enablePagination\",\n \"enableRowSelection\",\n \"enableMultiRowSelection\",\n \"enableColumnResizing\",\n \"enableColumnPinning\",\n \"enableColumnOrdering\",\n \"enableHiding\",\n \"enableEditing\",\n \"enableGrouping\",\n \"enableRowPinning\",\n \"enableCellSpanning\",\n \"getSubRows\",\n \"renderDetailPanel\",\n \"selectionColumn\",\n \"expanderColumn\",\n \"enableRowOrdering\",\n \"onRowReorder\",\n \"rowDragColumn\",\n \"sortingMode\",\n \"filterMode\",\n \"paginationMode\",\n \"rowCount\",\n \"editTrigger\",\n \"editMode\",\n \"onEditCommit\",\n \"onRowEditCommit\",\n \"editingRowId\",\n \"onEditingRowIdChange\",\n \"enableActiveRow\",\n \"activeRowId\",\n \"defaultActiveRowId\",\n \"onActiveRowIdChange\",\n \"sorting\",\n \"defaultSorting\",\n \"onSortingChange\",\n \"columnFilters\",\n \"defaultColumnFilters\",\n \"onColumnFiltersChange\",\n \"globalFilter\",\n \"defaultGlobalFilter\",\n \"onGlobalFilterChange\",\n \"pagination\",\n \"defaultPagination\",\n \"onPaginationChange\",\n \"rowSelection\",\n \"defaultRowSelection\",\n \"onRowSelectionChange\",\n \"expanded\",\n \"defaultExpanded\",\n \"onExpandedChange\",\n \"columnVisibility\",\n \"defaultColumnVisibility\",\n \"onColumnVisibilityChange\",\n \"columnPinning\",\n \"defaultColumnPinning\",\n \"onColumnPinningChange\",\n \"columnOrder\",\n \"defaultColumnOrder\",\n \"onColumnOrderChange\",\n \"columnSizing\",\n \"defaultColumnSizing\",\n \"onColumnSizingChange\",\n \"grouping\",\n \"defaultGrouping\",\n \"onGroupingChange\",\n \"rowPinning\",\n \"defaultRowPinning\",\n \"onRowPinningChange\",\n \"editingCell\",\n \"onEditingCellChange\",\n \"persistState\",\n \"defaultColumn\",\n \"filterFns\",\n \"tableOptions\"\n] as const satisfies ReadonlyArray<keyof UseDataTableOptions<RowData>>;\n\n/**\n * Compile-time exhaustiveness: adding an option without listing it above is a type error.\n */\ntype MissingOptionKeys = Exclude<keyof UseDataTableOptions<RowData>, (typeof OPTION_KEYS)[number]>;\n\ntype AssertNever<T extends never> = T;\n\n// AssertNever<MissingOptionKeys> is `never` while the list is exhaustive; a forgotten key turns\n// it into a constraint violation right here.\nconst OPTION_KEY_SET: ReadonlySet<string> = new Set<AssertNever<MissingOptionKeys> | string>(OPTION_KEYS);\n\n// ------------------------------------------------------------------------------------------------\n// Component\n// ----------------------------------------------------------------------------------------------\n\nfunction DataTableRoot<TData extends RowData>(_props: DataTableProps<TData>) {\n const props = useProps(\"DataTable\", defaultProps as Partial<DataTableProps<TData>>, _props);\n\n if (props.table) {\n const { table, ...presentation } = props;\n\n return (\n <DataTableCore\n presentation={presentation as DataTableBaseProps<TData>}\n stylesProps={props}\n table={table}\n />\n );\n }\n\n return <DataTableFromOptions props={props} />;\n}\n\nexport const DataTable = genericFactory<DataTableFactory>(DataTableRoot);\n\ninterface RoutedProps<TData extends RowData> {\n presentation: DataTableBaseProps<TData>;\n /**\n * Everything the component was given, after `useProps`. The Styles API's callbacks are typed\n * with the component's whole props and Mantine hands them exactly that — so the behaviour half,\n * which the partition below routes to `useDataTable` and keeps off the DOM, still has to reach\n * `useStyles`. Only the DOM partition is `presentation`.\n */\n stylesProps: DataTableProps<TData>;\n table: TableInstance<TData>;\n}\n\n/**\n * The rows and the naming column of one committed render, in the shape the handlers that answer\n * for the screen need them (docs/architecture.md).\n */\nexport interface DisplaySnapshot<TData extends RowData> {\n /**\n * Every row on screen, in display order — pinned top, the page, pinned bottom. What the\n * keyboard steps through and what the announcement counts.\n */\n ordered: Array<Row<TData>>;\n /**\n * The unpinned zone alone, which is what the virtualizer indexes.\n */\n centerRows: Array<Row<TData>>;\n topRows: Array<Row<TData>>;\n bottomRows: Array<Row<TData>>;\n /**\n * The page's own row model — what `scrollToIndex` counts through.\n */\n pageRows: Array<Row<TData>>;\n /**\n * The leading data column, whose accessor names a row for the announcement.\n */\n leadingColumn: Column<TData, unknown> | null;\n /**\n * Detail panels are on, so an expanded row owns a synthetic display item of its own.\n */\n withDetailPanels: boolean;\n}\n\n/**\n * Resolve a row against the exact list owned by the virtualizer. Pinned rows are mounted outside\n * that list, so they deliberately have no scroll index.\n */\nexport function resolveVirtualDisplayIndex<TData extends RowData>(\n snapshot: DisplaySnapshot<TData>,\n rowId: string\n): number | null {\n const pinned = [...snapshot.topRows, ...snapshot.bottomRows].some(row => row.id === rowId);\n\n if (pinned) {\n return null;\n }\n\n const index = buildDisplayRows(snapshot.centerRows, snapshot.withDetailPanels)\n .findIndex(displayRow => displayRow.kind === \"data\" && displayRow.row.id === rowId);\n\n return index === -1 ? null : index;\n}\n\nfunction DataTableFromOptions<TData extends RowData>({ props }: { props: DataTableProps<TData> }) {\n const options: Record<string, unknown> = {};\n const presentation: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n (OPTION_KEY_SET.has(key) ? options : presentation)[key] = value;\n }\n\n // The partition is exhaustive by construction (see the AssertNever check above).\n const table = useDataTable(options as unknown as UseDataTableOptions<TData>);\n\n return (\n <DataTableCore\n presentation={presentation as DataTableBaseProps<TData>}\n stylesProps={props}\n table={table}\n />\n );\n}\n\nfunction DataTableCore<TData extends RowData>({\n presentation,\n stylesProps,\n table\n}: RoutedProps<TData>) {\n const {\n striped,\n // Consumed by varsResolver from raw props; destructured only to keep them off the DOM node.\n stripedColor: _stripedColor,\n highlightOnHover,\n highlightOnHoverColor: _highlightOnHoverColor,\n withTableBorder,\n withColumnBorders,\n withRowBorders,\n borderColor: _borderColor,\n verticalSpacing,\n horizontalSpacing,\n tabularNums,\n tableMinWidth,\n virtualizedRows,\n virtualizedColumns,\n onEndReached,\n endReachedOffset,\n loadingMore,\n loadMoreError,\n loading,\n emptyState,\n error,\n onRetry,\n withColumnHeaders,\n withPaginationBar,\n pageSizeOptions,\n onRowClick,\n onRowActivate,\n onRowDoubleClick,\n onRowContextMenu,\n rowProps,\n headerRowProps,\n footerRowProps,\n viewportProps,\n labels: labelsProp,\n icons: iconsProp,\n handleRef,\n ref: rootRef,\n classNames,\n styles,\n unstyled,\n vars,\n className,\n style,\n attributes,\n // The ARIA table is `main`, not the root — a name left on the root would describe a\n // roleless wrapper and never reach the table. Routed below, never duplicated.\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n ...others\n } = presentation;\n\n const getStyles = useStyles<DataTableFactory>({\n name: \"DataTable\",\n classes,\n props: stylesProps as DataTableProps,\n className,\n style,\n classNames,\n styles,\n unstyled,\n vars,\n attributes,\n varsResolver\n });\n\n /**\n * The Styles API, revised rather than mirrored.\n *\n * `useStyles` resolves theme, `classNames`, `styles`, `vars`, `attributes` and the props they\n * read on every render, and hands back a **new** getter each time. Putting that getter straight\n * into the context would rebuild the context value every render and leave nothing in the body\n * memoized; freezing it behind a ref instead — which this used to do — meant a real change never\n * reached the rows at all, and made the ref a render-phase write a discarded transition could\n * poison.\n *\n * So the getter is compared by what it *resolves*: every selector's className, style and\n * attributes, plus the provenance a per-call `options.style` is resolved against (this table\n * passes no other per-call option, and Mantine resolves that one through the theme alone).\n * Same answers, same getter — the rows never hear about it. Different answers, and this render's\n * getter becomes the context value, which is a context change and therefore reaches even a\n * memoized row. `Object.keys(classes)` is a constant 25-odd selectors, so the cost is per render,\n * never per row.\n */\n const stylesRevision = useStylesRevision(getStyles, STYLE_SELECTORS);\n\n const labels = useMemo(() => resolveLabels(labelsProp), [labelsProp]);\n const icons = useMemo(() => resolveIcons(iconsProp), [iconsProp]);\n\n /* ---- viewport ---- */\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const [viewport, setViewport] = useState<HTMLDivElement | null>(null);\n const assignViewport = useCallback((element: HTMLDivElement | null) => {\n viewportRef.current = element;\n setViewport(element);\n }, []);\n\n // ---- the width engine (docs/sizing.md) ----\n // Display order is pinned-aware (start + center + end) — header groups and row cells\n // already render in it, so the colgroup and every width/offset must follow the same order\n // (`getVisibleLeafColumns` alone ignores pinning). Stabilized by id signature so downstream\n // memos only recompute when the composition or order actually changes.\n const startLeafColumns = table.getStartVisibleLeafColumns();\n const endLeafColumns = table.getEndVisibleLeafColumns();\n const displayColumns = [\n ...startLeafColumns,\n ...table.getCenterVisibleLeafColumns(),\n ...endLeafColumns\n ];\n // Fresh numbers, never memoized off the signature: pinning the current first column changes\n // neither order nor composition, yet moves the zone boundary.\n const pinnedStartCount = startLeafColumns.length;\n const pinnedEndCount = endLeafColumns.length;\n const displayOrderSignature = JSON.stringify(displayColumns.map(column => column.id));\n const ledgerColumns = table.options.meta?.ledger?.columns;\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- the signature encodes order/composition; meta.ledger.columns identity covers definition swaps (options.columns re-resolves per v9 state tick)\n const visibleLeafColumns = useMemo(() => displayColumns, [displayOrderSignature, ledgerColumns]);\n const columnWidths = useColumnWidths(table, visibleLeafColumns, viewport, tableMinWidth);\n\n /* ---- virtualization config ---- */\n const virtualization: VirtualizationConfig | null = virtualizedRows\n ? {\n estimateHeight:\n typeof virtualizedRows === \"object\" && virtualizedRows.estimateHeight !== undefined\n ? virtualizedRows.estimateHeight\n : 44,\n overscan: typeof virtualizedRows === \"object\" && virtualizedRows.overscan !== undefined\n ? virtualizedRows.overscan\n : 8\n }\n : null;\n const virtualEnabled = virtualization !== null;\n\n /* ---- column window (docs/virtualization.md#column-virtualization) ---- */\n const columnVirtualizationEnabled = virtualizedColumns === true || typeof virtualizedColumns === \"object\";\n const centerColumnIds = useMemo(\n () => visibleLeafColumns\n .slice(pinnedStartCount, visibleLeafColumns.length - pinnedEndCount)\n .map(column => column.id),\n [visibleLeafColumns, pinnedStartCount, pinnedEndCount]\n );\n let pinnedStartWidth = 0;\n let pinnedEndWidth = 0;\n\n for (const [index, column] of visibleLeafColumns.entries()) {\n if (index < pinnedStartCount) {\n pinnedStartWidth += columnWidths.byId[column.id] ?? 0;\n } else if (index >= visibleLeafColumns.length - pinnedEndCount) {\n pinnedEndWidth += columnWidths.byId[column.id] ?? 0;\n }\n }\n\n const columnWindowRange = useColumnWindow({\n centerColumnIds,\n enabled: columnVirtualizationEnabled,\n overscan: typeof virtualizedColumns === \"object\" && virtualizedColumns.overscan !== undefined\n ? virtualizedColumns.overscan\n : DEFAULT_COLUMN_OVERSCAN,\n pinnedEndWidth,\n pinnedStartWidth,\n viewport,\n widths: columnWidths.byId\n });\n const displayIndexById = useMemo(\n () => new Map(visibleLeafColumns.map((column, index) => [column.id, index])),\n [visibleLeafColumns]\n );\n const columnWindow = useMemo<ColumnWindowView | null>(\n () => columnWindowRange && {\n ...columnWindowRange,\n centerCount: centerColumnIds.length,\n displayIndexById,\n pinnedEndCount,\n pinnedStartCount,\n totalLeafCount: visibleLeafColumns.length\n },\n [columnWindowRange, centerColumnIds.length, displayIndexById, pinnedEndCount, pinnedStartCount, visibleLeafColumns.length]\n );\n\n /* ---- row interaction handlers with stable identities ---- */\n const rowClickStable = useEventCallback(onRowClick);\n const rowActivateStable = useEventCallback(onRowActivate);\n const rowDoubleClickStable = useEventCallback(onRowDoubleClick);\n const rowContextMenuStable = useEventCallback(onRowContextMenu);\n\n // The context depends on each handler's EXISTENCE, never its identity — the stable wrappers\n // absorb per-render inline arrows, so a fresh `onRowClick` prop must not rebuild the context\n // value (and with it every memoized row). The `*Props` hooks stay raw below: their return\n // values feed the render, so identity is their honest dependency.\n const contextRowClick = onRowClick ? (rowClickStable as DataTableContextValue[\"onRowClick\"]) : undefined;\n const contextRowActivate = onRowActivate\n ? (rowActivateStable as DataTableContextValue[\"onRowActivate\"])\n : undefined;\n const contextRowDoubleClick = onRowDoubleClick\n ? (rowDoubleClickStable as DataTableContextValue[\"onRowDoubleClick\"])\n : undefined;\n const contextRowContextMenu = onRowContextMenu\n ? (rowContextMenuStable as DataTableContextValue[\"onRowContextMenu\"])\n : undefined;\n\n // Normalized once: the prop defaults to true, so an absent value must not read as \"off\" at\n // any of its three use sites (the context, the ARIA row numbering, the render).\n const columnHeadersVisible = withColumnHeaders !== false;\n\n const filterMode: \"client\" | \"server\" = table.options.manualFiltering ? \"server\" : \"client\";\n\n /* The documented single TData erasure (context.ts) — the render layer below is `any`-bound. */\n const erasedTable = table as TableInstance<any>;\n\n // Read from THIS render's wrapper, whose `options` is its own object — never from the shared\n // core, and never mirrored into a ref during render. Each of these is stable for as long as\n // the instance lives, so naming them individually is what lets the context value hold while\n // the wrapper identity changes on every state tick (context.ts).\n const ledger = table.options.meta?.ledger;\n const editing = ledger?.editing;\n const activeRowEnabled = ledger?.activeRow.enabled === true;\n const activeRowId = ledger?.activeRow.id ?? null;\n const setActiveRow = ledger?.activeRow.set;\n const subscribeColumnFilters = ledger?.filtering.subscribeColumnFilters;\n const commands = ledgerCommands(ledger);\n const selectionCommands = commands?.selection;\n const expansionCommands = commands?.expansion;\n\n const instanceId = useId();\n\n // ---- column geometry: the width engine resolves every column to exact integer pixels,\n // written as CSS variables (a resize updates variables, never re-renders rows) ----\n const tableState = table.state;\n\n const columnVars = useMemo(() => {\n const varsMap: Record<string, string> = {};\n let leftOffset = 0;\n\n for (const column of visibleLeafColumns) {\n const width = columnWidths.byId[column.id] ?? 0;\n varsMap[columnWidthVar(column.id)] = `${width}px`;\n\n if (column.getIsPinned() === \"start\") {\n varsMap[columnStartVar(column.id)] = `${leftOffset}px`;\n leftOffset += width;\n }\n }\n\n let rightOffset = 0;\n\n for (let index = visibleLeafColumns.length - 1; index >= 0; index -= 1) {\n const column = visibleLeafColumns[index]!;\n\n if (column.getIsPinned() === \"end\") {\n varsMap[columnAfterVar(column.id)] = `${rightOffset}px`;\n rightOffset += columnWidths.byId[column.id] ?? 0;\n }\n }\n\n return varsMap;\n // getIsPinned reads the pinning slice — columnPinning is its identity in the deps.\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- see comment above\n }, [visibleLeafColumns, columnWidths, tableState.columnPinning]);\n\n // The one colgroup all three synced tables share. Under a column window the hidden center\n // runs collapse into two spacer cols with the exact widths the missing columns add up to, so\n // the table keeps its full scroll width and the pinned offsets stay honest.\n const colElements = columnWindow === null\n ? visibleLeafColumns.map(column => leafCol(column))\n : [\n ...visibleLeafColumns.slice(0, pinnedStartCount).map(column => leafCol(column)),\n columnWindow.start > 0\n && <col key=\"ledger:spacer-leading\" data-ledger-spacer style={{ width: columnWindow.leadingSpace }} />,\n ...visibleLeafColumns\n .slice(pinnedStartCount + columnWindow.start, pinnedStartCount + columnWindow.end)\n .map(column => leafCol(column)),\n columnWindow.end < columnWindow.centerCount\n && <col key=\"ledger:spacer-trailing\" data-ledger-spacer style={{ width: columnWindow.trailingSpace }} />,\n ...pinnedEndCount === 0 ? [] : visibleLeafColumns.slice(-pinnedEndCount).map(column => leafCol(column))\n ];\n\n /* ---- data flags ---- */\n const rowsLength = table.getRowModel().rows.length;\n const errorActive = Boolean(error) && !loading;\n const isEmpty = !loading && !errorActive && rowsLength === 0;\n // Zero rows with an active filter is \"nothing matched\", not \"no data\" — a different message.\n const filtersActive = tableState.columnFilters.length > 0 || tableState.globalFilter !== \"\";\n const paginationEnabled = table.options.meta?.ledger?.enablePagination === true;\n const skeletonRowCount = Math.min(Math.max(tableState.pagination.pageSize, 3), 12);\n\n /* ---- infinite loading ---- */\n // Keyed on the data's identity, not its length: a server-side filter or sort can hand back a\n // different page of the same size, and a length guard would then never re-arm. Consumers\n // already keep `data` referentially stable per snapshot (docs/api.md), so a new array is\n // exactly \"new data\".\n const lastEndReachedData = useRef<unknown>(null);\n const currentData = table.options.data;\n const hasEndReachedHandler = Boolean(onEndReached);\n\n const maybeFireEndReached = useEventCallback(() => {\n const element = viewportRef.current;\n\n // clientHeight 0 = not laid out yet; distance math would fire a phantom page load.\n if (!element || element.clientHeight === 0 || !onEndReached || loading || loadingMore) {\n return;\n }\n\n if (lastEndReachedData.current === currentData) {\n return;\n }\n\n const distance = element.scrollHeight - element.scrollTop - element.clientHeight;\n\n if (distance <= (endReachedOffset ?? 240)) {\n lastEndReachedData.current = currentData;\n onEndReached();\n }\n });\n\n useEffect(() => {\n // Next frame: the virtualizer's first measurement commit must settle before the\n // \"content shorter than the viewport\" check can mean anything.\n const frame = requestAnimationFrame(() => maybeFireEndReached());\n\n return () => cancelAnimationFrame(frame);\n // Each of these can turn a viewport that could not ask for more into one that can: new data,\n // a viewport that just appeared, a load that finished, or a handler mounted after the fact.\n // Probing only on data length left short content stranded with no way to reach the bottom.\n }, [currentData, viewport, loading, loadingMore, hasEndReachedHandler, maybeFireEndReached]);\n\n // Retry re-arms the once-per-data guard — the failed attempt consumed it.\n const retryLoadMore = useEventCallback(() => {\n lastEndReachedData.current = null;\n onEndReached?.();\n });\n\n /* ---- pinned-edge shadows ---- */\n const [scrollEdges, setScrollEdges] = useState({ start: false, end: false });\n\n const updateScrollEdges = useEventCallback(() => {\n const element = viewportRef.current;\n\n if (!element) {\n return;\n }\n\n const max = element.scrollWidth - element.clientWidth;\n const offset = Math.abs(element.scrollLeft);\n const next = { start: offset > 1, end: max > 1 && offset < max - 1 };\n\n setScrollEdges(previous => previous.start === next.start && previous.end === next.end ? previous : next);\n });\n\n /* ---- the header and footer viewports mirror the body's horizontal scroll ---- */\n const headerViewportRef = useRef<HTMLDivElement | null>(null);\n const footerViewportRef = useRef<HTMLDivElement | null>(null);\n const hasFooter = tableHasFooter(table);\n // No header region means no header rows — every aria-rowindex downstream counts from 0.\n const headerRowCount = columnHeadersVisible ? table.getHeaderGroups().length : 0;\n const withDetailPanels = Boolean(ledger?.renderDetailPanel);\n const rowPinningActive = table.options.enableRowPinning === true;\n /**\n * The zones this render draws, read once here. Each array is TanStack-memoized, so holding\n * them costs nothing per scroll step — and every handler below answers from them instead of\n * asking the table again when the key is pressed. A row model reached for at event time is\n * the shared core's, which carries whatever pass rendered last, a discarded one included\n * (docs/architecture.md).\n */\n const pageRows = table.getRowModel().rows;\n const topRows = rowPinningActive ? table.getTopRows() : NO_ARIA_ROWS;\n const bottomRows = rowPinningActive ? table.getBottomRows() : NO_ARIA_ROWS;\n const centerRows = rowPinningActive ? table.getCenterRows() : pageRows;\n // Counting, not building: this runs on every render of a component the virtualizer also\n // re-renders, and three throwaway arrays per scroll step is the same O(rows) cost twice over.\n const logicalDisplayRowCount\n = rowPinningActive\n ? countDisplayRows(topRows, withDetailPanels)\n + countDisplayRows(centerRows, withDetailPanels)\n + countDisplayRows(bottomRows, withDetailPanels)\n : countDisplayRows(pageRows, withDetailPanels);\n\n /**\n * The leading DATA column of the display order — what names a row to a screen reader. The\n * injected columns hold controls, not identity.\n */\n // The first column that can actually name a row: a leading display column (a row number, an\n // actions cluster) has no accessor and would leave every announcement nameless.\n const leadingColumn = useMemo(\n () => visibleLeafColumns.find(column => !isInternalColumn(column.id) && column.accessorFn !== undefined) ?? null,\n [visibleLeafColumns]\n );\n\n /**\n * One object so a `useEventCallback` closure carries the whole display in a single binding:\n * mirrored in an insertion effect, it is always the snapshot of the render that reached the\n * screen (utils.ts). Keyed on the row models themselves — sorting, filtering or paging moves\n * the current row, changes the total, and can take it off the page altogether.\n */\n const displaySnapshot = useMemo<DisplaySnapshot<TData>>(\n () => {\n return {\n bottomRows,\n centerRows,\n leadingColumn,\n ordered: rowPinningActive ? [...topRows, ...centerRows, ...bottomRows] : centerRows,\n pageRows,\n topRows,\n withDetailPanels\n };\n },\n [topRows, centerRows, bottomRows, pageRows, leadingColumn, rowPinningActive, withDetailPanels]\n );\n const bodyAriaRowCount\n = loading && logicalDisplayRowCount === 0\n ? skeletonRowCount\n : logicalDisplayRowCount + (loadMoreError || loadingMore ? 1 : 0);\n // The rendered rows, not every mirrored header level — `aria-rowcount` must match the DOM.\n const footerRowCount = visibleFooterGroups(table).length;\n const ariaRowCount = headerRowCount + bodyAriaRowCount + footerRowCount;\n const footerAriaRowIndexStart = headerRowCount + bodyAriaRowCount + 1;\n\n const mirrorBodyScrollLeft = useEventCallback(() => {\n const element = viewportRef.current;\n\n if (!element) {\n return;\n }\n\n for (const mirror of [headerViewportRef.current, footerViewportRef.current]) {\n if (mirror && mirror.scrollLeft !== element.scrollLeft) {\n // Assigned inside the scroll event, before paint — all regions move in the same frame.\n mirror.scrollLeft = element.scrollLeft;\n }\n }\n });\n\n useEffect(() => {\n updateScrollEdges();\n mirrorBodyScrollLeft();\n }, [viewport, columnVars, hasFooter, updateScrollEdges, mirrorBodyScrollLeft]);\n\n // A dominantly horizontal wheel over the header or footer belongs to the body scroller;\n // vertical-leaning wheels bubble on so the page keeps scrolling naturally.\n useEffect(() => {\n const regions = [headerViewportRef.current, footerViewportRef.current].filter(\n (region): region is HTMLDivElement => region !== null\n );\n\n if (regions.length === 0) {\n return;\n }\n\n const forwardWheel = (event: WheelEvent) => {\n const element = viewportRef.current;\n\n if (!element || Math.abs(event.deltaX) <= Math.abs(event.deltaY)) {\n return;\n }\n\n element.scrollLeft += event.deltaX;\n // Consumed — without this the delta would also scroll a horizontal ancestor.\n event.preventDefault();\n };\n\n // React root wheel listeners are passive; preventDefault needs native non-passive ones.\n for (const region of regions) {\n region.addEventListener(\"wheel\", forwardWheel, { passive: false });\n }\n\n return () => {\n for (const region of regions) {\n region.removeEventListener(\"wheel\", forwardWheel);\n }\n };\n }, [hasFooter]);\n\n const handleScrollPositionChange = useEventCallback(() => {\n mirrorBodyScrollLeft();\n maybeFireEndReached();\n updateScrollEdges();\n });\n\n /* ---- imperative handle ---- */\n const virtualizerRef = useRef<Virtualizer<HTMLDivElement, Element> | null>(null);\n const handleVirtualizerChange = useCallback(\n (virtualizer: Virtualizer<HTMLDivElement, Element> | null) => {\n virtualizerRef.current = virtualizer;\n },\n []\n );\n\n const scrollRowIntoView = useEventCallback(\n (rowId: string, options?: DataTableScrollOptions) => {\n const virtualizer = virtualizerRef.current;\n\n if (virtualizer) {\n const index = resolveVirtualDisplayIndex(displaySnapshot, rowId);\n\n if (index !== null) {\n virtualizer.scrollToIndex(index, {\n align: options?.align ?? \"auto\",\n behavior: options?.behavior\n });\n }\n\n return;\n }\n\n const selector = `[data-row-id=\"${typeof CSS === \"undefined\" ? rowId.replaceAll(\"\\\"\", String.raw`\\\"`) : CSS.escape(rowId)}\"]`;\n const rowElement = viewportRef.current?.querySelector<HTMLElement>(`:scope ${selector}`);\n\n rowElement?.scrollIntoView({\n behavior: options?.behavior,\n block: options?.align === undefined || options.align === \"auto\" ? \"nearest\" : options.align\n });\n }\n );\n\n /**\n * The index counts through the page's own row model — the rows the table holds, before the\n * display order interleaves pinned rows and detail panels around them.\n */\n const scrollIndexIntoView = useEventCallback(\n (index: number, options?: DataTableScrollOptions) => {\n const rowId = displaySnapshot.pageRows[index]?.id;\n\n if (rowId !== undefined) {\n scrollRowIntoView(rowId, options);\n }\n }\n );\n\n /**\n * Pure width-engine math, no DOM measurement: the column's center-zone offset from the same\n * prefix numbers the window uses, against the strip the pinned overlays leave visible. Works\n * with or without a column window — the target column need not be rendered to be reachable.\n */\n const scrollColumnIntoView = useEventCallback(\n (columnId: string, options?: DataTableScrollOptions) => {\n const element = viewportRef.current;\n const index = displayIndexById.get(columnId);\n\n if (!element || index === undefined) {\n return;\n }\n\n // Pinned columns are sticky — always in view, nothing to scroll.\n if (index < pinnedStartCount || index >= visibleLeafColumns.length - pinnedEndCount) {\n return;\n }\n\n let offset = 0;\n\n for (let i = pinnedStartCount; i < index; i += 1) {\n offset += columnWidths.byId[visibleLeafColumns[i]!.id] ?? 0;\n }\n\n const width = columnWidths.byId[columnId] ?? 0;\n const strip = Math.max(0, element.clientWidth - pinnedStartWidth - pinnedEndWidth);\n const current = Math.abs(element.scrollLeft);\n const align = options?.align ?? \"auto\";\n let target: number;\n\n switch (align) {\n case \"start\": {\n target = offset;\n\n break;\n }\n\n case \"end\": {\n target = offset + width - strip;\n\n break;\n }\n\n case \"center\": {\n target = offset + (width - strip) / 2;\n\n break;\n }\n\n default: { if (offset >= current && offset + width <= current + strip) {\n return;\n }\n\n target = offset < current ? offset : offset + width - strip; }\n }\n\n target = Math.max(0, target);\n // RTL viewports scroll into negative territory; the math above is direction-agnostic.\n const rtl = getComputedStyle(element).direction === \"rtl\";\n element.scrollTo({ behavior: options?.behavior, left: rtl ? -target : target });\n }\n );\n\n useImperativeHandle(\n handleRef,\n () => {\n return {\n table,\n get viewport() {\n return viewportRef.current;\n },\n scrollToRow: scrollRowIntoView,\n scrollToIndex: scrollIndexIntoView,\n scrollToColumn: scrollColumnIntoView,\n startEditing: (rowId, columnId) => {\n const editing = table.options.meta?.ledger?.editing;\n\n if (!editing) {\n return;\n }\n\n if (editing.mode === \"row\") {\n editing.row.start(rowId, columnId === undefined ? undefined : { focusColumnId: columnId });\n } else if (columnId === undefined) {\n warnOnce(\"start-editing-column\", \"startEditing needs a columnId in cell mode.\");\n } else {\n editing.start({ rowId, columnId });\n }\n },\n stopEditing: options => {\n const editing = table.options.meta?.ledger?.editing;\n\n if (editing?.mode === \"row\") {\n editing.row.stop(options);\n } else {\n editing?.stop(options);\n }\n }\n };\n },\n [table, scrollRowIntoView, scrollIndexIntoView, scrollColumnIntoView]\n );\n\n /* ---- active row keyboard (docs/rows.md): the body viewport is the focus stop ---- */\n const activeRowAnnouncer = useRef<HTMLSpanElement>(null);\n const rowNavigationHintId = `${instanceId}-row-navigation`;\n // The keyboard model describes the element that actually takes focus — a description is read\n // out for the focused node, and the ARIA table never is one. `aria-describedby` is a global\n // property that any element may carry: `generic` prohibits an accessible *name*, not a\n // description, and referencing an id adds no role and owns nothing. The consumer's own\n // description stays on the table; theirs on the viewport keeps the first read there.\n const viewportDescribedBy = activeRowEnabled\n ? [viewportProps?.[\"aria-describedby\"], rowNavigationHintId].filter(Boolean).join(\" \")\n : viewportProps?.[\"aria-describedby\"];\n\n // Runs once per change of the current row rather than once per render: the row lookup is a\n // scan, and this component re-renders on every scroll step of a virtualized table.\n const announceActiveRow = useEventCallback(() => {\n const target = activeRowAnnouncer.current;\n\n if (!target) {\n return;\n }\n\n if (activeRowId === null) {\n target.textContent = \"\";\n\n return;\n }\n\n const { ordered, leadingColumn: leading } = displaySnapshot;\n const index = ordered.findIndex(row => row.id === activeRowId);\n\n if (index === -1) {\n target.textContent = \"\";\n\n return;\n }\n\n // Through the leading column's own accessor, never `row.getValue`: that resolves the column\n // through `row.table` — the shared core — and reads a cache the row only rebuilds when the\n // data changes (use-committed-table.ts).\n const row = ordered[index] as Row<TData>;\n const value = leading === null ? \"\" : String(leading.accessorFn?.(row.original, row.index) ?? \"\");\n\n target.textContent = labels.currentRow(value === \"\" ? activeRowId : value, index + 1, ordered.length);\n });\n\n useEffect(() => {\n if (activeRowEnabled) {\n announceActiveRow();\n }\n // The snapshot is the dependency in its own right, not the row id: sorting, filtering or\n // paging changes the current row's position, the total, and even whether it is still on the\n // page, and hiding or reordering a column can rename the row without moving it. An id-only\n // dependency would leave the last announcement standing after any of that.\n }, [activeRowId, activeRowEnabled, displaySnapshot, labels, announceActiveRow]);\n\n const handleActiveRowKeyDown = useEventCallback((event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (!activeRowEnabled || !setActiveRow) {\n return;\n }\n\n // Keys inside an interactive child (an editor, a checkbox, the retry button) belong to it.\n if ((event.target as HTMLElement).closest(\"input, button, select, textarea, a, [contenteditable]\")) {\n return;\n }\n\n // F2 is the one key here that needs no row list. The row it acts on is the active-row slice,\n // and where it opens is the editing controller's answer for the render that reached the\n // screen — so a render nobody saw cannot empty the table out from under it. The keys below\n // move *through* the rows the table holds, which is a different question and still asks the\n // core (docs/architecture.md).\n //\n // There is no cell cursor, so the row's first editable cell is the entry point — the cell to\n // edit in cell mode, the cell to focus in row mode; the pattern defines F2 as placing focus\n // in an input, so both modes land the caret somewhere. What a checkbox column is depends on\n // the mode, and so does whether it can be that entry point: in cell mode it commits on toggle\n // and never hosts an editor; in row mode it is a draft-bound editor like any other, and a row\n // whose only editable column is one would otherwise never open at all.\n if (event.key === \"F2\") {\n if (!editing || activeRowId === null) {\n return;\n }\n\n const rowMode = editing.mode === \"row\";\n const target = editing.firstEditable(activeRowId, !rowMode);\n\n if (target === null) {\n return;\n }\n\n event.preventDefault();\n\n if (rowMode) {\n editing.row.start(activeRowId, { focusColumnId: target });\n } else {\n editing.start({ rowId: activeRowId, columnId: target });\n }\n\n return;\n }\n\n const rows = displaySnapshot.ordered;\n\n if (rows.length === 0) {\n return;\n }\n\n const currentIndex = activeRowId === null ? -1 : rows.findIndex(row => row.id === activeRowId);\n\n const moveTo = (index: number) => {\n const row = rows[Math.min(Math.max(index, 0), rows.length - 1)];\n\n if (row) {\n setActiveRow(row.id);\n scrollRowIntoView(row.id);\n }\n };\n\n switch (event.key) {\n case \"ArrowDown\": {\n event.preventDefault();\n moveTo(currentIndex + 1);\n\n break;\n }\n\n case \"ArrowUp\": {\n event.preventDefault();\n moveTo(currentIndex - 1);\n\n break;\n }\n\n case \"Home\": {\n event.preventDefault();\n moveTo(0);\n\n break;\n }\n\n case \"End\": {\n event.preventDefault();\n moveTo(rows.length - 1);\n\n break;\n }\n\n case \"Enter\": {\n const row = currentIndex >= 0 ? rows[currentIndex] : null;\n\n // Only `onRowActivate` is input-agnostic. `onRowClick` stays literal — synthesizing a\n // MouseEvent for it would make its own type signature a lie.\n if (row && onRowActivate) {\n event.preventDefault();\n onRowActivate(row as Row<TData>, event);\n }\n\n break;\n }\n\n // The WAI-APG grid pattern's dedicated edit key. Enter is spoken for here (it activates\n // the row), which is exactly the overload F2 exists to resolve.\n // No default\n }\n });\n\n /* ---- dev guard rails ---- */\n if (paginationEnabled && onEndReached) {\n warnOnce(\n \"pagination-and-end-reached\",\n \"enablePagination and onEndReached are configured together — pagination and infinite loading are mutually exclusive.\"\n );\n }\n\n useEffect(() => {\n if (!virtualEnabled || !viewport || rowsLength <= 50) {\n return;\n }\n\n // Next frame: judged only after the virtualizer's first measurement commit has painted,\n // otherwise the still-empty tbody reads as \"content fits\" and false-alarms.\n const frame = requestAnimationFrame(() => {\n if (viewport.clientHeight > 0 && viewport.scrollHeight <= viewport.clientHeight + 4) {\n warnOnce(\n \"virtualized-unconstrained\",\n \"virtualizedRows is set but the viewport is unconstrained (its height equals the content height) — give the table or an ancestor a definite height.\"\n );\n }\n });\n\n return () => cancelAnimationFrame(frame);\n }, [virtualEnabled, viewport, rowsLength]);\n\n /* ---- render ---- */\n const stripedMode = striped === true ? \"odd\" : striped || undefined;\n\n // Header and body render as separate tables so the vertical scroller owns only the body:\n // identical props, colgroup, and root-level column variables keep their layouts pixel-equal.\n // Semantics come from the ARIA table on `main` — the native tables are presentational.\n // Row/column borders are ledger-owned at cell level (docs/styling.md), so the border props\n // become root data-attributes instead of Mantine Table props.\n const sharedTableProps = {\n horizontalSpacing,\n layout: \"fixed\" as const,\n role: \"presentation\" as const,\n tabularNums,\n verticalSpacing\n };\n // Exact table width (the engine's total) — the browser never redistributes column widths;\n // `border-collapse: separate` is inline because the host's unlayered `collapse` would win,\n // and collapse drops borders on stuck sticky cells (docs/styling.md).\n const tableStyleProps = () => getStyles(\"table\", {\n style: {\n width: columnWidths.total > 0 ? columnWidths.total : undefined,\n minWidth: toPx(tableMinWidth),\n borderCollapse: \"separate\" as const,\n borderSpacing: 0\n }\n });\n\n /* ---- row reordering session (docs/rows.md#row-ordering) ---- */\n const rowOrderingEnabled = ledger?.rowOrdering.enabled === true;\n\n // The same naming the active-row announcement uses — the leading column's own accessor over\n // the committed row — falling back to the row id rather than announcing a nameless lift.\n const nameReorderRow = useEventCallback((row: Row<TData>) => {\n const leading = displaySnapshot.leadingColumn;\n const value = leading === null ? \"\" : String(leading.accessorFn?.(row.original, row.index) ?? \"\");\n\n return value === \"\" ? row.id : value;\n });\n const centerRowsForReorder = useEventCallback(() => displaySnapshot.centerRows);\n const scrollReorderTargetIntoView = useEventCallback((rowId: string) => scrollRowIntoView(rowId));\n\n const rowReorder = useRowReorder<TData>({\n onRowReorder: ledger?.rowOrdering.onRowReorder,\n labels,\n viewportRef,\n getCenterRows: centerRowsForReorder,\n nameRow: nameReorderRow,\n scrollToRow: scrollReorderTargetIntoView\n });\n\n const contextValue = useMemo<DataTableContextValue>(\n () => {\n return {\n activeRowEnabled,\n setActiveRow,\n rowReorderKeyboard: rowOrderingEnabled ? rowReorder.keyboard : undefined,\n selection: selectionCommands,\n expansion: expansionCommands,\n subscribeColumnFilters,\n instanceId,\n getStyles: stylesRevision,\n labels,\n icons,\n filterMode,\n virtualizedRows: virtualEnabled,\n withColumnHeaders: columnHeadersVisible,\n onRowClick: contextRowClick,\n onRowActivate: contextRowActivate,\n onRowDoubleClick: contextRowDoubleClick,\n onRowContextMenu: contextRowContextMenu,\n rowProps: rowProps as DataTableContextValue[\"rowProps\"],\n headerRowProps: headerRowProps as DataTableContextValue[\"headerRowProps\"],\n footerRowProps: footerRowProps as DataTableContextValue[\"footerRowProps\"]\n };\n },\n [\n activeRowEnabled,\n setActiveRow,\n rowOrderingEnabled,\n rowReorder.keyboard,\n selectionCommands,\n expansionCommands,\n subscribeColumnFilters,\n instanceId,\n stylesRevision,\n labels,\n icons,\n filterMode,\n virtualEnabled,\n columnHeadersVisible,\n contextRowClick,\n contextRowActivate,\n contextRowDoubleClick,\n contextRowContextMenu,\n rowProps,\n headerRowProps,\n footerRowProps\n ]\n );\n\n return (\n <DataTableProvider value={contextValue}>\n <RowReorderScope session={rowOrderingEnabled ? rowReorder : null}>\n <Box\n ref={rootRef}\n data-empty={isEmpty || undefined}\n data-error={errorActive || undefined}\n data-highlight-on-hover={highlightOnHover || undefined}\n data-loading={loading || undefined}\n data-scrolled-end={scrollEdges.end || undefined}\n data-scrolled-start={scrollEdges.start || undefined}\n data-striped={stripedMode}\n data-virtualized-columns={columnWindow !== null || undefined}\n data-virtualized-rows={virtualEnabled || undefined}\n data-with-column-borders={withColumnBorders || undefined}\n data-with-row-borders={withRowBorders || undefined}\n data-with-table-border={withTableBorder || undefined}\n {...getStyles(\"root\", { style: columnVars })}\n {...others}\n >\n {activeRowEnabled && (\n <>\n {/* Focus never leaves the viewport when the arrow keys move the current row, so the\n move is visual only unless it is spoken. Written imperatively: a live region wants\n a text change, not a React re-render of the table. Both of these sit outside\n `role=\"table\"` — a table may only own rows. */}\n <VisuallyHidden ref={activeRowAnnouncer} aria-live=\"polite\" role=\"status\" />\n {/* The text the focus stop points at. It sits out here rather than inside the\n table because `aria-describedby` resolves by id from anywhere, while a stray\n element inside `role=\"table\"` would not. */}\n <VisuallyHidden id={rowNavigationHintId}>{labels.rowNavigation}</VisuallyHidden>\n </>\n )}\n\n <div\n // On the element that is the table: `aria-busy` is defined for the widget whose\n // content is being updated, and the root carries no role for it to qualify.\n aria-busy={loading || undefined}\n aria-colcount={columnWindow === null ? undefined : columnWindow.totalLeafCount}\n aria-describedby={ariaDescribedBy}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-rowcount={virtualEnabled ? ariaRowCount : undefined}\n role=\"table\"\n {...getStyles(\"main\")}\n >\n {columnHeadersVisible && (\n <div ref={headerViewportRef} {...getStyles(\"header\")}>\n <MantineTable {...sharedTableProps} {...tableStyleProps()}>\n <colgroup>{colElements}</colgroup>\n\n <TableHeader\n columnSizing={tableState.columnSizing}\n columnWidths={columnWidths.byId}\n columnWindow={columnWindow}\n table={erasedTable}\n />\n </MantineTable>\n </div>\n )}\n\n {/* overscroll-behavior: none — rubber-band overscroll translates the body past its\n clamped scroll position, which the mirrored header/footer can never follow; the\n regions shear apart for the duration of the bounce.\n Transparent track/corner — Mantine tints them on hover through unlayered rules\n that defeat any layered override, so inline is the only seat that wins; the thumb\n is its own element and keeps its background. */}\n <ScrollArea\n {...getStyles(\"scroller\")}\n scrollbars=\"xy\"\n type=\"hover\"\n viewportRef={assignViewport}\n styles={{\n corner: { backgroundColor: \"transparent\" },\n scrollbar: { backgroundColor: \"transparent\" }\n }}\n viewportProps={mergeElementProps(viewportProps, {\n style: { overscrollBehavior: \"none\" as const },\n // With the active row on, the body viewport is the keyboard focus stop, and it\n // carries the description of the keyboard model (`rowNavigationHintId`, composed\n // after any the consumer passed). Deliberately unnamed: this div is `generic`, a\n // role that prohibits an accessible name, and it cannot take a role either —\n // that would break `table`'s owned rows. It stays the focus stop so the browser's\n // own scrolling keys keep reaching the scroller.\n \"aria-describedby\": viewportDescribedBy,\n ...activeRowEnabled && { tabIndex: 0, onKeyDown: handleActiveRowKeyDown }\n })}\n onScrollPositionChange={handleScrollPositionChange}\n >\n <MantineTable {...sharedTableProps} {...tableStyleProps()}>\n <colgroup>{colElements}</colgroup>\n\n <TableBody\n columnWindow={columnWindow}\n loading={loading === true}\n loadingMore={loadingMore === true}\n loadMoreError={loadMoreError ?? false}\n reorderSourceId={rowOrderingEnabled ? rowReorder.sourceId : null}\n reorderTarget={rowOrderingEnabled ? rowReorder.target : null}\n skeletonRowCount={skeletonRowCount}\n table={erasedTable}\n viewportRef={viewportRef}\n virtualization={virtualization}\n onLoadMoreRetry={onEndReached ? retryLoadMore : undefined}\n onVirtualizerChange={handleVirtualizerChange}\n />\n </MantineTable>\n\n {isEmpty && (\n // Polite, not assertive: filtering a table down to nothing is worth announcing,\n // but it must not interrupt the typing that caused it.\n <div\n {...getStyles(\"empty\")}\n data-variant={filtersActive ? \"no-results\" : \"no-data\"}\n role=\"status\"\n >\n {emptyState ?? (\n <EmptyState\n withIndicatorBackground\n size=\"sm\"\n styles={EMPTY_STATE_STYLES}\n title={filtersActive ? labels.noResults : labels.empty}\n // The indicator forces the svg to 1em (40px at `sm`), so the stroke is set for\n // that scale — the default (2, drawn for Lucide's 24px grid) turns chunky here.\n icon={filtersActive\n ? <icons.noResults size={40} strokeWidth={1.5} />\n : <icons.empty size={40} strokeWidth={1.5} />}\n />\n )}\n </div>\n )}\n\n {errorActive && (\n <div\n {...getStyles(\"empty\")}\n data-over-rows={rowsLength > 0 || undefined}\n data-variant=\"error\"\n role=\"alert\"\n >\n <EmptyState\n withIndicatorBackground\n icon={<icons.error size={40} strokeWidth={1.5} />}\n size=\"sm\"\n styles={EMPTY_STATE_STYLES}\n title={error === true ? labels.error : error}\n >\n {onRetry && (\n <Button\n leftSection={<icons.retry size={14} />}\n size=\"xs\"\n variant=\"light\"\n onClick={onRetry}\n >\n {labels.retry}\n </Button>\n )}\n </EmptyState>\n </div>\n )}\n </ScrollArea>\n\n {hasFooter && (\n <div ref={footerViewportRef} {...getStyles(\"footer\")}>\n <MantineTable {...sharedTableProps} {...tableStyleProps()}>\n <colgroup>{colElements}</colgroup>\n\n <TableFooter\n ariaRowIndexStart={virtualEnabled ? footerAriaRowIndexStart : undefined}\n columnWindow={columnWindow}\n table={erasedTable}\n />\n </MantineTable>\n </div>\n )}\n </div>\n\n {loading && rowsLength > 0 && <LoadingOverlay visible overlayProps={{ blur: 1 }} zIndex={20} />}\n\n {paginationEnabled && withPaginationBar\n && <PaginationBar pageSizeOptions={pageSizeOptions ?? DEFAULT_PAGE_SIZE_OPTIONS} table={table} />}\n </Box>\n </RowReorderScope>\n </DataTableProvider>\n );\n}\n\nDataTable.displayName = \"@coldsmirk/ledger-mantine/DataTable\";\nDataTable.classes = classes;\nDataTable.Search = DataTableSearch;\nDataTable.ColumnsPanel = DataTableColumnsPanel;\nDataTable.Pagination = DataTablePagination;\nDataTable.SelectionBar = DataTableSelectionBar;\n","import type { ComboboxData } from \"@mantine/core\";\n\nimport type { DataTableEditRenderer, DataTableInstantEditRenderer } from \"./types\";\n\n/**\n * The shipped editor renderers — conveniences, never the mechanism. Each is an ordinary\n * renderer over the public editing contexts (docs/editing.md#editors), which is the proof the\n * contexts suffice: anything these do, an application's own renderer can do the same way.\n * All are default-variant Mantine inputs — the border marks the cell as an open editor.\n */\nimport { Checkbox, NumberInput, Select, TextInput } from \"@mantine/core\";\n\nconst renderTextEditor: DataTableEditRenderer<any, any> = ({\n value,\n setValue,\n error,\n pending,\n autoFocus,\n label\n}) => (\n <TextInput\n aria-label={label}\n autoFocus={autoFocus}\n disabled={pending}\n error={error}\n size=\"xs\"\n value={value === null || value === undefined ? \"\" : String(value)}\n onChange={event => setValue(event.currentTarget.value)}\n />\n);\n\n/**\n * A plain text editor: `meta.edit: textEditor()`.\n */\nexport function textEditor(): DataTableEditRenderer<any, any> {\n return renderTextEditor;\n}\n\nconst renderNumberEditor: DataTableEditRenderer<any, any> = ({\n value,\n setValue,\n error,\n pending,\n autoFocus,\n label\n}) => (\n <NumberInput\n hideControls\n aria-label={label}\n autoFocus={autoFocus}\n disabled={pending}\n error={error}\n size=\"xs\"\n value={typeof value === \"number\" || typeof value === \"string\" ? value : \"\"}\n onChange={next => setValue(next === \"\" ? null : next)}\n />\n);\n\n/**\n * A numeric editor; an emptied input holds `null`, never `0`.\n */\nexport function numberEditor(): DataTableEditRenderer<any, any> {\n return renderNumberEditor;\n}\n\n/**\n * A single-pick editor over the given options. In cell mode the dropdown opens immediately and\n * picking an option commits at once — one cell is the whole session; in row mode it is one\n * draft-bound field among the row's others, and the row's own commit decides.\n */\nexport function selectEditor(options: ComboboxData): DataTableEditRenderer<any, any> {\n return ({\n value,\n setValue,\n commit,\n error,\n pending,\n mode,\n autoFocus,\n label\n }) => (\n <Select\n aria-label={label}\n autoFocus={autoFocus}\n comboboxProps={{ withinPortal: true }}\n data={options}\n defaultDropdownOpened={mode === \"cell\"}\n disabled={pending}\n error={error}\n size=\"xs\"\n value={value === null || value === undefined ? null : String(value)}\n onChange={next => {\n setValue(next);\n\n if (mode === \"cell\") {\n void commit();\n }\n }}\n />\n );\n}\n\nconst renderCheckboxEditor: DataTableInstantEditRenderer<any, any> = ({\n value,\n commit,\n pending,\n error,\n label\n}) => (\n <Checkbox\n aria-label={label}\n checked={Boolean(value)}\n disabled={pending}\n // Styles only — the instant host renders the message in its own alert region.\n error={Boolean(error)}\n size=\"xs\"\n onChange={event => void commit(event.currentTarget.checked)}\n />\n);\n\n/**\n * A live checkbox for an instant column: `meta.edit: { instant: checkboxEditor() }`. Each\n * toggle commits the flipped value; the host disables it while its own write is out.\n */\nexport function checkboxEditor(): DataTableInstantEditRenderer<any, any> {\n return renderCheckboxEditor;\n}\n"],"mappings":"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;;AAK3C,MAAM,eAAwB,CAAC;AAI/B,MAAM,qBAAqB,EACzB,OAAO;CAAE,OAAO;CAA+B,YAAY;AAAI,EACjE;AAsJA,MAAM,eAAe;CACnB,SAAS;CACT,kBAAkB;CAClB,iBAAiB;CACjB,mBAAmB;CACnB,gBAAgB;CAChB,iBAAiB;CACjB,mBAAmB;CACnB,aAAa;CACb,iBAAiB;CACjB,oBAAoB;CACpB,kBAAkB;CAClB,aAAa;CACb,SAAS;CACT,mBAAmB;CACnB,mBAAmB;CACnB,iBAAiB;AACnB;AAEA,SAAS,QAAQ,QAAwB;CACvC,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAqB,OAAO,EAAE,OAAO,OAAO,eAAe,OAAO,EAAE,EAAE,GAAG,EAAI,GAAnE,OAAO,EAA4D;AACtF;AAEA,MAAM,gBAAA,GAAeC,cAAAA,mBAAAA,EAClB,OAAO,EACN,cACA,uBACA,kBACI;CACJ,OAAO,EACL,MAAM;EACJ,0BAA0B,gBAAA,GAAeC,cAAAA,cAAAA,CAAc,cAAc,KAAK,IAAI,KAAA;EAC9E,wBAAwB,yBAAA,GACpBA,cAAAA,cAAAA,CAAc,uBAAuB,KAAK,IAC1C,KAAA;EAEJ,yBAAyB,eAAA,GAAcA,cAAAA,cAAAA,CAAc,aAAa,KAAK,IAAI,KAAA;CAC7E,EACF;AACF,CACF;AAoGA,MAAM,iCAAsC,IAAI,IAA6C;CA7F3F;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAYqG,CAAC;AAMxG,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"}
1
+ {"version":3,"file":"index.cjs","names":["createSafeContext","ActionIcon","useRef","useCallback","PointerActivationConstraints","PointerSensor","AutoScroller","Cursor","PreventSelection","useState","useRef","useMemo","DragDropProvider","Portal","VisuallyHidden","useDraggable","Tooltip","ActionIcon","Checkbox","Radio","useProps","Popover","move","DragDropProvider","Group","Text","Button","useSortable","Tooltip","ActionIcon","Checkbox","NumberInput","SegmentedControl","Center","VisuallyHidden","useId","Group","Text","Select","Pagination","useProps","useProps","useState","useDebouncedCallback","TextInput","CloseButton","useProps","Group","Text","Button","useReducer","Loader","useRef","useMemo","useState","useRef","useState","useRef","useCallback","ActionIcon","flexRender","useReducer","Loader","MantineTable","memo","Skeleton","Button","useMemo","useCallback","useVirtualizer","MantineTable","flexRender","Popover","ActionIcon","Stack","Group","CloseButton","MultiSelect","Select","useState","useDebouncedCallback","TextInput","NumberInput","DatePicker","Button","useState","useRef","useState","useRef","MantineTable","flexRender","Tooltip","useState","useCallback","useMemo","filterFn_arrHas","filterFn_arrIncludes","filterFn_arrIncludesAll","filterFn_arrIncludesSome","filterFn_between","filterFn_betweenInclusive","filterFn_empty","filterFn_endsWith","filterFn_equals","filterFn_equalsString","filterFn_equalsStringSensitive","filterFn_greaterThan","filterFn_greaterThanOrEqualTo","filterFn_inDateRange","filterFn_inNumberRange","filterFn_includesString","filterFn_includesStringSensitive","filterFn_lessThan","filterFn_lessThanOrEqualTo","filterFn_notEmpty","filterFn_startsWith","filterFn_weakEquals","tableFeatures","createExpandedRowModel","createFacetedMinMaxValues","createFacetedRowModel","createFacetedUniqueValues","createFilteredRowModel","createGroupedRowModel","createPaginatedRowModel","createSortedRowModel","aggregationFn_count","aggregationFn_extent","aggregationFn_first","aggregationFn_last","aggregationFn_max","aggregationFn_mean","aggregationFn_median","aggregationFn_min","aggregationFn_sum","aggregationFn_unique","aggregationFn_uniqueCount","sortFn_alphanumeric","sortFn_alphanumericCaseSensitive","sortFn_basic","sortFn_datetime","sortFn_text","sortFn_textCaseSensitive","tanStackCreateColumnHelper","useRef","useRef","useState","useCallback","useMemo","EMPTY","useRef","useCallback","useMemo","useRef","useCallback","useMemo","useMemo","useState","useRef","useCallback","useMemo","useRef","useState","useCallback","useMemo","useUncontrolled","useRef","useCallback","functionalUpdate","useState","useRef","useCallback","functionalUpdate","useMemo","useTable","useMantineTheme","useMantineClassNamesPrefix","useMantineWithStaticClasses","useMantineIsHeadless","useMantineStylesTransform","useRef","createVarsResolver","getThemeColor","getRadius","useProps","genericFactory","useStyles","useMemo","useRef","useState","useCallback","useId","Box","VisuallyHidden","MantineTable","ScrollArea","EmptyState","Button","LoadingOverlay","TextInput","NumberInput","Select","Checkbox"],"sources":["../src/context.ts","../src/expander.tsx","../src/filter-fns.ts","../src/utils.ts","../src/row-reorder.tsx","../src/selection.tsx","../src/build-columns.tsx","../src/column-order.ts","../src/icons.tsx","../src/labels.ts","../src/columns-panel.tsx","../src/csv.ts","../src/element-props.ts","../src/env.ts","../src/ledger-commands.ts","../src/pagination-bar.tsx","../src/search.tsx","../src/selection-bar.tsx","../src/edit-meta.ts","../src/cell-editor.tsx","../src/pinning.ts","../src/truncate.ts","../src/use-column-window.ts","../src/use-pinned-row-offsets.ts","../src/table-body.tsx","../src/table-footer.tsx","../src/autosize-column.ts","../src/filter-popover.tsx","../src/use-column-reorder.ts","../src/use-column-resize.ts","../src/table-header.tsx","../src/use-column-widths.ts","../src/ledger-features.ts","../src/persist.ts","../src/toggle-fns.ts","../src/use-cell-editing.ts","../src/use-committed-table.ts","../src/use-instant-editing.ts","../src/use-responsive-columns.ts","../src/use-row-commands.ts","../src/use-row-editing.ts","../src/use-slice.ts","../src/use-data-table.ts","../src/use-styles-revision.ts","../src/data-table.tsx","../src/editors.tsx"],"sourcesContent":["import type { GetStylesApi, TableTrProps } from \"@mantine/core\";\nimport type { ColumnFiltersState } from \"@tanstack/react-table\";\nimport type { KeyboardEvent, MouseEvent } from \"react\";\n\nimport type { DataTableFactory } from \"./data-table\";\nimport type { DataTableElementProps } from \"./element-props\";\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { RowReorderKeyboard } from \"./row-reorder\";\nimport type { HeaderGroup, Row } from \"./types\";\nimport type { LedgerExpansionController, LedgerSelectionController } from \"./use-row-commands\";\n\n/**\n * Internal context for everything rendered inside the <DataTable> tree. The data generic is\n * erased at this boundary — the single deliberate erasure in the package, mirroring the family\n * convention (one documented boundary instead of casts scattered through the tree). Cells and\n * filter popovers receive their strongly-typed TanStack objects (`Row<TData>`, `Column<TData>`)\n * directly as props; the context only carries table-wide plumbing.\n *\n * The table instance itself is deliberately NOT here. Anything below that rendered without the\n * root rendering with it — a filter popover redrawing from its own state, a row the virtualizer\n * put back — would read whatever pass wrote the instance last, and v9 writes the shared core\n * during render, a pass React discarded included. So the few table-wide facts the tree needs\n * arrive as their own fields, each stable enough to keep the context value itself stable\n * (docs/architecture.md).\n */\nimport { createSafeContext } from \"@mantine/core\";\n\nexport interface DataTableContextValue {\n /**\n * Stable per-instance id — what the single-select radios group themselves by.\n */\n instanceId: string;\n getStyles: GetStylesApi<DataTableFactory>;\n labels: DataTableLabels;\n icons: DataTableIcons;\n filterMode: \"client\" | \"server\";\n /**\n * Row virtualization active — rows must then carry aria-rowindex (header rows included).\n */\n virtualizedRows: boolean;\n /**\n * The header region renders — so header rows count toward every `aria-rowindex`.\n */\n withColumnHeaders: boolean;\n /**\n * The active-row slice, as its own two facts: the switch, and the stable setter that moves it.\n * Rows are memoized, so both have to reach them through the context — a prop that only\n * TableBody knows about would leave a row that did not re-render answering with the switch as\n * it stood when it last did.\n */\n activeRowEnabled: boolean;\n setActiveRow?: (rowId: string) => void;\n /**\n * The row-ordering keyboard session (docs/rows.md#row-ordering) — the handle cells drive it,\n * `DataTable` owns it. The handlers are stable; only presence changes with the gate.\n */\n rowReorderKeyboard?: RowReorderKeyboard;\n /**\n * The row-state toggles the injected columns drive. Stable for the life of the instance, so a\n * cell reaches one without the route deciding anything (`use-row-commands.ts`).\n */\n selection?: LedgerSelectionController;\n expansion?: LedgerExpansionController;\n /**\n * Notification of every `columnFilters` set attempt, no-ops included — what a debounced filter\n * control listens to so an external reset reaches its own local value. Stable per instance.\n */\n subscribeColumnFilters?: (listener: (value: ColumnFiltersState) => void) => () => void;\n onRowClick?: (row: Row<any>, event: MouseEvent) => void;\n onRowActivate?: (row: Row<any>, event: MouseEvent | KeyboardEvent) => void;\n onRowDoubleClick?: (row: Row<any>, event: MouseEvent) => void;\n onRowContextMenu?: (row: Row<any>, event: MouseEvent) => void;\n rowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, Row<any>>;\n headerRowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, HeaderGroup<any>>;\n footerRowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, HeaderGroup<any>>;\n}\n\nexport const [DataTableProvider, useDataTableContext] = createSafeContext<DataTableContextValue>(\n \"DataTable parts must be rendered inside <DataTable>\"\n);\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Row, TableInstance } from \"./types\";\n\n/**\n * The injected expander column: a per-row chevron (detail panels and sub-row trees share it)\n * and an expand-all header affordance for trees. Clicks never reach `onRowClick`.\n */\nimport { ActionIcon } from \"@mantine/core\";\n\nimport { useDataTableContext } from \"./context\";\n\nexport function ExpanderHeaderCell<TData extends RowData>({ table }: { table: TableInstance<TData> }) {\n const {\n labels,\n icons,\n expansion\n } = useDataTableContext();\n\n // Expand-all only makes sense over a tree; a master–detail table opens panels one at a time.\n if (!table.options.getSubRows) {\n return null;\n }\n\n const allExpanded = table.getIsAllRowsExpanded();\n const canSomeExpand = table.getCanSomeRowsExpand();\n\n return (\n <ActionIcon\n aria-label={allExpanded ? labels.collapseAll : labels.expandAll}\n data-expanded={allExpanded || undefined}\n size=\"sm\"\n variant=\"subtle\"\n onClick={event => {\n event.stopPropagation();\n expansion?.toggleAll(!allExpanded, canSomeExpand);\n }}\n >\n <icons.expandRow />\n </ActionIcon>\n );\n}\n\nexport function ExpanderCell<TData extends RowData>({ row }: { row: Row<TData> }) {\n const {\n labels,\n icons,\n expansion\n } = useDataTableContext();\n const canExpand = row.getCanExpand();\n\n if (!canExpand) {\n return null;\n }\n\n const expanded = row.getIsExpanded();\n\n return (\n <ActionIcon\n aria-expanded={expanded}\n aria-label={expanded ? labels.collapseRow : labels.expandRow}\n data-expanded={expanded || undefined}\n size=\"sm\"\n variant=\"subtle\"\n onClick={event => {\n event.stopPropagation();\n expansion?.toggle(row.id, expanded, canExpand);\n }}\n >\n <icons.expandRow />\n </ActionIcon>\n );\n}\n","/**\n * The mapping from `meta.filter` variants to TanStack filter functions, plus the one custom\n * function the built-ins lack. A column keeps any `filterFn` it declares itself — the variant\n * mapping only fills the gap (docs/filtering.md).\n *\n * The functions are registered on the canonical feature set (`ledger-features.ts`), which is\n * what makes their ids valid `filterFn` strings for consumers — v9 registry slots replace v8's\n * `FilterFns` declaration merging.\n */\nimport type { FilterFn } from \"@tanstack/react-table\";\n\nimport type { DataTableFilterVariant } from \"./types\";\n\nexport type DateRangeFilterValue = [string | null, string | null];\n\nconst DATE_ONLY = /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})$/;\n\nfunction localDayStart(value: string): number | undefined {\n const match = DATE_ONLY.exec(value);\n\n if (!match) {\n return undefined;\n }\n\n const year = Number(match.groups?.year);\n const month = Number(match.groups?.month) - 1;\n const day = Number(match.groups?.day);\n const date = new Date(year, month, day);\n\n if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {\n return undefined;\n }\n\n return date.getTime();\n}\n\nfunction dateValueTime(value: string | number | Date): number {\n if (typeof value === \"string\") {\n const localTime = localDayStart(value);\n\n if (localTime !== undefined) {\n return localTime;\n }\n }\n\n return new Date(value).getTime();\n}\n\nfunction parsedTime(value: string): number | undefined {\n const time = new Date(value).getTime();\n\n return Number.isNaN(time) ? undefined : time;\n}\n\n/**\n * Inclusive [from, to] match over anything `new Date()` can parse. Date-only values and bounds\n * use local calendar days; their upper bound is the next local midnight so DST days stay exact.\n * Full timestamp bounds retain their exact instant.\n */\nconst dateRange: FilterFn<any, any> = (row, columnId, filterValue: DateRangeFilterValue) => {\n const raw = row.getValue(columnId);\n\n if (raw === null || raw === undefined || raw === \"\") {\n return false;\n }\n\n if (!Array.isArray(filterValue)) {\n return false;\n }\n\n const time = dateValueTime(raw as string | number | Date);\n\n if (Number.isNaN(time)) {\n return false;\n }\n\n const [from, to] = filterValue;\n\n if (from) {\n const fromTime = localDayStart(from) ?? parsedTime(from);\n\n if (fromTime !== undefined && time < fromTime) {\n return false;\n }\n }\n\n if (to) {\n const localToTime = localDayStart(to);\n\n if (localToTime === undefined) {\n const toTime = parsedTime(to);\n\n if (toTime !== undefined && time > toTime) {\n return false;\n }\n } else {\n const nextDay = new Date(localToTime);\n nextDay.setDate(nextDay.getDate() + 1);\n\n if (time >= nextDay.getTime()) {\n return false;\n }\n }\n }\n\n return true;\n};\n\ndateRange.autoRemove = (value: DateRangeFilterValue | undefined) => !value || (!value[0] && !value[1]);\n\n/**\n * Strict set membership for the multi-select variant. No TanStack built-in covers both cell\n * shapes exactly: `arrIncludesSome` rejects non-array row values outright, `arrHas` rejects\n * array cells, and `arrIncludes` substring-matches strings (\"active\" would match \"inactive\") —\n * the variant's semantics are exact membership for scalar and array cells.\n */\nconst oneOf: FilterFn<any, any> = (row, columnId, filterValue: string[]) => {\n const raw = row.getValue(columnId);\n\n if (raw === null || raw === undefined || !Array.isArray(filterValue)) {\n return false;\n }\n\n const values = Array.isArray(raw) ? raw : [raw];\n\n return values.some(value => value !== null && value !== undefined && filterValue.includes(String(value)));\n};\n\noneOf.autoRemove = (value: string[] | undefined) => !value || value.length === 0;\n\nexport const ledgerFilterFns = {\n \"ledger-date-range\": dateRange,\n \"ledger-one-of\": oneOf\n};\n\nexport type LedgerFilterFnId\n = | \"includesString\"\n | \"equalsString\"\n | \"inNumberRange\"\n | \"ledger-one-of\"\n | \"ledger-date-range\";\n\n/**\n * TanStack built-in (or ledger-registered) filter function id per filter variant.\n */\nexport const filterFnByVariant: Record<DataTableFilterVariant, LedgerFilterFnId> = {\n text: \"includesString\",\n select: \"equalsString\",\n \"multi-select\": \"ledger-one-of\",\n range: \"inNumberRange\",\n \"date-range\": \"ledger-date-range\"\n};\n","import { useCallback, useInsertionEffect, useRef } from \"react\";\n\nconst CSS_SAFE_CHARACTER = /^[a-z0-9-]$/i;\n\n/**\n * Column ids are consumer-supplied; CSS custom property names must stay ident-safe.\n */\nfunction cssSafeColumnId(columnId: string): string {\n let encoded = \"\";\n\n for (const character of columnId) {\n encoded += CSS_SAFE_CHARACTER.test(character)\n ? character\n : `_${character.codePointAt(0)!.toString(16)}_`;\n }\n\n // TanStack column ids are normally non-empty, but keeping the encoder total avoids emitting an\n // invalid custom-property suffix if a custom feature supplies an empty id.\n return encoded || \"_empty_\";\n}\n\nexport function columnWidthVar(columnId: string): string {\n return `--ledger-col-width-${cssSafeColumnId(columnId)}`;\n}\n\n/**\n * Pinned offset variables — written table-level with the width vars, referenced by cells.\n */\nexport function columnStartVar(columnId: string): string {\n return `--ledger-col-start-${cssSafeColumnId(columnId)}`;\n}\n\nexport function columnAfterVar(columnId: string): string {\n return `--ledger-col-after-${cssSafeColumnId(columnId)}`;\n}\n\nexport function toPx(value: number | string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\n/**\n * Whether a commit handler answered with a promise. Editing commits are `boolean | Promise<boolean>`\n * throughout, and both the session and the editors have to tell the two apart.\n */\nexport function isPromiseLike<T>(value: T | PromiseLike<T>): value is PromiseLike<T> {\n return typeof value === \"object\" && value !== null && \"then\" in value && typeof value.then === \"function\";\n}\n\n/**\n * Stable-identity event callback (the classic useEvent shape) for handlers stored in table meta.\n *\n * Two shapes, because most call sites wrap a handler that always exists: those keep the result\n * type they wrote, while wrapping a consumer's optional prop widens it with the `undefined` a\n * missing handler answers with. One overload each, so a caller never has to assert the widening\n * away — the assertions that used to do it were the only thing standing between an internal\n * session's `boolean | Promise<boolean>` contract and the type system agreeing with it.\n */\nexport function useEventCallback<Args extends unknown[], Result>(\n handler: (...args: Args) => Result\n): (...args: Args) => Result;\nexport function useEventCallback<Args extends unknown[], Result>(\n handler: ((...args: Args) => Result) | undefined\n): (...args: Args) => Result | undefined;\n\nexport function useEventCallback<Args extends unknown[], Result>(\n handler: ((...args: Args) => Result) | undefined\n): (...args: Args) => Result | undefined {\n const handlerRef = useRef(handler);\n\n useInsertionEffect(() => {\n handlerRef.current = handler;\n });\n\n return useCallback((...args: Args) => handlerRef.current?.(...args), []);\n}\n","import type { PointerSensorOptions } from \"@dnd-kit/dom\";\nimport type { DragEndEvent, DragMoveEvent, DragStartEvent } from \"@dnd-kit/react\";\n/**\n * Row drag reordering (docs/rows.md#row-ordering). Row order IS data order — there is no order\n * state — so ledger owns the interaction (the handle column, the session, the drop indicator,\n * the announcements) and hands the completed move to `onRowReorder`; the application reorders\n * `data`.\n *\n * Two input channels feed one session:\n *\n * - Pointer drags ride dnd-kit — the columns panel's dependency — for what is expensive to\n * hand-roll: activation constraints, edge auto-scrolling, cursor and selection suppression.\n * The drop target is ledger's own math over the rendered rows, not droppables: per-row\n * droppables would re-register on every virtualizer round-trip, and the sortable plugin's\n * optimistic DOM moves would break the one-`<tr>`-per-virtual-item invariant. The Feedback\n * and Accessibility plugins stay out for the same reason — the row ghost and the live\n * region are ledger's, fed from `labels`.\n * - The keyboard steps the insertion index directly (Space lifts, ↑/↓ move, Home/End jump,\n * Space drops, Escape cancels; blur abandons) — exact positions, not synthetic pixels.\n *\n * Session state lives up in `DataTable`, so the affected rows re-render through their own\n * memoized props; the row ghost and the live region are written imperatively — a pointer\n * move never re-renders the table.\n */\nimport type { RowData } from \"@tanstack/react-table\";\nimport type { KeyboardEvent, ReactNode, RefObject } from \"react\";\n\nimport type { DataTableRowReorder, Row, TableInstance } from \"./types\";\n\nimport { AutoScroller, Cursor, PointerActivationConstraints, PreventSelection } from \"@dnd-kit/dom\";\nimport {\n DragDropProvider,\n PointerSensor,\n useDraggable\n\n} from \"@dnd-kit/react\";\nimport { ActionIcon, Portal, Tooltip, VisuallyHidden } from \"@mantine/core\";\nimport { useMemo, useRef, useState } from \"react\";\n\nimport { useDataTableContext } from \"./context\";\nimport { useEventCallback } from \"./utils\";\n\n/**\n * The 5px house threshold (use-column-reorder.ts) keeps a plain click from lifting the row —\n * a lift is announced, and a click should say nothing. Touch keeps the press-and-hold delay\n * that separates dragging from scrolling.\n */\nconst activationConstraints: PointerSensorOptions[\"activationConstraints\"] = event => event.pointerType === \"touch\"\n ? [new PointerActivationConstraints.Delay({ value: 250, tolerance: 5 })]\n : [new PointerActivationConstraints.Distance({ value: 5 })];\n\nexport const ROW_REORDER_SENSORS = [PointerSensor.configure({ activationConstraints })];\nexport const ROW_REORDER_PLUGINS = [AutoScroller, Cursor, PreventSelection];\n\nexport interface RowReorderTarget {\n rowId: string;\n side: \"before\" | \"after\";\n}\n\n/**\n * The keyboard half of the session, handed to the handle cells through the render context. The\n * handlers are stable event callbacks; `active` reads the live session, so a handle can answer\n * \"do the keys belong to me\" in the render that draws it.\n */\nexport interface RowReorderKeyboard {\n lift: (rowId: string) => void;\n move: (delta: 1 | -1) => void;\n moveToEdge: (edge: \"start\" | \"end\") => void;\n drop: () => void;\n cancel: () => void;\n active: (rowId: string) => boolean;\n}\n\nexport interface RowReorderSession {\n /**\n * The row a live drag lifted, either channel. Rows render `data-dragging` from it.\n */\n sourceId: string | null;\n /**\n * Where the lifted row would land — `null` while the drop would change nothing. The target\n * row renders the indicator (`data-drop-side`).\n */\n target: RowReorderTarget | null;\n providerProps: {\n onDragStart: (event: DragStartEvent) => void;\n onDragMove: (event: DragMoveEvent) => void;\n onDragEnd: (event: DragEndEvent) => void;\n };\n keyboard: RowReorderKeyboard;\n /**\n * True once a pointer drag has actually moved — the overlay mounts the ghost from it, and\n * its late start is also what keeps a bare click silent.\n */\n ghostActive: boolean;\n attachGhost: (element: HTMLDivElement | null) => void;\n announcerRef: RefObject<HTMLSpanElement | null>;\n}\n\nexport interface RowReorderInput<TData extends RowData> {\n onRowReorder: ((reorder: DataTableRowReorder<TData>) => void) | undefined;\n labels: {\n rowReorderLifted: (row: string) => string;\n rowReorderTarget: (row: string, side: \"before\" | \"after\") => string;\n rowReorderDropped: (row: string) => string;\n rowReorderCanceled: string;\n };\n /**\n * The body scroll viewport — the element whose rendered `<tr>`s the pointer math reads.\n */\n viewportRef: RefObject<HTMLElement | null>;\n /**\n * The center rows of the committed display, in display order (pinned rows are not part of a\n * data-order move). Read once per lift into the session snapshot.\n */\n getCenterRows: () => Array<Row<TData>>;\n /**\n * Names a row the way the active-row announcements do — its leading visible cell.\n */\n nameRow: (row: Row<TData>) => string;\n /**\n * Keeps the keyboard target on screen, virtualized included.\n */\n scrollToRow: (rowId: string) => void;\n}\n\ninterface DragSnapshot<TData extends RowData> {\n via: \"pointer\" | \"keyboard\";\n sourceId: string;\n sourceName: string;\n fromIndex: number;\n /**\n * Keyboard stepping position in `toIndex` space; `fromIndex` means \"at rest\".\n */\n toIndex: number;\n rows: Array<Row<TData>>;\n rowsById: Map<string, Row<TData>>;\n}\n\nexport function useRowReorder<TData extends RowData>({\n onRowReorder,\n labels,\n viewportRef,\n getCenterRows,\n nameRow,\n scrollToRow\n}: RowReorderInput<TData>): RowReorderSession {\n const [sourceId, setSourceId] = useState<string | null>(null);\n const [target, setTargetState] = useState<RowReorderTarget | null>(null);\n const [ghostActive, setGhostActive] = useState(false);\n\n const snapshot = useRef<DragSnapshot<TData> | null>(null);\n const targetRef = useRef<RowReorderTarget | null>(null);\n const ghostRef = useRef<HTMLDivElement | null>(null);\n const ghostPosition = useRef({ x: 0, y: 0 });\n const ghostOrigin = useRef({ x: 0, y: 0 });\n const announcerRef = useRef<HTMLSpanElement | null>(null);\n\n const announce = useEventCallback((message: string) => {\n if (announcerRef.current) {\n announcerRef.current.textContent = message;\n }\n });\n\n /**\n * `arrayMove` semantics: the final index of the moved row once the drop lands `side` of the\n * target. `null` when the move would change nothing.\n */\n const resolveToIndex = (targetRow: Row<TData>, side: \"before\" | \"after\"): number | null => {\n const session = snapshot.current;\n\n if (!session) {\n return null;\n }\n\n const raw = targetRow.index + (side === \"after\" ? 1 : 0);\n const toIndex = raw > session.fromIndex ? raw - 1 : raw;\n\n return toIndex === session.fromIndex ? null : toIndex;\n };\n\n const setTarget = (next: RowReorderTarget | null) => {\n const { current } = targetRef;\n\n if (current?.rowId === next?.rowId && current?.side === next?.side) {\n return;\n }\n\n targetRef.current = next;\n setTargetState(next);\n\n if (next) {\n const row = snapshot.current?.rowsById.get(next.rowId);\n\n if (row) {\n announce(labels.rowReorderTarget(nameRow(row), next.side));\n }\n }\n };\n\n const begin = (via: \"pointer\" | \"keyboard\", rowId: string): DragSnapshot<TData> | null => {\n const rows = getCenterRows();\n const row = rows.find(candidate => candidate.id === rowId);\n\n if (!row) {\n return null;\n }\n\n const session: DragSnapshot<TData> = {\n via,\n sourceId: rowId,\n sourceName: nameRow(row),\n fromIndex: row.index,\n toIndex: row.index,\n rows,\n rowsById: new Map(rows.map(candidate => [candidate.id, candidate]))\n };\n snapshot.current = session;\n setSourceId(rowId);\n\n return session;\n };\n\n const finish = (canceled: boolean) => {\n const session = snapshot.current;\n const finalTarget = targetRef.current;\n\n if (session && !canceled) {\n if (finalTarget) {\n const row = session.rowsById.get(session.sourceId);\n const targetRow = session.rowsById.get(finalTarget.rowId);\n const toIndex = targetRow ? resolveToIndex(targetRow, finalTarget.side) : null;\n\n if (row && toIndex !== null) {\n onRowReorder?.({\n row,\n fromIndex: session.fromIndex,\n toIndex\n });\n }\n }\n\n announce(labels.rowReorderDropped(session.sourceName));\n } else if (session) {\n announce(labels.rowReorderCanceled);\n }\n\n snapshot.current = null;\n targetRef.current = null;\n setSourceId(null);\n setTargetState(null);\n setGhostActive(false);\n };\n\n /* ---- pointer channel (dnd-kit) ---- */\n\n const onDragStart = useEventCallback((event: DragStartEvent) => {\n const id = event.operation.source?.id;\n\n if (typeof id !== \"string\" || snapshot.current) {\n return;\n }\n\n begin(\"pointer\", id);\n });\n\n /**\n * The rendered center rows, read where they are drawn: virtualization renders a window, and\n * the rows that exist are exactly the ones a pointer can be over. Pinned rows are sticky\n * overlays of the same scroller, so a pointer inside their bands must not read as \"over the\n * row beneath\" — they bound the scan instead of joining it.\n */\n const pointerTarget = (y: number): RowReorderTarget | null => {\n const viewport = viewportRef.current;\n const session = snapshot.current;\n\n if (!viewport || !session) {\n return null;\n }\n\n const rows = viewport.querySelectorAll<HTMLTableRowElement>(\"tr[data-row-id]:not([data-pinned-row])\");\n const nearest = pointerDropEdge(rows, element => element.getBoundingClientRect(), y);\n\n if (!nearest) {\n return null;\n }\n\n const { rowId } = nearest.row.dataset;\n const row = rowId === undefined ? undefined : session.rowsById.get(rowId);\n\n if (rowId === undefined || !row || resolveToIndex(row, nearest.side) === null) {\n return null;\n }\n\n return { rowId, side: nearest.side };\n };\n\n const onDragMove = useEventCallback((event: DragMoveEvent) => {\n const session = snapshot.current;\n\n if (session?.via !== \"pointer\") {\n return;\n }\n\n const position = event.operation.position.current;\n ghostPosition.current = position;\n\n if (ghostRef.current) {\n ghostRef.current.style.transform = ghostTransform(position, ghostOrigin.current);\n }\n\n // The lift is announced here, on the first real move, so a plain click stays silent.\n if (!ghostActive) {\n setGhostActive(true);\n announce(labels.rowReorderLifted(session.sourceName));\n }\n\n setTarget(pointerTarget(position.y));\n });\n\n const onDragEnd = useEventCallback((event: DragEndEvent) => {\n if (snapshot.current?.via !== \"pointer\") {\n return;\n }\n\n finish(event.canceled);\n });\n\n /* ---- keyboard channel (index stepping) ---- */\n\n const step = (session: DragSnapshot<TData>, candidate: number) => {\n const last = session.rows.length - 1;\n const toIndex = Math.max(0, Math.min(last, candidate));\n\n if (toIndex === session.fromIndex || toIndex === session.toIndex) {\n return;\n }\n\n // Map the landing index back to the row that shows the indicator: landing below the source\n // means \"after that row\" (every row in between has shifted one up), above means \"before\".\n const row = session.rows[toIndex];\n\n if (!row) {\n return;\n }\n\n session.toIndex = toIndex;\n setTarget({ rowId: row.id, side: toIndex > session.fromIndex ? \"after\" : \"before\" });\n scrollToRow(row.id);\n };\n\n const lift = useEventCallback((rowId: string) => {\n if (snapshot.current) {\n return;\n }\n\n const session = begin(\"keyboard\", rowId);\n\n if (session) {\n announce(labels.rowReorderLifted(session.sourceName));\n }\n });\n\n const move = useEventCallback((delta: 1 | -1) => {\n const session = snapshot.current;\n\n if (session?.via !== \"keyboard\") {\n return;\n }\n\n // Skip over the at-rest position — stepping back onto it would show nothing; Escape is how\n // a lift returns home.\n let candidate = session.toIndex + delta;\n\n if (candidate === session.fromIndex) {\n candidate += delta;\n }\n\n step(session, candidate);\n });\n\n const moveToEdge = useEventCallback((edge: \"start\" | \"end\") => {\n const session = snapshot.current;\n\n if (session?.via !== \"keyboard\") {\n return;\n }\n\n step(session, edge === \"start\" ? 0 : session.rows.length - 1);\n });\n\n const drop = useEventCallback(() => {\n if (snapshot.current?.via === \"keyboard\") {\n finish(false);\n }\n });\n\n const cancel = useEventCallback(() => {\n if (snapshot.current?.via === \"keyboard\") {\n finish(true);\n }\n });\n\n const keyboardActive = useEventCallback(\n (rowId: string) => snapshot.current?.via === \"keyboard\" && snapshot.current.sourceId === rowId\n );\n\n const attachGhost = useEventCallback((element: HTMLDivElement | null) => {\n ghostRef.current = element;\n\n if (!element) {\n return;\n }\n\n // Built once per lift: the ghost is a DOM snapshot of the whole source row — the source\n // table's shell around the cloned `<tr>`, under per-column pixel widths read from the live\n // cells (the width variables live on the ledger root and cannot reach the portal) — so a\n // pointer move stays a pure transform write and no live cell ever renders twice.\n const session = snapshot.current;\n const source = session\n ? viewportRef.current?.querySelector<HTMLTableRowElement>(\n `tr[data-row-id=\"${CSS.escape(session.sourceId)}\"]`\n )\n : null;\n const sourceTable = source?.closest(\"table\");\n\n if (source && sourceTable) {\n const ghostTable = sourceTable.cloneNode(false) as HTMLTableElement;\n ghostTable.style.width = `${sourceTable.getBoundingClientRect().width}px`;\n\n const colgroup = document.createElement(\"colgroup\");\n\n for (const cell of source.cells) {\n const col = document.createElement(\"col\");\n col.style.width = `${cell.getBoundingClientRect().width}px`;\n colgroup.append(col);\n }\n\n const body = document.createElement(\"tbody\");\n const rowClone = source.cloneNode(true) as HTMLTableRowElement;\n delete rowClone.dataset.dragging;\n body.append(rowClone);\n ghostTable.append(colgroup, body);\n element.replaceChildren(ghostTable);\n\n // Anchored to where the row was lifted from, so the ghost reads as the row itself\n // coming off the table under the pointer's grab point.\n const rowRect = source.getBoundingClientRect();\n ghostOrigin.current = {\n x: rowRect.left - ghostPosition.current.x,\n y: rowRect.top - ghostPosition.current.y\n };\n }\n\n // Positioned before its first paint — a ghost that mounts at the portal origin and then\n // jumps to the pointer is exactly the drift the imperative transform exists to avoid.\n element.style.transform = ghostTransform(ghostPosition.current, ghostOrigin.current);\n });\n\n // Stable — every handler is an event callback — so the render context carrying it holds.\n const keyboard = useMemo<RowReorderKeyboard>(\n () => {\n return {\n active: keyboardActive,\n cancel,\n drop,\n lift,\n move,\n moveToEdge\n };\n },\n [keyboardActive, cancel, drop, lift, move, moveToEdge]\n );\n\n return {\n sourceId,\n target,\n providerProps: {\n onDragEnd,\n onDragMove,\n onDragStart\n },\n keyboard,\n ghostActive,\n attachGhost,\n announcerRef\n };\n}\n\n/**\n * The drop edge a pointer at `y` indicates, scanned top to bottom over the rendered rows: above\n * every row reads \"before\" the first, inside a row splits at its midline, the gap between two\n * rows belongs to the row above, and below every row reads \"after\" the last. Zero-height rows\n * never claim the pointer. Pure over `measure` — the session feeds it live rects, and reads\n * lazily so the scan still stops at the row under the pointer.\n */\nexport function pointerDropEdge<T>(\n rows: Iterable<T>,\n measure: (row: T) => { top: number; bottom: number },\n y: number\n): { row: T; side: \"before\" | \"after\" } | null {\n let nearest: { row: T; side: \"before\" | \"after\" } | null = null;\n\n for (const row of rows) {\n const { top, bottom } = measure(row);\n\n if (bottom <= top) {\n continue;\n }\n\n if (y < top) {\n nearest ??= { row, side: \"before\" };\n\n break;\n }\n\n nearest = { row, side: y < (top + bottom) / 2 ? \"before\" : \"after\" };\n\n if (y <= bottom) {\n break;\n }\n }\n\n return nearest;\n}\n\nfunction ghostTransform(\n { x, y }: { x: number; y: number },\n origin: { x: number; y: number }\n): string {\n return `translate(${Math.round(x + origin.x)}px, ${Math.round(y + origin.y)}px)`;\n}\n\n/**\n * Mounts the pointer channel around the table when the gate is on: dnd-kit's provider (context\n * for the handles' draggables), the session's handlers, and the overlay. Renders no DOM of its\n * own, so the table markup is byte-identical either way.\n */\nexport function RowReorderScope({ session, children }: { session: RowReorderSession | null; children: ReactNode }) {\n if (!session) {\n return children;\n }\n\n return (\n <DragDropProvider plugins={ROW_REORDER_PLUGINS} sensors={ROW_REORDER_SENSORS} {...session.providerProps}>\n {children}\n <RowReorderOverlay session={session} />\n </DragDropProvider>\n );\n}\n\n/**\n * The pointer ghost and the live region, portaled out of the ARIA table (a `role=\"table\"` may\n * only own rows; a fixed-position ghost inside the scroller would clip and shear under sticky\n * transforms). The ghost's content is the row snapshot `attachGhost` clones in, and it is\n * `aria-hidden`: the live region already narrates the drag.\n */\nfunction RowReorderOverlay({ session }: { session: RowReorderSession }) {\n const { getStyles } = useDataTableContext();\n\n return (\n <Portal>\n <VisuallyHidden ref={session.announcerRef} aria-live=\"polite\" role=\"status\" />\n {session.ghostActive && <div ref={session.attachGhost} aria-hidden {...getStyles(\"rowDragOverlay\")} />}\n </Portal>\n );\n}\n\n/**\n * The injected handle cell. The pointer half hands the button to dnd-kit as the draggable;\n * the keyboard half drives the session's index stepping directly. Disabled — visually and for\n * both channels — while something else controls the visible order, with the tooltip saying\n * why (docs/rows.md#row-ordering).\n */\nexport function RowDragCell<TData extends RowData>({ row, table }: { row: Row<TData>; table: TableInstance<TData> }) {\n const {\n labels,\n icons,\n rowReorderKeyboard\n } = useDataTableContext();\n const orderable = table.options.meta?.ledger?.rowOrdering.orderable === true;\n\n // A pinned row's order is pinning state, not data order (docs/rows.md#row-ordering): it cannot\n // be lifted and is never a drop target, so it carries no handle at all. Gated on the switch,\n // not the state alone — with `enableRowPinning` off the zones never split, and a leftover\n // `rowPinning` value renders as an ordinary, draggable center row.\n const pinned = table.options.enableRowPinning === true && row.getIsPinned() !== false;\n\n // No Feedback plugin runs (ROW_REORDER_PLUGINS): the handle stays put and the session's own\n // row ghost is the drag's visual.\n const { ref, isDragSource } = useDraggable({\n id: row.id,\n disabled: !orderable || pinned\n });\n\n if (pinned) {\n return null;\n }\n\n const lifted = rowReorderKeyboard?.active(row.id) === true;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const keyboard = rowReorderKeyboard;\n\n if (!keyboard || !orderable) {\n return;\n }\n\n const { key } = event;\n\n if (key === \" \" || key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n\n if (lifted) {\n keyboard.drop();\n } else {\n keyboard.lift(row.id);\n }\n\n return;\n }\n\n // The remaining keys belong to a live lift alone — an idle handle leaves them to the page.\n if (!lifted) {\n return;\n }\n\n switch (key) {\n case \"ArrowUp\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.move(-1);\n\n break;\n }\n\n case \"ArrowDown\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.move(1);\n\n break;\n }\n\n case \"Home\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.moveToEdge(\"start\");\n\n break;\n }\n\n case \"End\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.moveToEdge(\"end\");\n\n break;\n }\n\n case \"Escape\": {\n event.preventDefault();\n event.stopPropagation();\n keyboard.cancel();\n\n break;\n }\n // No default\n }\n };\n\n return (\n <Tooltip disabled={isDragSource || lifted} label={orderable ? labels.reorderRow : labels.rowOrderingUnavailable} openDelay={500}>\n <ActionIcon\n ref={ref}\n aria-disabled={!orderable || undefined}\n aria-label={labels.reorderRow}\n aria-pressed={lifted || undefined}\n color=\"gray\"\n size=\"sm\"\n variant=\"subtle\"\n onBlur={() => {\n // A keyboard lift is bound to the handle that owns the keys — focus leaving it would\n // strand a session nothing can reach.\n if (lifted) {\n rowReorderKeyboard?.cancel();\n }\n }}\n onKeyDown={handleKeyDown}\n >\n <icons.reorderRow size={14} />\n </ActionIcon>\n </Tooltip>\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { MouseEvent } from \"react\";\n\nimport type { Row, TableInstance } from \"./types\";\n\n/**\n * The injected selection column's header and body cells. Both stop propagation so selection\n * never triggers `onRowClick` (docs/rows.md). Shift-range selection keeps TanStack v9's\n * semantics (`enableRowRangeSelection`, on by default): an ordinary click sets the anchor, a\n * Shift-click applies the display-order range, non-selectable rows excluded. What it never keeps\n * is v9's route to them — `getToggleSelectedHandler()` resolves the gate, the anchor and the\n * display order from the shared core when the click arrives, which is whatever render pass ran\n * last. The controller answers from the commit instead (`use-row-commands.ts`).\n */\nimport { Checkbox, Radio } from \"@mantine/core\";\n\nimport { useDataTableContext } from \"./context\";\n\nfunction noop() {\n // Selection is applied in onClick (where shiftKey exists); the controlled checkbox still\n // needs an onChange to satisfy React's controlled-input contract.\n}\n\nexport function SelectionHeaderCell<TData extends RowData>({ table }: { table: TableInstance<TData> }) {\n const { labels, selection } = useDataTableContext();\n\n if (table.options.enableMultiRowSelection === false) {\n return null;\n }\n\n const scope = table.options.meta?.ledger?.selectAllScope ?? \"all\";\n const allSelected = scope === \"page\" ? table.getIsAllPageRowsSelected() : table.getIsAllRowsSelected();\n // v9 semantics: \"some\" means \"at least one\" and stays true at full selection — the\n // indeterminate glyph must therefore be gated on the matching all-selected check.\n const someSelected = scope === \"page\" ? table.getIsSomePageRowsSelected() : table.getIsSomeRowsSelected();\n\n return (\n <Checkbox\n aria-label={labels.selectAllRows}\n checked={allSelected}\n indeterminate={!allSelected && someSelected}\n size=\"xs\"\n onChange={noop}\n onClick={(event: MouseEvent<HTMLInputElement>) => {\n event.stopPropagation();\n // What the box shows is what clicking it departs from — resolved by this render, never\n // asked of the table again when the click lands.\n selection?.toggleAll(scope, !allSelected);\n }}\n />\n );\n}\n\nexport function SelectionCell<TData extends RowData>({ row }: { row: Row<TData> }) {\n const {\n labels,\n instanceId,\n selection\n } = useDataTableContext();\n const selected = row.getIsSelected();\n\n const select = (event: MouseEvent<HTMLInputElement>) => {\n event.stopPropagation();\n selection?.toggle(\n row as Row<any>,\n event.currentTarget.checked,\n event.shiftKey || event.nativeEvent.shiftKey\n );\n };\n\n // Single-select is a radio group, not a lone checkbox: one choice at a time is what a radio\n // means, and the shared name makes the rendered rows one group for the platform. (Under\n // virtualization only the mounted window is in that group — the same boundary as autosize.)\n if (row.getCanMultiSelect() === false) {\n return (\n <Radio\n aria-label={labels.selectRow}\n checked={selected}\n disabled={!row.getCanSelect()}\n name={`${instanceId}-selection`}\n size=\"xs\"\n onChange={noop}\n onClick={select}\n />\n );\n }\n\n return (\n <Checkbox\n aria-label={labels.selectRow}\n checked={selected}\n disabled={!row.getCanSelect()}\n // Sub-row selection (escape hatch `enableSubRowSelection`): a parent with a partly\n // selected subtree reads as indeterminate.\n indeterminate={!selected && row.getIsSomeSelected()}\n size=\"xs\"\n onChange={noop}\n onClick={select}\n />\n );\n}\n","/**\n * Column preprocessing for `useDataTable`: inject the selection and expander columns (pinned\n * left, fixed width, excluded from every data feature) and derive `filterFn`s from\n * `meta.filter` variants for columns that declare none themselves.\n */\nimport type { RowData } from \"@tanstack/react-table\";\n\nimport type { Column, ColumnDef, TableInstance } from \"./types\";\n\nimport { ExpanderCell, ExpanderHeaderCell } from \"./expander\";\nimport { filterFnByVariant } from \"./filter-fns\";\nimport { RowDragCell } from \"./row-reorder\";\nimport { SelectionCell, SelectionHeaderCell } from \"./selection\";\n\nexport const ROW_DRAG_COLUMN_ID = \"ledger:row-drag\";\nexport const SELECTION_COLUMN_ID = \"ledger:select\";\nexport const EXPANDER_COLUMN_ID = \"ledger:expander\";\n\nexport function isInternalColumn(columnId: string): boolean {\n return columnId === ROW_DRAG_COLUMN_ID || columnId === SELECTION_COLUMN_ID || columnId === EXPANDER_COLUMN_ID;\n}\n\n/**\n * Human-readable column title for every plain-text surface — the columns panel, CSV headers,\n * filter and editor field names. An explicit `meta.label` wins; otherwise the string `header`;\n * a render-function header falls back to the column id, which is why such columns should\n * declare a `meta.label`.\n */\nexport function columnHeaderText<TData extends RowData>(column: Column<TData, unknown>): string {\n const { header, meta } = column.columnDef;\n\n return meta?.label ?? (typeof header === \"string\" ? header : column.id);\n}\n\nexport interface BuildColumnsInput<TData extends RowData> {\n\n columns: Array<ColumnDef<TData, any>>;\n withRowDrag: boolean;\n withSelection: boolean;\n withExpander: boolean;\n rowDragColumn?: Partial<ColumnDef<TData, unknown>>;\n selectionColumn?: Partial<ColumnDef<TData, unknown>>;\n expanderColumn?: Partial<ColumnDef<TData, unknown>>;\n}\n\n/**\n * Author-declared sizing, snapshotted per leaf definition BEFORE TanStack merges its default\n * column def (size 150, minSize 20) into every `column.columnDef` — after that merge, \"the\n * author declared no size\" is indistinguishable from \"the author chose 150\". The width engine\n * (docs/sizing.md) reads this registry through the per-column meta clone created below.\n */\nexport interface RawColumnSizing {\n size: number | undefined;\n minSize: number | undefined;\n maxSize: number | undefined;\n}\n\nconst rawSizingByMeta = new WeakMap<object, RawColumnSizing>();\n\nexport function rawColumnSizing(columnDef: { meta?: object }): RawColumnSizing | undefined {\n return columnDef.meta ? rawSizingByMeta.get(columnDef.meta) : undefined;\n}\n\n/**\n * The per-column `enableResizing` knob rides ledger's `ColumnDef` alias — the TanStack module\n * that would declare it (`columnResizingFeature`) is deliberately unregistered — so reads off\n * the resolved instance definition narrow here.\n */\nexport function columnEnableResizing(columnDef: object): boolean | undefined {\n return (columnDef as { enableResizing?: boolean }).enableResizing;\n}\n\n/**\n * An injected column is an ordinary def, so an override is an ordinary merge — the author's keys\n * win over ledger's defaults. The id alone is reserved: `isInternalColumn` is how the render\n * layer recognizes these columns (centered content, stop-propagation, excluded from CSV and the\n * columns panel), so it is reapplied last.\n */\nfunction injectedColumn<TData extends RowData>(\n defaults: ColumnDef<TData, any>,\n override: Partial<ColumnDef<TData, unknown>> | undefined\n): ColumnDef<TData, any> {\n return processLeaf(\n override\n ? {\n ...defaults,\n ...override,\n id: defaults.id\n } as ColumnDef<TData, any>\n : defaults\n );\n}\n\nexport function buildColumns<TData extends RowData>({\n columns,\n withRowDrag,\n withSelection,\n withExpander,\n rowDragColumn,\n selectionColumn,\n expanderColumn\n}: BuildColumnsInput<TData>): Array<ColumnDef<TData, any>> {\n const result: Array<ColumnDef<TData, any>> = [];\n\n if (withRowDrag) {\n result.push(injectedColumn<TData>({\n id: ROW_DRAG_COLUMN_ID,\n size: 36,\n minSize: 36,\n maxSize: 36,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableGrouping: false,\n // A header with nothing to say: the handles below explain themselves, and the drag\n // column offers no all-rows action the way selection's header checkbox does.\n header: () => null,\n cell: ({ row, table }) => <RowDragCell row={row} table={table as TableInstance<TData>} />\n }, rowDragColumn));\n }\n\n if (withSelection) {\n result.push(injectedColumn<TData>({\n id: SELECTION_COLUMN_ID,\n size: 40,\n minSize: 40,\n maxSize: 40,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableGrouping: false,\n // Contexts carry the core `Table` type, but the runtime object IS the adapter-augmented\n // instance — the assertion narrows the type to what actually exists.\n header: ({ table }) => <SelectionHeaderCell table={table as TableInstance<TData>} />,\n cell: ({ row }) => <SelectionCell row={row} />\n }, selectionColumn));\n }\n\n if (withExpander) {\n result.push(injectedColumn<TData>({\n id: EXPANDER_COLUMN_ID,\n size: 36,\n minSize: 36,\n maxSize: 36,\n enableSorting: false,\n enableHiding: false,\n enableResizing: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n enableGrouping: false,\n header: ({ table }) => <ExpanderHeaderCell table={table as TableInstance<TData>} />,\n cell: ({ row }) => <ExpanderCell row={row} />\n }, expanderColumn));\n }\n\n for (const column of columns) {\n result.push(processColumn(column));\n }\n\n return result;\n}\n\n/**\n * Group definitions recurse so every LEAF gets processed — its raw sizing registered and its\n * `meta.filter` variant mapped.\n */\nfunction processColumn<TData extends RowData>(column: ColumnDef<TData, any>): ColumnDef<TData, any> {\n if (\"columns\" in column && Array.isArray(column.columns)) {\n return { ...column, columns: column.columns.map(child => processColumn(child)) };\n }\n\n return processLeaf(column);\n}\n\nfunction processLeaf<TData extends RowData>(column: ColumnDef<TData, any>): ColumnDef<TData, any> {\n // A fresh meta clone per leaf keys the raw-sizing registry (and survives TanStack's merge).\n const meta = { ...column.meta };\n rawSizingByMeta.set(meta, {\n size: column.size,\n minSize: column.minSize,\n maxSize: column.maxSize\n });\n\n return withVariantFilterFn({ ...column, meta });\n}\n\nfunction withVariantFilterFn<TData extends RowData>(column: ColumnDef<TData, any>): ColumnDef<TData, any> {\n const filter = column.meta?.filter;\n\n if (!filter || typeof filter === \"function\" || column.filterFn) {\n return column;\n }\n\n const variant = typeof filter === \"string\" ? filter : filter.variant;\n\n return { ...column, filterFn: filterFnByVariant[variant] };\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { TableInstance } from \"./types\";\n\nimport { isInternalColumn } from \"./build-columns\";\n\n/**\n * Pure edits over TanStack's flat `columnOrder` array, shared by the two affordances that\n * reorder columns: the header drag (`use-column-reorder.ts`) and the columns panel\n * (`columns-panel.tsx`).\n *\n * The flat array is the ONLY thing `columnOrder` governs — a pinned column's position comes from\n * its index inside `columnPinning.start` / `.end` instead (TanStack's `getStartLeafColumns` maps\n * over that array, while `getCenterLeafColumns` filters the `columnOrder`-sorted leaf list). So\n * reordering the center zone edits `columnOrder`, and reordering a pinned zone edits\n * `columnPinning` — never both.\n */\n\n/**\n * The flat order to edit from: the state order stripped of ids the table no longer defines, with\n * any column it never mentioned appended in definition order. An empty slice means \"definition\n * order\", which is exactly `getAllLeafColumns()`.\n */\nexport function resolveColumnOrder<TData extends RowData>(table: TableInstance<TData>): string[] {\n const leafIds = table.getAllLeafColumns().map(column => column.id);\n // Slice atoms exist on both the hook wrapper and the core instance handed to header renderers.\n const columnOrder = table.atoms.columnOrder.get();\n\n if (columnOrder.length === 0) {\n return leafIds;\n }\n\n return [\n ...columnOrder.filter(id => leafIds.includes(id)),\n ...leafIds.filter(id => !columnOrder.includes(id))\n ];\n}\n\nexport interface ColumnDropTarget {\n id: string;\n side: \"before\" | \"after\";\n}\n\nexport type ColumnZone = \"start\" | \"center\" | \"end\";\n\nexport function getColumnZone<TData extends RowData>(table: TableInstance<TData>, columnId: string): ColumnZone | null {\n const pinned = table.getColumn(columnId)?.getIsPinned();\n\n return pinned === \"start\" || pinned === \"end\" ? pinned : pinned === false ? \"center\" : null;\n}\n\n/**\n * Move `columnId` to sit immediately before or after `target.id`. Returns the input untouched\n * when the target is no longer part of the order.\n */\nexport function moveColumnBeside(order: string[], columnId: string, target: ColumnDropTarget): string[] {\n const without = order.filter(id => id !== columnId);\n const targetIndex = without.indexOf(target.id);\n\n if (targetIndex === -1) {\n return order;\n }\n\n const insertAt = target.side === \"before\" ? targetIndex : targetIndex + 1;\n\n return [...without.slice(0, insertAt), columnId, ...without.slice(insertAt)];\n}\n\n/**\n * Rewrite the flat order so the center columns read `nextCenterIds`, leaving every pinned column\n * in the slot it already occupies: each center slot takes the next id off the new sequence.\n * Pinned ids keep their flat positions because those positions are inert — a pinned column\n * renders from its `columnPinning` index, not from here.\n */\nexport function applyCenterOrder(order: string[], nextCenterIds: string[]): string[] {\n const centerIds = new Set(nextCenterIds);\n const queue = [...nextCenterIds];\n\n return order.map(id => centerIds.has(id) ? queue.shift()! : id);\n}\n\n/**\n * Reorder a header inside its current display zone. Pin controls are the only way to cross a\n * zone boundary; a drop across one is rejected so the visual affordance never lies.\n */\nexport function reorderColumnWithinZone<TData extends RowData>(\n table: TableInstance<TData>,\n columnId: string,\n target: ColumnDropTarget\n): boolean {\n const zone = getColumnZone(table, columnId);\n\n if (!zone || getColumnZone(table, target.id) !== zone) {\n return false;\n }\n\n if (zone === \"center\") {\n const centerIds = table.getCenterLeafColumns()\n .map(column => column.id)\n .filter(id => !isInternalColumn(id));\n const nextCenterIds = moveColumnBeside(centerIds, columnId, target);\n\n table.setColumnOrder(applyCenterOrder(resolveColumnOrder(table), nextCenterIds));\n\n return true;\n }\n\n const start = table.getStartLeafColumns()\n .map(column => column.id)\n .filter(id => !isInternalColumn(id));\n const end = table.getEndLeafColumns()\n .map(column => column.id)\n .filter(id => !isInternalColumn(id));\n const zoneOrder = zone === \"start\" ? start : end;\n const nextZoneOrder = moveColumnBeside(zoneOrder, columnId, target);\n\n table.setColumnPinning({\n start: zone === \"start\" ? nextZoneOrder : start,\n end: zone === \"end\" ? nextZoneOrder : end\n });\n\n return true;\n}\n","import type { ComponentType, SVGProps } from \"react\";\n\n/**\n * The table chrome's glyphs and the `icons` registry that swaps them (docs/styling.md#icons).\n *\n * The defaults are vendored from Lucide (https://lucide.dev): path data copied verbatim from\n * `lucide-static` v1.34.0, so there is no icon-library dependency and the set is a default, not\n * a lock — any component satisfying `DataTableIconProps` slots in, and `lucide-react` components\n * satisfy it as-is.\n *\n * License of the vendored path data — ISC, Copyright (c) 2026 Lucide Icons and Contributors:\n * permission to use, copy, modify, and/or distribute this software for any purpose with or\n * without fee is hereby granted, provided that the above copyright notice and this permission\n * notice appear in all copies. The chevron, search and x glyphs are derived from Feather\n * (MIT, Copyright (c) 2013-present Cole Bemis).\n */\ninterface IconProps extends SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nfunction Icon({\n size = 16,\n children,\n ...others\n}: IconProps) {\n return (\n <svg\n aria-hidden\n fill=\"none\"\n height={size}\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n viewBox=\"0 0 24 24\"\n width={size}\n {...others}\n >\n {children}\n </svg>\n );\n}\n\n// Glyphs, named for their Lucide source icons. Module-private: components reach them through\n// the resolved registry, never directly.\n\nfunction IconInbox(props: IconProps) {\n return (\n <Icon {...props}>\n <polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n </Icon>\n );\n}\n\nfunction IconTriangleAlert(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </Icon>\n );\n}\n\nfunction IconChevronUp(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m18 15-6-6-6 6\" />\n </Icon>\n );\n}\n\nfunction IconChevronDown(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m6 9 6 6 6-6\" />\n </Icon>\n );\n}\n\nfunction IconChevronRight(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m9 18 6-6-6-6\" />\n </Icon>\n );\n}\n\nfunction IconChevronsUpDown(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m7 15 5 5 5-5\" />\n <path d=\"m7 9 5-5 5 5\" />\n </Icon>\n );\n}\n\nfunction IconFunnel(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z\" />\n </Icon>\n );\n}\n\nfunction IconGripVertical(props: IconProps) {\n return (\n <Icon {...props}>\n <circle cx=\"9\" cy=\"12\" r=\"1\" />\n <circle cx=\"9\" cy=\"5\" r=\"1\" />\n <circle cx=\"9\" cy=\"19\" r=\"1\" />\n <circle cx=\"15\" cy=\"12\" r=\"1\" />\n <circle cx=\"15\" cy=\"5\" r=\"1\" />\n <circle cx=\"15\" cy=\"19\" r=\"1\" />\n </Icon>\n );\n}\n\n/**\n * The three pin states speak one language — where the column sits relative to the table's edges\n * (a pushpin cannot say start from end, which is why `pin` / `pin-off` were passed over).\n */\nfunction IconArrowLeftToLine(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M3 19V5\" />\n <path d=\"m13 6-6 6 6 6\" />\n <path d=\"M7 12h14\" />\n </Icon>\n );\n}\n\nfunction IconArrowRightToLine(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M17 12H3\" />\n <path d=\"m11 18 6-6-6-6\" />\n <path d=\"M21 5v14\" />\n </Icon>\n );\n}\n\n/**\n * Neither edge: the column moves with the scroll again.\n */\nfunction IconMoveHorizontal(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m18 8 4 4-4 4\" />\n <path d=\"M2 12h20\" />\n <path d=\"m6 8-4 4 4 4\" />\n </Icon>\n );\n}\n\n/**\n * \"Put it back the way it was\": counter-clockwise is the industry's undo, clockwise its\n * refresh — the table shows both, so they must not be the same glyph.\n */\nfunction IconRotateCcw(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </Icon>\n );\n}\n\nfunction IconRotateCw(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\" />\n <path d=\"M21 3v5h-5\" />\n </Icon>\n );\n}\n\nfunction IconSearch(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m21 21-4.34-4.34\" />\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n </Icon>\n );\n}\n\nfunction IconX(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </Icon>\n );\n}\n\nfunction IconListTree(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M8 5h13\" />\n <path d=\"M13 12h8\" />\n <path d=\"M13 19h8\" />\n <path d=\"M3 10a2 2 0 0 0 2 2h3\" />\n <path d=\"M3 5v12a2 2 0 0 0 2 2h3\" />\n </Icon>\n );\n}\n\n/**\n * What a replacement icon receives — the two knobs the chrome actually turns. Lucide icons are\n * drawn on a 24px grid at stroke 2; a custom component is free to ignore either.\n */\nexport interface DataTableIconProps {\n /**\n * Rendered width and height in px. The chrome passes 12–16 for controls and 40 for the\n * empty/error indicators.\n */\n size?: number;\n strokeWidth?: number;\n}\n\nexport type DataTableIconComponent = ComponentType<DataTableIconProps>;\n\n/**\n * Every glyph the table chrome renders, one slot per affordance. Slots are named for the\n * `DataTableLabels` key of the same affordance where one exists (`pinStart`, `retry`,\n * `clearSelection`, …), so the two registries read as one vocabulary.\n */\nexport interface DataTableIcons {\n /* Header */\n sortAsc: DataTableIconComponent;\n sortDesc: DataTableIconComponent;\n /**\n * The neutral both-directions affordance an unsorted sortable column shows.\n */\n sortable: DataTableIconComponent;\n filterColumn: DataTableIconComponent;\n\n /* Rows — one chevron, rotated open by the stylesheet (expand-all and groups included). */\n expandRow: DataTableIconComponent;\n /**\n * The drag handle of the injected row-ordering column, and the ghost that follows a drag.\n */\n reorderRow: DataTableIconComponent;\n\n /* States */\n empty: DataTableIconComponent;\n noResults: DataTableIconComponent;\n error: DataTableIconComponent;\n retry: DataTableIconComponent;\n\n /* Global search */\n search: DataTableIconComponent;\n\n /* Selection */\n clearSelection: DataTableIconComponent;\n\n /* Columns panel */\n resetColumns: DataTableIconComponent;\n reorderColumn: DataTableIconComponent;\n /**\n * Both the group toggle and the grouped rest-state mark.\n */\n groupByColumn: DataTableIconComponent;\n pinStart: DataTableIconComponent;\n unpin: DataTableIconComponent;\n pinEnd: DataTableIconComponent;\n}\n\nexport const defaultIcons: DataTableIcons = {\n sortAsc: IconChevronUp,\n sortDesc: IconChevronDown,\n sortable: IconChevronsUpDown,\n filterColumn: IconFunnel,\n expandRow: IconChevronRight,\n reorderRow: IconGripVertical,\n empty: IconInbox,\n noResults: IconSearch,\n error: IconTriangleAlert,\n retry: IconRotateCw,\n search: IconSearch,\n clearSelection: IconX,\n resetColumns: IconRotateCcw,\n reorderColumn: IconGripVertical,\n groupByColumn: IconListTree,\n pinStart: IconArrowLeftToLine,\n unpin: IconMoveHorizontal,\n pinEnd: IconArrowRightToLine\n};\n\nexport function resolveIcons(icons: Partial<DataTableIcons> | undefined): DataTableIcons {\n return icons ? { ...defaultIcons, ...icons } : defaultIcons;\n}\n","/**\n * Every user-visible string in the library flows through this object — components never hardcode\n * a locale. App-wide configuration is the Mantine-native mechanism (theme defaultProps, see\n * docs/i18n.md); a complete zh-CN preset ships from \"./locales\".\n */\nexport interface DataTableLabels {\n /* Pagination */\n paginationSummary: (from: number, to: number, total: number) => string;\n rowsPerPage: string;\n\n /* Selection */\n selectAllRows: string;\n selectRow: string;\n selectedCount: (count: number) => string;\n clearSelection: string;\n\n /* Expansion */\n expandRow: string;\n collapseRow: string;\n expandAll: string;\n collapseAll: string;\n\n /* Active row (enableActiveRow) */\n /**\n * Describes the body viewport — the keyboard focus stop — while `enableActiveRow` is on. It\n * is the only place the arrow-key row model is announced, so say what the keys do. A\n * description, never a name: that div is roleless, and `generic` prohibits a name.\n */\n rowNavigation: string;\n /**\n * Announced politely whenever the current row changes: focus stays on the viewport, so without\n * this the move is visual only.\n */\n currentRow: (row: string, index: number, count: number) => string;\n\n /* Columns panel */\n columnsPanel: string;\n resetColumns: string;\n /**\n * Logical positions (TanStack v9 vocabulary): start/end map to left/right in LTR layouts and\n * mirror under RTL.\n */\n pinStart: string;\n pinEnd: string;\n unpin: string;\n /**\n * Zone captions the columns panel shows above its pinned columns; nouns for the state, where\n * `pinStart` / `pinEnd` name the action.\n */\n pinnedStart: string;\n pinnedEnd: string;\n groupByColumn: string;\n ungroupColumn: string;\n columnWidth: string;\n /**\n * Width placeholder for a column whose definition declares no `size` — it grows to share the\n * leftover viewport. A column that declares one shows that number instead.\n */\n columnWidthAuto: string;\n\n /* Column interactions */\n resizeColumn: string;\n reorderColumn: string;\n\n /* Filters */\n /**\n * Names the funnel trigger and the control inside it — an unnamed control in a table of them\n * is unusable, so the column title is interpolated rather than left generic.\n */\n filterColumn: (column: string) => string;\n clearFilter: string;\n filterPlaceholder: string;\n filterRangeMin: string;\n filterRangeMax: string;\n\n /* Global search */\n searchPlaceholder: string;\n\n /* States */\n loading: string;\n empty: string;\n /**\n * Zero rows while a column filter or the global search is active — a different situation\n * than an empty data set, so it gets its own message.\n */\n noResults: string;\n loadingMore: string;\n error: string;\n retry: string;\n loadMoreError: string;\n\n /* Editing */\n /**\n * Names an inline editor by the column it edits.\n */\n editColumn: (column: string) => string;\n editPending: string;\n\n /* Row ordering (enableRowOrdering) */\n /**\n * Names every drag handle; the row a handle belongs to is evident from its position, so the\n * label states the action, matching `selectRow` / `expandRow`.\n */\n reorderRow: string;\n /**\n * Why the handles are disabled — shown as their tooltip while sorting, a filter, a search or\n * grouping controls the visible order.\n */\n rowOrderingUnavailable: string;\n /**\n * Announced when a drag lifts a row. The one place the keyboard drag model is spoken, so say\n * what the keys do.\n */\n rowReorderLifted: (row: string) => string;\n /**\n * Announced as the drop target changes; `row` names the target the same way `currentRow`\n * names rows (leading visible cell).\n */\n rowReorderTarget: (row: string, side: \"before\" | \"after\") => string;\n rowReorderDropped: (row: string) => string;\n rowReorderCanceled: string;\n}\n\nexport const defaultLabels: DataTableLabels = {\n paginationSummary: (from, to, total) => `${from}–${to} of ${total}`,\n rowsPerPage: \"Rows per page\",\n\n selectAllRows: \"Select all rows\",\n selectRow: \"Select row\",\n selectedCount: count => `${count} selected`,\n clearSelection: \"Clear selection\",\n\n rowNavigation: \"Table rows — use the arrow keys to move between rows\",\n currentRow: (row, index, count) => `${row}, row ${index} of ${count}`,\n\n expandRow: \"Expand row\",\n collapseRow: \"Collapse row\",\n expandAll: \"Expand all rows\",\n collapseAll: \"Collapse all rows\",\n\n columnsPanel: \"Columns\",\n resetColumns: \"Reset\",\n pinStart: \"Pin to start\",\n pinEnd: \"Pin to end\",\n unpin: \"Unpin\",\n pinnedStart: \"Pinned start\",\n pinnedEnd: \"Pinned end\",\n groupByColumn: \"Group by this column\",\n ungroupColumn: \"Ungroup\",\n columnWidth: \"Width\",\n columnWidthAuto: \"Auto\",\n\n resizeColumn: \"Drag to resize; double-click to fit content\",\n reorderColumn: \"Drag to reorder column\",\n\n filterColumn: column => `Filter ${column}`,\n clearFilter: \"Clear filter\",\n filterPlaceholder: \"Filter…\",\n filterRangeMin: \"Min\",\n filterRangeMax: \"Max\",\n\n searchPlaceholder: \"Search…\",\n\n loading: \"Loading\",\n empty: \"No data\",\n noResults: \"No matching records\",\n loadingMore: \"Loading more\",\n error: \"Couldn't load data\",\n retry: \"Retry\",\n loadMoreError: \"Couldn't load more rows\",\n\n editColumn: column => `Edit ${column}`,\n editPending: \"Saving\",\n\n reorderRow: \"Drag to reorder row\",\n rowOrderingUnavailable: \"Clear sorting, filters, and grouping to reorder rows\",\n rowReorderLifted: row => `${row} lifted — use the arrow keys to move, space to drop, escape to cancel`,\n rowReorderTarget: (row, side) => side === \"before\" ? `Before ${row}` : `After ${row}`,\n rowReorderDropped: row => `${row} dropped`,\n rowReorderCanceled: \"Reorder canceled\"\n};\n\nexport function resolveLabels(labels: Partial<DataTableLabels> | undefined): DataTableLabels {\n return labels ? { ...defaultLabels, ...labels } : defaultLabels;\n}\n","import type { DragEndEvent } from \"@dnd-kit/react\";\nimport type { PopoverProps } from \"@mantine/core\";\nimport type { ColumnPinningPosition, RowData } from \"@tanstack/react-table\";\nimport type { CSSProperties, ReactElement } from \"react\";\n\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { Column, TableInstance } from \"./types\";\n\n/**\n * `DataTable.ColumnsPanel` — one surface for every column-layout decision: order (drag),\n * visibility, pinning, width, and grouping. It replaces the per-column header menu, whose\n * \"hide column\" item was a trap door — a hidden column took its own menu with it.\n *\n * Trigger-agnostic by construction. `children` IS the trigger and the panel opens from it in a\n * Popover; with no children the panel renders bare, so a drawer, a sidebar, or a settings page\n * hosts it just as well. Bare is the primary shape — the rest of the compound family\n * (`.Search` / `.Pagination` / `.SelectionBar`) is bare content the page places, too.\n *\n * Presentation contract (docs/columns.md): at rest a row is identity — checkbox and name — plus\n * dimmed marks only where the layout deviates from default (captions over pinned zones, an\n * overridden width, a grouped column, a dimmed hidden name). The machinery — drag handle, width\n * field, pin segment, group toggle — surfaces on the hovered or keyboard-focused row and stays\n * inline where hover does not exist. The reveal is stylesheet-only: every control is always in\n * the DOM and the accessibility tree.\n */\nimport { move } from \"@dnd-kit/helpers\";\nimport { DragDropProvider } from \"@dnd-kit/react\";\nimport { useSortable } from \"@dnd-kit/react/sortable\";\nimport {\n ActionIcon,\n Button,\n Center,\n Checkbox,\n Group,\n NumberInput,\n Popover,\n SegmentedControl,\n Text,\n Tooltip,\n useProps,\n VisuallyHidden\n} from \"@mantine/core\";\nimport clsx from \"clsx\";\n\nimport { columnEnableResizing, columnHeaderText, isInternalColumn, rawColumnSizing } from \"./build-columns\";\nimport { applyCenterOrder, resolveColumnOrder } from \"./column-order\";\nimport { resolveIcons } from \"./icons\";\nimport { resolveLabels } from \"./labels\";\n\nexport interface DataTableColumnsPanelProps<TData extends RowData> {\n table: TableInstance<TData>;\n /**\n * The control that opens the panel, wrapped as the Popover target — a button, an icon in a\n * header cell, anything. Omitted: the panel renders bare for a drawer, a sidebar, or a page\n * of its own.\n */\n children?: ReactElement;\n /**\n * Forwarded to the Popover; only meaningful alongside a trigger.\n */\n popoverProps?: Omit<PopoverProps, \"children\">;\n labels?: Partial<DataTableLabels>;\n icons?: Partial<DataTableIcons>;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * The three lists the panel renders, in table display order. `start` / `center` / `end` are\n * TanStack's own words (`getStartLeafColumns` / `getCenterLeafColumns` / `getEndLeafColumns`);\n * \"zone\" is ledger's collective noun for them, because TanStack names the accessors but never\n * the set.\n */\ntype ColumnZone = \"start\" | \"center\" | \"end\";\n\ninterface ColumnsPanelZone<TData extends RowData> {\n id: ColumnZone;\n columns: Array<Column<TData, unknown>>;\n}\n\n/**\n * Leaf columns per zone — hidden ones included (bringing them back is what the panel is for) and\n * ledger's injected columns excluded (they can never be reordered, hidden, or unpinned). The\n * order is TanStack's: a pinned zone reads its `columnPinning` array, the center reads\n * `columnOrder`.\n */\nfunction resolveZones<TData extends RowData>(table: TableInstance<TData>): Array<ColumnsPanelZone<TData>> {\n const external = (columns: Array<Column<TData, unknown>>) => columns.filter(column => !isInternalColumn(column.id));\n\n return [\n { id: \"start\", columns: external(table.getStartLeafColumns()) },\n { id: \"center\", columns: external(table.getCenterLeafColumns()) },\n { id: \"end\", columns: external(table.getEndLeafColumns()) }\n ];\n}\n\n/**\n * The pinned zones caption themselves — the zone's pin glyph beside its name, the same pair the\n * row's pin segments speak; the center is the default territory and stays unlabeled.\n */\nconst zoneCaptions = {\n start: {\n label: \"pinnedStart\",\n icon: \"pinStart\"\n },\n end: {\n label: \"pinnedEnd\",\n icon: \"pinEnd\"\n }\n} satisfies Partial<Record<ColumnZone, { label: keyof DataTableLabels; icon: keyof DataTableIcons }>>;\n\ninterface ZoneCaptionProps {\n zone: keyof typeof zoneCaptions;\n labels: DataTableLabels;\n icons: DataTableIcons;\n}\n\nfunction ZoneCaption({\n zone,\n labels,\n icons\n}: ZoneCaptionProps) {\n const caption = zoneCaptions[zone];\n const Glyph = icons[caption.icon];\n\n // A ledger-owned div, not <Text>: the host may load Mantine's stylesheet unlayered, where the\n // Text reset (`padding: 0` on its <p>) beats anything the ledger layer declares — the caption's\n // box, type, and color all live in the stylesheet instead.\n return (\n <div className=\"ledger-columns-panel-zone-label\">\n <Glyph size={12} />\n {labels[caption.label]}\n </div>\n );\n}\n\n/**\n * The three-state position control, one segment per TanStack `ColumnPinningPosition`. `key`\n * addresses both registries — the icon slots are named for their label keys. `value` stands in\n * for the position inside the SegmentedControl, whose values must be strings (\"center\" is the\n * zone name for TanStack's `false`).\n */\nconst pinSegments: Array<{\n position: ColumnPinningPosition;\n value: \"start\" | \"center\" | \"end\";\n key: \"pinStart\" | \"unpin\" | \"pinEnd\";\n}> = [\n {\n position: \"start\",\n value: \"start\",\n key: \"pinStart\"\n },\n {\n position: false,\n value: \"center\",\n key: \"unpin\"\n },\n {\n position: \"end\",\n value: \"end\",\n key: \"pinEnd\"\n }\n];\n\nconst columnsPanelDefaultProps = {} satisfies Partial<DataTableColumnsPanelProps<RowData>>;\n\nexport function DataTableColumnsPanel<TData extends RowData>(props: DataTableColumnsPanelProps<TData>) {\n const {\n table,\n children,\n popoverProps,\n labels,\n icons,\n className,\n style\n } = useProps(\"DataTableColumnsPanel\", columnsPanelDefaultProps, props);\n\n const content = (\n <ColumnsPanelContent\n className={className}\n icons={resolveIcons(icons)}\n labels={resolveLabels(labels)}\n style={style}\n table={table}\n />\n );\n\n if (!children) {\n return content;\n }\n\n // 360 fits the widest row a column can ask for — handle, checkbox, a comfortable title, and\n // the revealed toolbar — so the default never squeezes; `popoverProps` tunes it for column\n // sets that need less or titles that need more.\n return (\n <Popover position=\"bottom-end\" shadow=\"md\" width={360} {...popoverProps}>\n <Popover.Target>{children}</Popover.Target>\n\n {/* A dropdown grows without bound, so it gets a definite cap here and the panel's own list\n becomes the scroller; p={0} because the panel brings its own padding. */}\n <Popover.Dropdown display=\"flex\" mah=\"60vh\" p={0}>\n {content}\n </Popover.Dropdown>\n </Popover>\n );\n}\n\ninterface ColumnsPanelContentProps<TData extends RowData> {\n table: TableInstance<TData>;\n labels: DataTableLabels;\n icons: DataTableIcons;\n className?: string;\n style?: CSSProperties;\n}\n\nfunction ColumnsPanelContent<TData extends RowData>({\n table,\n labels,\n icons,\n className,\n style\n}: ColumnsPanelContentProps<TData>) {\n const zones = resolveZones(table);\n\n // The same rule the header drag applies (use-column-reorder.ts): with column groups, sibling\n // order inside a group is ambiguous — that hook already carries the dev warning.\n const orderable\n = table.options.meta?.ledger?.enableColumnOrdering === true\n && table.getHeaderGroups().length === 1;\n\n const zoneIds = (id: ColumnZone) => zones.find(zone => zone.id === id)?.columns.map(column => column.id) ?? [];\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { source } = event.operation;\n\n if (event.canceled || !source) {\n return;\n }\n\n const zone = zones.find(candidate => candidate.columns.some(column => column.id === source.id));\n\n if (!zone) {\n return;\n }\n\n const ids = zone.columns.map(column => column.id);\n const next = move(ids, event);\n\n if (next === ids) {\n return;\n }\n\n if (zone.id === \"center\") {\n table.setColumnOrder(applyCenterOrder(resolveColumnOrder(table), next));\n\n return;\n }\n\n // Assembled from the panel's own zone lists, never from the columnPinning slice: that one\n // carries the injected column ids useDataTable merges in on every render, and echoing them\n // back would leak `ledger:*` into the consumer's onColumnPinningChange and persisted state.\n table.setColumnPinning({\n start: zone.id === \"start\" ? next : zoneIds(\"start\"),\n end: zone.id === \"end\" ? next : zoneIds(\"end\")\n });\n };\n\n const handleReset = () => {\n // Exactly the layout set `persistState` persists by default (docs/state.md). Each reset\n // targets `table.initialState`, which useDataTable seeds from the `defaultX` options — so\n // this restores the application's declared layout, not merely an empty one.\n table.resetColumnOrder();\n table.resetColumnVisibility();\n table.resetColumnPinning();\n table.resetColumnSizing();\n };\n\n return (\n <DragDropProvider onDragEnd={handleDragEnd}>\n <div className={clsx(\"ledger-columns-panel\", className)} style={style}>\n <Group className=\"ledger-columns-panel-header\" gap=\"xs\" justify=\"space-between\" wrap=\"nowrap\">\n <Text fw={600} size=\"sm\">\n {labels.columnsPanel}\n </Text>\n\n <Button\n color=\"gray\"\n leftSection={<icons.resetColumns size={14} />}\n size=\"compact-xs\"\n variant=\"subtle\"\n onClick={handleReset}\n >\n {labels.resetColumns}\n </Button>\n </Group>\n\n <div className=\"ledger-columns-panel-list\">\n {zones\n .filter(zone => zone.columns.length > 0)\n .map(zone => (\n <div key={zone.id} className=\"ledger-columns-panel-zone\" data-pinned={zone.id !== \"center\" || undefined}>\n {zone.id !== \"center\" && <ZoneCaption icons={icons} labels={labels} zone={zone.id} />}\n\n {zone.columns.map((column, index) => (\n <ColumnsPanelItem\n key={column.id}\n column={column}\n icons={icons}\n index={index}\n labels={labels}\n orderable={orderable}\n table={table}\n zone={zone.id}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n </DragDropProvider>\n );\n}\n\ninterface ColumnsPanelItemProps<TData extends RowData> {\n column: Column<TData, unknown>;\n table: TableInstance<TData>;\n labels: DataTableLabels;\n icons: DataTableIcons;\n index: number;\n zone: ColumnZone;\n orderable: boolean;\n}\n\nfunction ColumnsPanelItem<TData extends RowData>({\n column,\n table,\n labels,\n icons,\n index,\n zone,\n orderable\n}: ColumnsPanelItemProps<TData>) {\n // `type`/`accept` both carry the zone, so a column only ever sorts among its own kind: moving\n // between zones is what the pin controls are for, and an empty zone has no drop target anyway.\n const {\n ref,\n handleRef,\n isDragging\n } = useSortable({\n id: column.id,\n index,\n group: zone,\n type: zone,\n accept: zone,\n disabled: !orderable\n });\n\n const title = columnHeaderText(column);\n const pinned = column.getIsPinned();\n const grouped = column.getIsGrouped();\n const canPin = column.getCanPin();\n // Ledger's own gate — the TanStack `columnResizingFeature` (and `getCanResize`) is unregistered.\n const canResize\n = table.options.meta?.ledger?.enableColumnResizing === true\n && columnEnableResizing(column.columnDef) !== false;\n const canGroup = table.options.enableGrouping === true && column.getCanGroup();\n\n // The field holds the OVERRIDE; empty falls back to whatever the definition prescribes — the\n // author's `size`, or growing where none is declared. The placeholder shows that fallback\n // rather than a blanket \"auto\", which would misdescribe every column that declares a size.\n // Author sizing comes from the RAW registry, never `columnDef.size`: TanStack merges its\n // `size: 150` default into every resolved definition, which would make \"unsized\"\n // unrepresentable (docs/sizing.md).\n // Read through the slice atom, not `table.state`: `.state` exists only on the hook's wrapper,\n // while a panel hosted in a header cell receives the core instance — atoms live on both.\n const width = table.atoms.columnSizing.get()[column.id];\n const declaredWidth = rawColumnSizing(column.columnDef)?.size ?? table.options.defaultColumn?.size;\n\n const handleWidthChange = (value: number | string) => {\n table.setColumnSizing(previous => {\n // Cleared: drop the entry entirely rather than zeroing it — the same move the resize drag\n // makes on Escape (use-column-resize.ts), and the only state the width engine reads as\n // \"no override\" (docs/sizing.md).\n if (value === \"\") {\n const { [column.id]: _dropped, ...rest } = previous;\n\n return rest;\n }\n\n return { ...previous, [column.id]: Number(value) };\n });\n };\n\n return (\n <Group\n ref={ref}\n className=\"ledger-columns-panel-item\"\n data-dragging={isDragging || undefined}\n data-hidden={!column.getIsVisible() || undefined}\n gap=\"xs\"\n wrap=\"nowrap\"\n >\n {orderable && (\n <Tooltip label={labels.reorderColumn} openDelay={500}>\n <ActionIcon\n ref={handleRef}\n aria-label={labels.reorderColumn}\n className=\"ledger-columns-panel-handle\"\n color=\"gray\"\n size=\"sm\"\n variant=\"subtle\"\n >\n <icons.reorderColumn />\n </ActionIcon>\n </Tooltip>\n )}\n\n {/* miw={0} is load-bearing: a flex item defaults to `min-width: auto`, so the nowrap title\n would set an unshrinkable floor — long names would shove the rest of the row instead of\n ellipsing. The tooltip rides `wrapperProps` because Checkbox forwards bare props to its\n INPUT, and a title there would only answer on the box, never on the truncated text. */}\n <Checkbox\n checked={column.getIsVisible()}\n classNames={{ labelWrapper: \"ledger-columns-panel-label\" }}\n disabled={!column.getCanHide()}\n flex={1}\n label={title}\n miw={0}\n size=\"sm\"\n wrapperProps={{ title }}\n onChange={event => column.toggleVisibility(event.currentTarget.checked)}\n />\n\n {/* Rest-state marks for the two deviations the zone captions cannot carry. The toolbar\n covers them while revealed, and the touch stylesheet drops them outright — there the\n real controls sit inline and already say the same thing. */}\n {(grouped || width !== undefined) && (\n <div className=\"ledger-columns-panel-indicators\">\n {grouped && <icons.groupByColumn size={12} />}\n {/* lh=1 collapses the line box onto the digits, so flex centering lands the mark on the\n row's true midline instead of the taller line box's. */}\n {width !== undefined && <Text lh={1} size=\"xs\">{`${width}px`}</Text>}\n </div>\n )}\n\n {(canResize || canGroup || canPin) && (\n <div className=\"ledger-columns-panel-controls\">\n {/* startValue mirrors the placeholder: stepping an empty field materializes the\n declared width as the override and counts on from there, instead of jumping to\n minSize the way the default (0, clamped) would. */}\n {canResize && (\n <NumberInput\n aria-label={labels.columnWidth}\n classNames={{ input: \"ledger-columns-panel-width-input\" }}\n max={column.columnDef.maxSize}\n min={column.columnDef.minSize}\n placeholder={declaredWidth === undefined ? labels.columnWidthAuto : String(declaredWidth)}\n size=\"xs\"\n startValue={declaredWidth}\n step={10}\n value={width ?? \"\"}\n w={72}\n onChange={handleWidthChange}\n />\n )}\n\n {canGroup && (\n <Tooltip label={grouped ? labels.ungroupColumn : labels.groupByColumn} openDelay={500}>\n <ActionIcon\n aria-label={grouped ? labels.ungroupColumn : labels.groupByColumn}\n aria-pressed={grouped}\n size=\"input-xs\"\n variant={grouped ? \"light\" : \"subtle\"}\n onClick={() => column.toggleGrouping()}\n >\n <icons.groupByColumn />\n </ActionIcon>\n </Tooltip>\n )}\n\n {/* One radio group, not three toggle buttons: the pin state is a single choice of\n position, and the selected segment says which without a tooltip. Each glyph rides a\n <Center> (Mantine's own recipe for icon segments): left inline, the svg would sit on\n the text baseline and hang above the segment's midline by the descender's height.\n The label key serves twice — the visually hidden accessible name and the Tooltip\n label. */}\n {canPin && (\n <SegmentedControl\n size=\"xs\"\n value={pinSegments.find(segment => segment.position === pinned)?.value ?? \"center\"}\n data={pinSegments.map(({ value, key }) => {\n const Glyph = icons[key];\n\n return {\n value,\n label: (\n <Tooltip label={labels[key]} openDelay={500}>\n {/* h=18: the 14px glyph alone would size the control at 26px next to the\n width input's 30 — 18 plus the segment's own chrome lands both at 30. */}\n <Center h={18}>\n <Glyph size={14} />\n <VisuallyHidden>{labels[key]}</VisuallyHidden>\n </Center>\n </Tooltip>\n )\n };\n })}\n onChange={value => {\n column.pin(pinSegments.find(segment => segment.value === value)?.position ?? false);\n }}\n />\n )}\n </div>\n )}\n </Group>\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Column, Row, TableInstance } from \"./types\";\n\n/**\n * CSV export over the live table instance (RFC 4180 quoting, CRLF line ends). Exports accessor\n * columns only, in their current visible order; `meta.export` excludes a column or overrides\n * its exported header/value. Scopes read the same row models the screen shows — a\n * server-paginated table can therefore only export the rows it has.\n */\nimport { columnHeaderText, isInternalColumn } from \"./build-columns\";\n\nexport interface ToCsvOptions {\n /**\n * Which rows to export:\n * - `\"filtered\"` (default) — everything after filters and sorting, before pagination;\n * - `\"all\"` — the unfiltered data set;\n * - `\"page\"` — the current page (identical to `\"filtered\"` without pagination);\n * - `\"selected\"` — the current selection.\n */\n scope?: \"filtered\" | \"all\" | \"page\" | \"selected\";\n delimiter?: string;\n /**\n * Include the header line. Default true.\n */\n withHeaders?: boolean;\n /**\n * Prefix text a spreadsheet would evaluate as a formula (leading `=`, `+`, `-`, `@`, tab or\n * CR — the OWASP CSV-injection set) with a `'`. Applies to header text and string-valued\n * cells; numeric cells keep their sign. Default false — the quote is data to every\n * non-spreadsheet consumer, so it is opt-in for exports that feed spreadsheets.\n */\n escapeFormulas?: boolean;\n}\n\nexport function toCsv<TData extends RowData>(table: TableInstance<TData>, options: ToCsvOptions = {}): string {\n const {\n scope = \"filtered\",\n delimiter = \",\",\n withHeaders = true,\n escapeFormulas = false\n } = options;\n\n const rows = rowsForScope(table, scope);\n\n const columns = [\n ...table.getStartVisibleLeafColumns(),\n ...table.getCenterVisibleLeafColumns(),\n ...table.getEndVisibleLeafColumns()\n ].filter(column => !isInternalColumn(column.id)\n && column.accessorFn !== undefined\n && column.columnDef.meta?.export !== false);\n\n const lines: string[] = [];\n\n if (withHeaders) {\n lines.push(\n columns\n .map(column => {\n const text = exportHeaderText(column);\n\n return escapeCsvValue(escapeFormulas ? defuseFormula(text) : text, delimiter);\n })\n .join(delimiter)\n );\n }\n\n for (const row of rows) {\n lines.push(\n columns\n .map(column => {\n const raw = exportCellValue(column, row);\n const text = serializeCsvValue(raw);\n\n // Only string cells can smuggle a formula; serialized numbers keep their sign.\n return escapeCsvValue(escapeFormulas && typeof raw === \"string\" ? defuseFormula(text) : text, delimiter);\n })\n .join(delimiter)\n );\n }\n\n return lines.join(\"\\r\\n\");\n}\n\nfunction rowsForScope<TData extends RowData>(table: TableInstance<TData>, scope: NonNullable<ToCsvOptions[\"scope\"]>) {\n switch (scope) {\n case \"selected\": {\n // `rows` is the selected *tree*: a row only appears there if it is selected itself, so a\n // selected child of an unselected parent is nowhere in it. `flatRows` is every selected\n // row, each once, in the order they are drawn.\n return table.getSelectedRowModel().flatRows;\n }\n\n case \"all\": {\n return table.getCoreRowModel().rows;\n }\n\n case \"page\": {\n return table.getRowModel().rows;\n }\n\n case \"filtered\": {\n return table.getPrePaginatedRowModel().rows;\n }\n }\n}\n\nfunction exportHeaderText<TData extends RowData>(column: Column<TData, unknown>): string {\n const exportMeta = column.columnDef.meta?.export;\n\n return (typeof exportMeta === \"object\" ? exportMeta.header : undefined) ?? columnHeaderText(column);\n}\n\nfunction exportCellValue<TData extends RowData>(column: Column<TData, unknown>, row: Row<TData>): unknown {\n const exportMeta = column.columnDef.meta?.export;\n\n return typeof exportMeta === \"object\" && exportMeta.value\n ? exportMeta.value(row)\n : row.getValue(column.id);\n}\n\nfunction serializeCsvValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n\n return String(value);\n}\n\nconst FORMULA_LEAD = /^[=+\\-@\\t\\r]/;\n\nfunction defuseFormula(value: string): string {\n return FORMULA_LEAD.test(value) ? `'${value}` : value;\n}\n\nfunction escapeCsvValue(value: string, delimiter: string): string {\n if (value.includes(\"\\\"\") || value.includes(delimiter) || value.includes(\"\\n\") || value.includes(\"\\r\")) {\n return `\"${value.replaceAll(\"\\\"\", \"\\\"\\\"\")}\"`;\n }\n\n return value;\n}\n","import clsx from \"clsx\";\n\n/**\n * React's HTML attribute types enumerate every `aria-*` attribute but no `data-*` one: JSX\n * accepts them through a compiler special case that an object literal does not get. The escape\n * hatch therefore admits them explicitly — `data-*` is half the point of it.\n */\nexport type DataAttributes = Record<`data-${string}`, string | number | boolean | null | undefined>;\n\n/**\n * The DOM escape hatch (docs/styling.md#dom-props): every rendered row, cell, and header cell\n * accepts consumer props — attributes, `data-*`, `aria-*`, inline styles, extra handlers —\n * either as a static object or as a function of the element's subject.\n *\n * `ref` is deliberately excluded from every one of these types: they are declarative prop hooks\n * resolved per render (per virtual item, for rows), not component instances, and ledger already\n * owns the row ref for virtualization measurement.\n */\nexport type DataTableElementProps<TProps, TSubject>\n = | (TProps & DataAttributes)\n | ((subject: TSubject) => (TProps & DataAttributes) | undefined);\n\nexport function resolveElementProps<TProps, TSubject>(\n props: DataTableElementProps<TProps, TSubject> | undefined,\n subject: TSubject\n): (TProps & DataAttributes) | undefined {\n return typeof props === \"function\"\n ? (props as (subject: TSubject) => (TProps & DataAttributes) | undefined)(subject)\n : props;\n}\n\n/**\n * Compose consumer props with ledger's own, with four rules:\n *\n * - ledger's structural props win — `role`, the `data-*` state contract and the ARIA indices are\n * the styling and semantic contract, not suggestions;\n * - but only where ledger actually sets one: an owned key holding `undefined` means \"ledger has\n * no opinion here\" and must not erase the consumer's value;\n * - `className` and `style` compose, consumer last — an escape hatch that silently dropped an\n * author's declaration would not be one, so overriding a ledger inline value (a pinned cell's\n * sticky offset, say) is possible and is the author's to own;\n * - a handler present on both sides chains, ledger's first (its stop-propagation covenant and\n * active-row bookkeeping run before the consumer sees the event).\n */\nexport function mergeElementProps<TOwned extends Record<string, any>>(\n consumer: Record<string, any> | undefined,\n owned: TOwned\n): TOwned {\n if (!consumer) {\n return owned;\n }\n\n const merged: Record<string, any> = { ...consumer };\n\n for (const [key, ownedValue] of Object.entries(owned)) {\n const consumerValue = consumer[key];\n\n if (\n key.startsWith(\"on\")\n && typeof ownedValue === \"function\"\n && typeof consumerValue === \"function\"\n ) {\n merged[key] = (...args: unknown[]) => {\n ownedValue(...args);\n consumerValue(...args);\n };\n } else if (ownedValue !== undefined) {\n // An owned key holding `undefined` is \"no opinion\", and React reads a missing prop and an\n // undefined one alike — so skipping the write leaves the consumer's value standing.\n merged[key] = ownedValue;\n }\n }\n\n const className = clsx(owned.className, consumer.className);\n\n merged.className = className === \"\" ? undefined : className;\n\n if (consumer.style || owned.style) {\n merged.style = { ...owned.style, ...consumer.style };\n }\n\n return merged as TOwned;\n}\n","/**\n * Environment probing — deliberately dependency-free so it stays importable (and testable)\n * in environments where the rest of the graph cannot load.\n */\n\n/**\n * Bundlers replace `process.env.NODE_ENV`; the local declaration keeps package sources free of ambient node types.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention -- mirrors the platform env var name verbatim\ndeclare const process: { env: { NODE_ENV?: string } };\n\n/**\n * The mode, read from the one expression every bundler replaces.\n *\n * It has to be read *unguarded* for that to work. Vite substitutes `process.env.NODE_ENV`\n * textually in client code — dev server included, and that covers library source served through\n * the `source` export condition — so a `typeof process` guard in front of it short-circuits in\n * the browser before the substituted value is ever reached, and every dev guard goes quiet\n * exactly where a developer is looking at the console. Guarding it the other way round is worse:\n * \"no `process` object at runtime\" would then mean development, and in a browser that is what a\n * production bundle looks like, so the warning channel survives into production.\n *\n * So the read comes first and the *failure* is what is caught. Where something replaced the\n * expression, the value decides and the production build folds to `false`; where nothing did —\n * a bundle shipped without a `process` shim — the read throws and the answer is \"not\n * development\", which is the safe way to be wrong.\n *\n * Exported as a function so the regression test can probe it under a synchronously scoped\n * `process` stub — holding the stub across an async module re-import breaks the test runner's\n * own internals.\n */\nexport function computeIsDev(): boolean {\n let nodeEnv: string | undefined;\n\n try {\n nodeEnv = process.env.NODE_ENV;\n } catch {\n nodeEnv = undefined;\n }\n\n return nodeEnv !== undefined && nodeEnv !== \"production\";\n}\n\nexport const isDev: boolean = computeIsDev();\n\nconst emittedWarnings = new Set<string>();\n\n/**\n * Dev-only, once-per-session warning — the guard-rail channel catalogued in docs/state.md.\n */\nexport function warnOnce(key: string, message: string): void {\n if (!isDev || emittedWarnings.has(key)) {\n return;\n }\n\n emittedWarnings.add(key);\n\n console.warn(`[ledger] ${message}`);\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { SortToggleSpec } from \"./toggle-fns\";\nimport type { LedgerMeta } from \"./types\";\nimport type { LedgerExpansionController, LedgerSelectionController } from \"./use-row-commands\";\n\n/**\n * The row-state toggles, kept off the public `LedgerMeta`.\n *\n * `LedgerMeta` is exported and documented (docs/api.md) — it is what an application reads when it\n * reaches into `table.options.meta.ledger`. These controllers are ledger's own plumbing between\n * the hook and its controls, so they ride the same object without being part of that contract:\n * `useDataTable` builds a `LedgerInternalMeta`, and the few internal readers ask for them by way\n * of `ledgerCommands`.\n */\n\nexport interface LedgerSortingController {\n toggle: (spec: SortToggleSpec, multi: boolean) => void;\n}\n\nexport interface LedgerCommands {\n sorting: LedgerSortingController;\n selection: LedgerSelectionController;\n expansion: LedgerExpansionController;\n}\n\nexport type LedgerInternalMeta<TData extends RowData> = LedgerCommands & LedgerMeta<TData>;\n\nexport function ledgerCommands(meta: LedgerMeta<any> | undefined): LedgerCommands | undefined {\n return meta as LedgerInternalMeta<any> | undefined;\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { CSSProperties } from \"react\";\n\nimport type { DataTableLabels } from \"./labels\";\nimport type { TableInstance } from \"./types\";\n\n/**\n * The pagination bar: summary on the start side, rows-per-page and page controls on the end\n * side. One core rendering, two skins — the built-in bar (inside <DataTable>, styled through the\n * Styles API) and the standalone `DataTable.Pagination` compound for custom placement.\n * TanStack's 0-based `pageIndex` converts to Mantine `Pagination`'s 1-based `value` here and\n * nowhere else.\n */\nimport { Group, Pagination, Select, Text, useProps } from \"@mantine/core\";\nimport clsx from \"clsx\";\nimport { useId } from \"react\";\n\nimport { useDataTableContext } from \"./context\";\nimport { resolveLabels } from \"./labels\";\n\nexport const DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 50, 100];\n\ninterface PaginationBarCoreProps<TData extends RowData> {\n table: TableInstance<TData>;\n labels: DataTableLabels;\n pageSizeOptions: number[];\n className?: string;\n style?: CSSProperties;\n}\n\nfunction PaginationBarCore<TData extends RowData>({\n table,\n labels,\n pageSizeOptions,\n className,\n style\n}: PaginationBarCoreProps<TData>) {\n const pageSizeLabelId = useId();\n const { pageIndex, pageSize } = table.atoms.pagination.get();\n // `options.rowCount` (server mode) wins inside TanStack; client mode counts pre-paginated rows.\n const total = table.getRowCount();\n const pageCount = Math.max(1, table.getPageCount());\n const from = total === 0 ? 0 : pageIndex * pageSize + 1;\n const to = Math.min(total, (pageIndex + 1) * pageSize);\n // The size on screen is always offerable, whoever set it: a controlled `pagination` (or a\n // persisted one) may hold a size the author never listed, and a Select whose value is absent\n // from its data renders blank. Always de-duplicated and ascending, so the list a reader sees\n // does not depend on how the current size got there.\n const sizeOptions = [...new Set([...pageSizeOptions, pageSize])].toSorted((left, right) => left - right);\n\n return (\n <Group className={className} gap=\"md\" justify=\"space-between\" style={style} wrap=\"wrap\">\n <Text c=\"dimmed\" size=\"sm\">\n {labels.paginationSummary(from, to, total)}\n </Text>\n\n <Group gap=\"md\" wrap=\"nowrap\">\n <Group gap=\"xs\" wrap=\"nowrap\">\n {/* The visible text IS the label — pointing at it beats duplicating it into an\n aria-label, which would let the two drift apart (WCAG 2.5.3, label in name). */}\n <Text key=\"label\" c=\"dimmed\" id={pageSizeLabelId} size=\"sm\">\n {labels.rowsPerPage}\n </Text>\n\n <Select\n allowDeselect={false}\n aria-labelledby={pageSizeLabelId}\n data={sizeOptions.map(String)}\n size=\"xs\"\n value={String(pageSize)}\n w={84}\n onChange={value => value !== null && table.setPageSize(Number(value))}\n />\n </Group>\n\n <Pagination\n size=\"sm\"\n total={pageCount}\n value={pageIndex + 1}\n onChange={page => table.setPageIndex(page - 1)}\n />\n </Group>\n </Group>\n );\n}\n\n/**\n * The built-in bar rendered by <DataTable> (context-styled).\n */\nexport function PaginationBar<TData extends RowData>({ table, pageSizeOptions }: { table: TableInstance<TData>; pageSizeOptions: number[] }) {\n const { labels, getStyles } = useDataTableContext();\n const { className, style } = getStyles(\"paginationBar\");\n\n return (\n <PaginationBarCore\n className={className}\n labels={labels}\n pageSizeOptions={pageSizeOptions}\n style={style}\n table={table}\n />\n );\n}\n\nexport interface DataTablePaginationProps<TData extends RowData> {\n table: TableInstance<TData>;\n pageSizeOptions?: number[];\n labels?: Partial<DataTableLabels>;\n className?: string;\n style?: CSSProperties;\n}\n\nconst paginationDefaultProps = {} satisfies Partial<DataTablePaginationProps<RowData>>;\n\n/**\n * Standalone compound (`DataTable.Pagination`) — place it anywhere, theme it via defaultProps.\n */\nexport function DataTablePagination<TData extends RowData>(props: DataTablePaginationProps<TData>) {\n const {\n table,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n labels,\n className,\n style\n } = useProps(\"DataTablePagination\", paginationDefaultProps, props);\n\n return (\n <PaginationBarCore\n className={clsx(\"ledger-pagination-bar\", className)}\n labels={resolveLabels(labels)}\n pageSizeOptions={pageSizeOptions}\n style={style}\n table={table}\n />\n );\n}\n","import type { TextInputProps } from \"@mantine/core\";\nimport type { RowData } from \"@tanstack/react-table\";\n\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { TableInstance } from \"./types\";\n\n/**\n * `DataTable.Search` — the global-filter input, debounced. A standalone compound: takes the\n * table instance, composes anywhere (toolbars are the page's territory).\n */\nimport { CloseButton, TextInput, useProps } from \"@mantine/core\";\nimport { useDebouncedCallback } from \"@mantine/hooks\";\nimport { useEffect, useState } from \"react\";\n\nimport { resolveIcons } from \"./icons\";\nimport { resolveLabels } from \"./labels\";\n\nexport interface DataTableSearchProps<TData extends RowData>\n extends Omit<TextInputProps, \"value\" | \"defaultValue\" | \"onChange\"> {\n table: TableInstance<TData>;\n /**\n * Debounce before the global filter applies, in milliseconds.\n */\n debounce?: number;\n labels?: Partial<DataTableLabels>;\n icons?: Partial<DataTableIcons>;\n}\n\nconst searchDefaultProps = { debounce: 200 } satisfies Partial<DataTableSearchProps<RowData>>;\n\nexport function DataTableSearch<TData extends RowData>(props: DataTableSearchProps<TData>) {\n const {\n table,\n debounce,\n labels,\n icons,\n placeholder,\n ...others\n } = useProps(\n \"DataTableSearch\",\n searchDefaultProps,\n props\n );\n\n const resolved = resolveLabels(labels);\n const resolvedIcons = resolveIcons(icons);\n const globalFilter = (table.atoms.globalFilter.get() as string | undefined) ?? \"\";\n const [value, setValue] = useState(globalFilter);\n\n const apply = useDebouncedCallback((next: string) => table.setGlobalFilter(next), debounce);\n const subscribeGlobalFilter = table.options.meta?.ledger?.filtering.subscribeGlobalFilter;\n\n // A reset to the current table value is invisible to React state. Subscribe to set attempts so\n // it still cancels a pending local value before that value can write itself back later.\n useEffect(() => subscribeGlobalFilter?.(next => {\n apply.cancel();\n setValue(next);\n }), [apply, subscribeGlobalFilter]);\n\n // Follow external changes (a programmatic reset, a controlled slice) once they settle.\n useEffect(() => {\n apply.cancel();\n setValue(globalFilter);\n }, [apply, globalFilter]);\n\n const clear = () => {\n apply.cancel();\n setValue(\"\");\n table.setGlobalFilter(\"\");\n };\n\n const resolvedPlaceholder = placeholder ?? resolved.searchPlaceholder;\n\n return (\n <TextInput\n // A placeholder is not a label — it disappears the moment there is a value. The visible\n // text doubles as the name so the two never disagree; `others` lets a caller override it.\n aria-label={resolvedPlaceholder}\n leftSection={<resolvedIcons.search />}\n placeholder={resolvedPlaceholder}\n rightSectionPointerEvents=\"all\"\n value={value}\n rightSection={value !== \"\"\n && <CloseButton aria-label={resolved.clearFilter} size=\"sm\" onClick={clear} />}\n onChange={event => {\n setValue(event.currentTarget.value);\n apply(event.currentTarget.value);\n }}\n {...others}\n />\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { TableInstance } from \"./types\";\n\n/**\n * `DataTable.SelectionBar` — renders only while rows are selected: the count, a clear action,\n * and whatever bulk actions the page passes as children.\n */\nimport { Button, Group, Text, useProps } from \"@mantine/core\";\nimport clsx from \"clsx\";\n\nimport { resolveIcons } from \"./icons\";\nimport { resolveLabels } from \"./labels\";\n\nexport interface DataTableSelectionBarProps<TData extends RowData> {\n table: TableInstance<TData>;\n labels?: Partial<DataTableLabels>;\n icons?: Partial<DataTableIcons>;\n /**\n * Bulk actions, rendered after the count and clear control.\n */\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nconst selectionBarDefaultProps = {} satisfies Partial<DataTableSelectionBarProps<RowData>>;\n\nexport function DataTableSelectionBar<TData extends RowData>(props: DataTableSelectionBarProps<TData>) {\n const {\n table,\n labels,\n icons,\n children,\n className,\n style\n } = useProps(\n \"DataTableSelectionBar\",\n selectionBarDefaultProps,\n props\n );\n\n const resolved = resolveLabels(labels);\n const resolvedIcons = resolveIcons(icons);\n // The selection state's own count, deliberately — not `getSelectedRowModel().flatRows.length`.\n // That model resolves the state against the rows the table actually holds, which under server\n // pagination is one page: a bar counting it would drop everything selected on the pages that\n // are no longer loaded, and the id-keyed state is precisely what survives paging\n // (docs/selection.md). The corollary is that ids the data no longer holds still count, which is\n // the same reason selection requires a stable `getRowId`.\n const count = Object.values(table.atoms.rowSelection.get()).filter(Boolean).length;\n\n if (count === 0) {\n return null;\n }\n\n return (\n <Group className={clsx(\"ledger-selection-bar\", className)} gap=\"sm\" style={style}>\n <Text fw={500} size=\"sm\">\n {resolved.selectedCount(count)}\n </Text>\n\n <Button\n leftSection={<resolvedIcons.clearSelection />}\n size=\"compact-xs\"\n variant=\"subtle\"\n onClick={() => table.resetRowSelection()}\n >\n {resolved.clearSelection}\n </Button>\n\n {children}\n </Group>\n );\n}\n","/**\n * What the editing gate is, as the predicates every path shares: how a column's `meta.edit` is\n * read, whether a cell may be edited *right now*, and how a thrown value becomes a message. Not\n * referentially pure, and the difference matters — `canEditCell` calls the application's own\n * `edit.enabled(row)`, which may answer differently with no render in between, which is why the\n * render layer, the commits and the checkbox toggle each ask again rather than cache an answer\n * (docs/architecture.md). The session controllers and the editors both need these, and a\n * controller must not depend on a view module to get them.\n */\nimport type { Cell, DataTableEditRenderer, DataTableInstantEditRenderer, Row } from \"./types\";\n\n/**\n * One shape for every `meta.edit` form: which interaction model the column declared, its\n * renderer, and the gates. `validate` and `enabled` ride any kind — they are the session's\n * gate and gatekeeper, not properties of the control being rendered.\n */\nexport type NormalizedEdit\n = | {\n kind: \"session\";\n render: DataTableEditRenderer<any, unknown>;\n enabled?: (row: Row<any>) => boolean;\n validate?: (value: unknown, row: Row<any>) => string | null;\n }\n | {\n kind: \"instant\";\n render: DataTableInstantEditRenderer<any, unknown>;\n enabled?: (row: Row<any>) => boolean;\n validate?: (value: unknown, row: Row<any>) => string | null;\n };\n\nexport function editErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function normalizeEdit(\n edit: NonNullable<Cell<any, unknown>[\"column\"][\"columnDef\"][\"meta\"]>[\"edit\"]\n): NormalizedEdit | null {\n if (!edit) {\n return null;\n }\n\n if (typeof edit === \"function\") {\n return { kind: \"session\", render: edit };\n }\n\n if (\"instant\" in edit) {\n return {\n kind: \"instant\",\n render: edit.instant,\n enabled: edit.enabled,\n validate: edit.validate\n };\n }\n\n return {\n kind: \"session\",\n render: edit.render,\n enabled: edit.enabled,\n validate: edit.validate as NormalizedEdit[\"validate\"]\n };\n}\n\n/**\n * The value the cell of *this* render holds, through its own column's accessor.\n *\n * Not `cell.getValue()`: upstream caches a row's values on the row object, and that cache is only\n * rebuilt when `data` changes — so a column whose `accessorFn` changed under the same data would\n * go on answering with the accessor it had before, and an editor drawing from it would show a\n * value the table has stopped holding. Resolving here also means a redraw between renders cannot\n * pick up a definition from a render pass that never reached the screen.\n */\nexport function cellValue(cell: Cell<any, unknown>): unknown {\n return cell.column.accessorFn?.(cell.row.original, cell.row.index);\n}\n\nexport interface EditGate {\n enableEditing: boolean;\n /**\n * The commit belongs to the application (docs/editing.md), so the handler for the live mode is\n * part of the gate: without it an edit has nowhere to go, and offering one anyway means opening\n * an editor, validating it, closing it \"successfully\", and writing nothing.\n */\n hasCommitHandler: boolean;\n}\n\n/**\n * The gate itself, over values the caller supplies: the switch and handler of one render, the\n * column's `meta.edit` as that render defined it, and the row it resolved. Every caller decides\n * which render that is — the one being drawn, or the one that reached the screen — because the\n * core they would otherwise read it from carries whichever pass ran last, committed or not\n * (see `use-committed-table.ts`).\n */\nexport function canEditWith(\n row: Row<any>,\n edit: NonNullable<Cell<any, unknown>[\"column\"][\"columnDef\"][\"meta\"]>[\"edit\"],\n gate: EditGate\n): boolean {\n if (!gate.enableEditing || !gate.hasCommitHandler) {\n return false;\n }\n\n if (!edit) {\n return false;\n }\n\n return !(typeof edit === \"object\" && edit.enabled && !edit.enabled(row));\n}\n\n/**\n * Whether this cell is editable in the render being drawn. Render-phase only: it reads the\n * definitions and switches through the cell's own table, which is the core — correct while a\n * render is in progress, and a trap at event time.\n */\nexport function canEditCell(cell: Cell<any, unknown>, row: Row<any>): boolean {\n const { table } = cell.getContext();\n const ledger = table.options.meta?.ledger;\n\n return canEditWith(row, cell.column.columnDef.meta?.edit, {\n enableEditing: ledger?.enableEditing ?? false,\n hasCommitHandler: Boolean(ledger && (ledger.editing.mode === \"row\" ? ledger.onRowEditCommit : ledger.onEditCommit))\n });\n}\n","import type { KeyboardEvent } from \"react\";\n\nimport type { Cell } from \"./types\";\n\n/**\n * The editor hosts, for both modes. Each is a view of its session plus a keyboard surface: the\n * draft, the validation, the in-flight commit and the failure all belong to the controller, so\n * that a hidden column or a virtual scroll unmounting an editor takes nothing with it\n * (docs/architecture.md). The host renders no control of its own — the renderer the column\n * declared does (docs/editing.md#editors) — it supplies the context, the keyboard map, the blur\n * commit, and the pending presentation around it.\n */\nimport { Loader } from \"@mantine/core\";\nimport { useLayoutEffect, useReducer, useRef } from \"react\";\n\nimport { columnHeaderText } from \"./build-columns\";\nimport { useDataTableContext } from \"./context\";\nimport { cellValue, normalizeEdit } from \"./edit-meta\";\nimport { useEventCallback } from \"./utils\";\n\nexport { canEditCell } from \"./edit-meta\";\n\nexport function CellEditor({ cell }: { cell: Cell<any, unknown> }) {\n const { labels, getStyles } = useDataTableContext();\n const { table } = cell.getContext();\n const editing = table.options.meta?.ledger?.editing;\n const normalized = normalizeEdit(cell.column.columnDef.meta?.edit);\n const rowId = cell.row.id;\n const columnId = cell.column.id;\n\n const [, redraw] = useReducer((token: number) => token + 1, 0);\n const redrawFromSession = useEventCallback(() => redraw());\n\n // Layout, not passive: the registry is what \"on screen right now\" means to the session, and a\n // commit that unmounts this editor is followed by microtasks — a settling write among them —\n // long before a passive cleanup would run.\n const register = editing?.register;\n\n // Bound to the controller and the cell, not to this component's lifetime: in hook mode the\n // table can be swapped for another instance while React keeps this editor, and a registration\n // left with the controller that is gone means the one now in charge cannot reach it.\n useLayoutEffect(\n () => register?.(rowId, columnId, { redraw: redrawFromSession }),\n [register, rowId, columnId, redrawFromSession]\n );\n\n // An instant column has no session for this host to draw — a change in the cell is the commit\n // (docs/editing.md#instant-editing) — so a programmatic `startEditing` on one renders nothing.\n if (!normalized || normalized.kind === \"instant\" || !editing) {\n return null;\n }\n\n const draft = editing.drafts.read(rowId, columnId, cellValue(cell));\n const editError = editing.drafts.error(rowId, columnId);\n const pending = editing.drafts.pending(rowId, columnId);\n\n const setValue = (value: unknown) => {\n editing.drafts.write(rowId, columnId, value);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case \"Enter\": {\n event.preventDefault();\n void editing.commit();\n\n break;\n }\n\n case \"Escape\": {\n event.preventDefault();\n event.stopPropagation();\n editing.cancel();\n\n break;\n }\n\n case \"Tab\": {\n event.preventDefault();\n // The session owns the move: where the caret goes next depends on the row as the screen\n // has it, and this editor could only ask the shared core (docs/architecture.md).\n editing.moveTo(event.shiftKey);\n\n break;\n }\n // No default\n }\n };\n\n const editor = normalized.render({\n row: cell.row,\n column: cell.column,\n value: draft,\n setValue,\n commit: () => editing.commit(),\n cancel: () => editing.cancel(),\n error: editError,\n pending,\n mode: \"cell\",\n autoFocus: true,\n label: labels.editColumn(columnHeaderText(cell.column))\n });\n\n return (\n <div\n aria-busy={pending || undefined}\n aria-label={pending ? labels.editPending : undefined}\n data-pending={pending || undefined}\n onBlur={event => {\n // Blur commits — unless focus moved elsewhere inside the editor (e.g. a select option).\n if (!event.currentTarget.contains(event.relatedTarget)) {\n editing.commit();\n }\n }}\n onClick={event => event.stopPropagation()}\n onDoubleClick={event => event.stopPropagation()}\n onKeyDown={handleKeyDown}\n {...getStyles(\"cellEditor\")}\n >\n {editor}\n {pending && <Loader size={12} />}\n </div>\n );\n}\n\n/**\n * The row-mode editor host (docs/editing.md#row-mode): one per editable cell of the editing\n * row, all mounted at once. Drafts write through to the controller's store (they must survive\n * a virtualized unmount), blur never commits, and Enter/Escape commit or cancel the whole row.\n */\nexport function RowCellEditor({ cell }: { cell: Cell<any, unknown> }) {\n const { labels, getStyles } = useDataTableContext();\n const { table } = cell.getContext();\n const editing = table.options.meta?.ledger?.editing;\n const rowApi = editing?.row;\n const normalized = normalizeEdit(cell.column.columnDef.meta?.edit);\n const columnId = cell.column.id;\n const rowId = cell.row.id;\n\n // The store is the value, not a copy of it: what the row holds moves under an open editor —\n // the application feeds a write back, normalizes it, or the controller throws the edit away —\n // and local state would go on showing a value the row had already left behind. Rendering is\n // the only thing left to ask for.\n const [, redraw] = useReducer((token: number) => token + 1, 0);\n const draft = rowApi ? rowApi.drafts.read(rowId, columnId, cellValue(cell)) : cellValue(cell);\n const editError = rowApi?.drafts.error(rowId, columnId) ?? null;\n const pending = rowApi?.drafts.pending(rowId) ?? false;\n const containerRef = useRef<HTMLDivElement | null>(null);\n // Ref-read, not consumed — StrictMode's remount and virtualizer round-trips keep the focus.\n const autoFocus = rowApi?.shouldFocus(columnId) ?? false;\n\n const setValue = useEventCallback((value: unknown) => {\n rowApi?.drafts.write(rowId, columnId, value);\n redraw();\n });\n\n /**\n * Everything this editor shows lives in the session, so a change there is answered by drawing\n * again — there is nothing here to put back.\n */\n const redrawFromSession = useEventCallback(() => redraw());\n\n const focusEditor = useEventCallback(() => {\n containerRef.current\n ?.querySelector<HTMLElement>(\":scope input, :scope select, :scope textarea, :scope button\")\n ?.focus();\n });\n const register = rowApi?.register;\n\n // Layout, not passive: the registry is what \"on screen right now\" means to the session, and a\n // commit that unmounts this editor is followed by microtasks — a settling write among them —\n // long before a passive cleanup would have run. A registration that outlives its DOM would put\n // a failure on a column nobody can see. Bound to the controller and the column, not to this\n // component's lifetime: in hook mode the table can be swapped for another instance while React\n // keeps this editor, and a registration left with the controller that is gone means the one\n // now in charge cannot reach it.\n useLayoutEffect(() => register?.(columnId, { focus: focusEditor, redraw: redrawFromSession }), [register, columnId, focusEditor, redrawFromSession]);\n\n if (!normalized || !editing) {\n return null;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // An inner control that consumed the key (a select picking its option) keeps it.\n if (event.defaultPrevented) {\n return;\n }\n\n if (event.key === \"Enter\") {\n event.preventDefault();\n editing.row.stop({ commit: true });\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n editing.row.stop({ commit: false });\n }\n };\n\n const label = labels.editColumn(columnHeaderText(cell.column));\n\n const editor\n = normalized.kind === \"instant\"\n ? normalized.render({\n row: cell.row,\n column: cell.column,\n value: draft,\n // In row mode an instant control joins the row like any other editor: its commit\n // stages the value in the row draft, and the atomic row commit owns the write\n // (docs/editing.md#instant-editing).\n commit: (value: unknown) => {\n setValue(value);\n\n return true;\n },\n error: editError,\n pending,\n label\n })\n : normalized.render({\n row: cell.row,\n column: cell.column,\n value: draft,\n setValue,\n // Row mode: commit/cancel operate on the whole row, matching the keyboard map. The\n // result is the row's real one — validation across every editable column, and the\n // application's handler — not an acknowledgement that the request was made.\n commit: () => editing.row.commit(),\n cancel: () => editing.row.stop({ commit: false }),\n error: editError,\n pending,\n mode: \"row\",\n autoFocus,\n label\n });\n\n return (\n <div\n ref={containerRef}\n aria-busy={pending || undefined}\n aria-label={pending ? labels.editPending : undefined}\n data-pending={pending || undefined}\n onClick={event => event.stopPropagation()}\n onDoubleClick={event => event.stopPropagation()}\n onKeyDown={handleKeyDown}\n {...getStyles(\"cellEditor\")}\n >\n {editor}\n {pending && <Loader size={12} />}\n </div>\n );\n}\n","/**\n * Pinned-column geometry. Offsets are referenced as CSS variables (written table-level next to\n * the width variables), so a resize drag updates one style object and never re-renders rows;\n * TanStack v9's logical `start`/`end` positions pair with logical insets, so RTL mirrors for\n * free.\n */\nimport type { RowData } from \"@tanstack/react-table\";\nimport type { CSSProperties } from \"react\";\n\nimport type { Column } from \"./types\";\n\nimport { columnAfterVar, columnStartVar } from \"./utils\";\n\nexport function pinnedCellStyle<TData extends RowData>(column: Column<TData, unknown>): CSSProperties | undefined {\n const pinned = column.getIsPinned();\n\n if (pinned === \"start\") {\n return { insetInlineStart: `var(${columnStartVar(column.id)})` };\n }\n\n if (pinned === \"end\") {\n return { insetInlineEnd: `var(${columnAfterVar(column.id)})` };\n }\n\n return undefined;\n}\n\n/**\n * The boundary cell of a pinned block — where the scroll shadow renders.\n */\nexport function pinnedEdge<TData extends RowData>(column: Column<TData, unknown>): \"start\" | \"end\" | undefined {\n if (column.getIsPinned() === \"start\" && column.getIsLastColumn(\"start\")) {\n return \"start\";\n }\n\n if (column.getIsPinned() === \"end\" && column.getIsFirstColumn(\"end\")) {\n return \"end\";\n }\n\n return undefined;\n}\n","import type { PointerEvent } from \"react\";\n\n/**\n * The tooltip behind `meta.truncate` (docs/columns.md) and the header label.\n *\n * Resolved at hover time from the element itself, for three reasons the old render-time\n * `title={cell.getValue()}` got wrong: the rendered text is what is actually clipped (a custom\n * `cell` renderer's output included), a non-primitive value still has readable text, and a\n * tooltip is only worth having when the text really overflows.\n *\n * Deliberately imperative: measuring every truncated cell on every render would thrash layout\n * across a virtualized body, and the read here happens once, on the hover that precedes the\n * browser's own tooltip delay. Native `title` therefore reaches pointer users only — a richer\n * tooltip is a `meta.cellProps` or custom `cell` job.\n */\nexport function syncTruncationTitle(event: PointerEvent<HTMLElement>): void {\n const element = event.currentTarget;\n const text = element.scrollWidth > element.clientWidth ? element.textContent : null;\n\n if (text === null || text === \"\") {\n element.removeAttribute(\"title\");\n } else {\n element.title = text;\n }\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Header } from \"./types\";\n\n/**\n * Column virtualization (docs/virtualization.md#column-virtualization). Only the center zone\n * windows — pinned columns are sticky and always mounted — and the window is the width\n * engine's own numbers, not a second virtualizer: every column width is already an exact\n * integer pixel (use-column-widths.ts), so the rendered range is a binary search over their\n * prefix sums, derived in the same render pass that draws the colgroup. A measuring\n * virtualizer would hold a parallel copy of the horizontal geometry that resize, responsive\n * breakpoints, and grow redistribution would each have to invalidate by hand.\n */\nimport { startTransition, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\n\nimport { useEventCallback } from \"./utils\";\n\nconst DEFAULT_COLUMN_OVERSCAN = 4;\n\nexport { DEFAULT_COLUMN_OVERSCAN };\n\nexport interface ColumnWindowInput {\n enabled: boolean;\n /**\n * Extra columns rendered beyond the visible range on each side.\n */\n overscan: number;\n viewport: HTMLDivElement | null;\n /**\n * Visible center leaf column ids in display order — the zone that windows.\n */\n centerColumnIds: readonly string[];\n /**\n * The width engine's resolved integer pixels per visible leaf column id.\n */\n widths: Record<string, number>;\n /**\n * The sticky pinned overlays narrow the visible center strip by their summed widths.\n */\n pinnedStartWidth: number;\n pinnedEndWidth: number;\n}\n\nexport interface ColumnWindow {\n /**\n * The rendered center slice, `[start, end)` over the center zone.\n */\n start: number;\n end: number;\n /**\n * Widths of the not-rendered runs — the two spacer `<col>`s.\n */\n leadingSpace: number;\n trailingSpace: number;\n}\n\n/**\n * The render-facing descriptor: the window plus the display geometry every renderer tiles by.\n */\nexport interface ColumnWindowView extends ColumnWindow {\n pinnedStartCount: number;\n pinnedEndCount: number;\n centerCount: number;\n /**\n * Total visible leaf columns — `aria-colcount`.\n */\n totalLeafCount: number;\n /**\n * Display index (pinned-aware) per visible leaf column id; `aria-colindex` is this + 1.\n */\n displayIndexById: ReadonlyMap<string, number>;\n}\n\n/**\n * First index whose value is greater than `target` (`values` ascending).\n */\nfunction upperBound(values: readonly number[], target: number): number {\n let low = 0;\n let high = values.length;\n\n while (low < high) {\n const mid = (low + high) >> 1;\n\n if (values[mid]! <= target) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n\n return low;\n}\n\n/**\n * First index whose value is at least `target` (`values` ascending).\n */\nfunction lowerBound(values: readonly number[], target: number): number {\n let low = 0;\n let high = values.length;\n\n while (low < high) {\n const mid = (low + high) >> 1;\n\n if (values[mid]! < target) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n\n return low;\n}\n\n/**\n * The measured window over `[0, centerCount)` given a scroll position: the columns whose spans\n * intersect the visible center strip, extended by `overscan` on each side. Pure — the hook's\n * unit-testable core.\n */\nexport function measureColumnWindow(input: {\n offsets: readonly number[];\n scrollLeft: number;\n clientWidth: number;\n pinnedStartWidth: number;\n pinnedEndWidth: number;\n overscan: number;\n}): { start: number; end: number } {\n const count = input.offsets.length - 1;\n // RTL viewports report a negative scrollLeft; the window only needs the distance scrolled.\n const from = Math.abs(input.scrollLeft);\n const to = from + Math.max(0, input.clientWidth - input.pinnedStartWidth - input.pinnedEndWidth);\n const first = Math.max(0, upperBound(input.offsets, from) - 1);\n const last = Math.max(first + 1, lowerBound(input.offsets, to));\n\n return {\n start: Math.max(0, first - input.overscan),\n end: Math.min(count, last + input.overscan)\n };\n}\n\nexport function useColumnWindow({\n enabled,\n overscan,\n viewport,\n centerColumnIds,\n widths,\n pinnedStartWidth,\n pinnedEndWidth\n}: ColumnWindowInput): ColumnWindow | null {\n // Prefix sums over the center zone: offsets[i] is where column i starts, offsets at the end\n // is the zone's total width.\n const offsets = useMemo(\n () => {\n const out: number[] = [0];\n let sum = 0;\n\n for (const id of centerColumnIds) {\n sum += widths[id] ?? 0;\n out.push(sum);\n }\n\n return out;\n },\n [centerColumnIds, widths]\n );\n\n const [range, setRange] = useState({ end: 0, start: 0 });\n\n // Chase state: at most one transition is ever in flight, and the freshest target rides a ref\n // so that flight lands on the newest window it can. Restarting the transition per scroll\n // event instead would starve it — a smooth scroll fires one event per frame, each restart\n // abandons the sliced render, and nothing commits until the scrolling stops.\n const chaseTarget = useRef<{ start: number; end: number } | null>(null);\n const transitionPending = useRef(false);\n const lastScrollLeft = useRef(0);\n\n const measure = useEventCallback((defer: boolean) => {\n if (!enabled || !viewport || centerColumnIds.length === 0) {\n return;\n }\n\n const scrollLeft = Math.abs(viewport.scrollLeft);\n const strip = Math.max(0, viewport.clientWidth - pinnedStartWidth - pinnedEndWidth);\n // A discrete leap (scrollToColumn, a scrollbar jump) has no continuation to starve and no\n // shear to fear — one event, and the mirror already ran ahead of this listener — while a\n // transition would leave the landing blank for a render. It applies synchronously.\n const jumped = Math.abs(scrollLeft - lastScrollLeft.current) > strip;\n lastScrollLeft.current = scrollLeft;\n\n const next = measureColumnWindow({\n clientWidth: viewport.clientWidth,\n offsets,\n overscan,\n pinnedEndWidth,\n pinnedStartWidth,\n scrollLeft: viewport.scrollLeft\n });\n\n // The committed window shares nothing with where the viewport now is — the visible strip\n // is already fully blank, so a transition has nothing left to keep responsive. Committing\n // synchronously puts content under the pointer now; this is what keeps a fast scrollbar\n // drag showing bands instead of white.\n const blank = next.start >= range.end || next.end <= range.start;\n\n if (!defer || jumped || blank) {\n chaseTarget.current = null;\n setRange(previous => previous.start === next.start && previous.end === next.end ? previous : next);\n\n return;\n }\n\n if (next.start === range.start && next.end === range.end) {\n chaseTarget.current = null;\n\n return;\n }\n\n // Scroll-driven shifts render as a TRANSITION — a shift re-renders every windowed cell,\n // and a blocking render freezes the main-thread scrollLeft mirror while the compositor\n // keeps moving the body, shearing the header away for the render's whole duration.\n // Time-sliced, the render yields and the mirror stays inside the frame; the window filling\n // in a beat behind a fast fling is the standard virtualization trade.\n chaseTarget.current = next;\n\n if (transitionPending.current) {\n return;\n }\n\n transitionPending.current = true;\n // Read at processing time, so the flight lands on the newest target. ALWAYS a fresh\n // object, even when a synchronous commit got there first (`chaseTarget` null) and the\n // values repeat: `transitionPending` is only cleared by the commit effect below, so a\n // flight that bailed out of committing would jam the chase shut for good — the jitter\n // deadlock a scrollbar drag reliably found.\n startTransition(() => {\n setRange(previous => {\n return { ...chaseTarget.current ?? previous };\n });\n });\n });\n\n // The chase step: a commit landed, so re-measure from the live scroll position — a smooth\n // scroll has moved on while the transition rendered, and the next hop starts from here.\n // Terminates because the measure above no-ops once the window matches the scroll.\n useEffect(() => {\n transitionPending.current = false;\n measure(true);\n }, [range, measure]);\n\n // A layout effect so the first real window replaces the minimal initial render before paint.\n // Subscriptions only — re-measuring on geometry changes is the next effect's job, so a width\n // change never churns the listener and the observer (a resize drag reshapes `offsets` on\n // every pointer move).\n useLayoutEffect(() => {\n if (!enabled || !viewport) {\n return;\n }\n\n measure(false);\n const onScroll = () => measure(true);\n viewport.addEventListener(\"scroll\", onScroll, { passive: true });\n const observer = new ResizeObserver(() => measure(false));\n observer.observe(viewport);\n\n return () => {\n viewport.removeEventListener(\"scroll\", onScroll);\n observer.disconnect();\n };\n }, [enabled, viewport, measure]);\n\n // A width or pinned-boundary change re-derives the range from the same scroll position in\n // the same commit that moved the columns; `measure` itself guards the disabled states.\n useLayoutEffect(() => {\n measure(false);\n }, [measure, offsets, pinnedStartWidth, pinnedEndWidth]);\n\n const count = centerColumnIds.length;\n\n return useMemo(\n () => {\n if (!enabled || count === 0) {\n return null;\n }\n\n // Clamped against the CURRENT columns: the measured range may predate a width or\n // composition change by one commit, and the spaces must always sum with the rendered\n // columns to the exact zone total.\n const start = Math.min(range.start, count - 1);\n const end = Math.max(start + 1, Math.min(range.end, count));\n\n return {\n end,\n leadingSpace: offsets[start] ?? 0,\n start,\n trailingSpace: (offsets[count] ?? 0) - (offsets[end] ?? 0)\n };\n },\n [enabled, count, range, offsets]\n );\n}\n\n// ------------------------------------------------------------------------------------------------\n// Tiling helpers — how the three synced tables render against a window\n// ------------------------------------------------------------------------------------------------\n\n/**\n * Rendered column count including the spacer cols — what a full-width cell (detail panel,\n * loader row) spans.\n */\nexport function renderedColCount(view: ColumnWindowView | null, leafColumnCount: number): number {\n if (view === null) {\n return leafColumnCount;\n }\n\n return view.pinnedStartCount\n + (view.end - view.start)\n + view.pinnedEndCount\n + (view.start > 0 ? 1 : 0)\n + (view.end < view.centerCount ? 1 : 0);\n}\n\nexport interface WindowedRowCells<T> {\n leading: T[];\n windowed: T[];\n trailing: T[];\n}\n\n/**\n * A leaf-level row's cells against the window. `cells` is the full display-ordered list, so a\n * segment cell's display index is its segment offset plus the segment's start.\n */\nexport function windowRowCells<T>(cells: readonly T[], view: ColumnWindowView): WindowedRowCells<T> {\n return {\n leading: cells.slice(0, view.pinnedStartCount),\n trailing: view.pinnedEndCount === 0 ? [] : cells.slice(cells.length - view.pinnedEndCount),\n windowed: cells.slice(view.pinnedStartCount + view.start, view.pinnedStartCount + view.end)\n };\n}\n\nexport type WindowedHeaderCell<TData extends RowData>\n = | { kind: \"header\"; header: Header<TData, unknown>; colSpan: number; ariaColIndex: number }\n | { kind: \"spacer\"; edge: \"leading\" | \"trailing\" };\n\n/**\n * One clamp rule for every header and footer row (docs/virtualization.md#column-virtualization):\n * a header's colSpan is the number of its leaf columns actually rendered, plus a spacer col its\n * span fully contains (a header whose rendered leaves sit on both sides of a hidden run is one\n * rectangle and must absorb it); headers with nothing rendered vanish, and a spacer col nobody\n * absorbed stands alone. Well-defined because v9 builds header groups over the display-ordered\n * leaves — every header instance covers a contiguous run, pinning splits included.\n */\nexport function windowHeaderCells<TData extends RowData>(\n headers: Array<Header<TData, unknown>>,\n view: ColumnWindowView\n): Array<WindowedHeaderCell<TData>> {\n const windowStart = view.pinnedStartCount + view.start;\n const windowEnd = view.pinnedStartCount + view.end;\n const centerEnd = view.pinnedStartCount + view.centerCount;\n\n const isRendered = (index: number) => index < view.pinnedStartCount || index >= centerEnd || (index >= windowStart && index < windowEnd);\n\n const out: Array<WindowedHeaderCell<TData>> = [];\n let leadingPending = view.start > 0;\n let trailingPending = view.end < view.centerCount;\n\n for (const header of headers) {\n let low = Infinity;\n let high = -Infinity;\n let renderedCount = 0;\n let firstRendered = Infinity;\n // Unique indexes: for a placeholder chain (an ungrouped column passing through a group\n // row) v9's getLeafHeaders yields the same leaf column more than once.\n const seen = new Set<number>();\n\n for (const leaf of header.getLeafHeaders()) {\n const index = view.displayIndexById.get(leaf.column.id);\n\n if (index !== undefined && !seen.has(index)) {\n seen.add(index);\n low = Math.min(low, index);\n high = Math.max(high, index);\n\n if (isRendered(index)) {\n renderedCount += 1;\n firstRendered = Math.min(firstRendered, index);\n }\n }\n }\n\n if (renderedCount === 0) {\n continue;\n }\n\n // A rendered leaf in the pinned-start zone AND one at or past the window start puts the\n // leading hidden run inside this header's rectangle; same shape on the trailing side.\n const absorbLeading = leadingPending && low < view.pinnedStartCount && high >= windowStart;\n const absorbTrailing = trailingPending && low < windowEnd && high >= centerEnd;\n\n if (leadingPending && !absorbLeading && high >= windowStart) {\n out.push({ edge: \"leading\", kind: \"spacer\" });\n leadingPending = false;\n }\n\n if (trailingPending && !absorbTrailing && low >= windowEnd) {\n out.push({ edge: \"trailing\", kind: \"spacer\" });\n trailingPending = false;\n }\n\n if (absorbLeading) {\n leadingPending = false;\n }\n\n if (absorbTrailing) {\n trailingPending = false;\n }\n\n out.push({\n ariaColIndex: firstRendered + 1,\n colSpan: renderedCount + (absorbLeading ? 1 : 0) + (absorbTrailing ? 1 : 0),\n header,\n kind: \"header\"\n });\n }\n\n if (trailingPending) {\n out.push({ edge: \"trailing\", kind: \"spacer\" });\n }\n\n return out;\n}\n","/**\n * Sticky offsets for pinned display items: each top item sticks at the body edge plus the measured\n * heights above it (bottom items mirror upward). One shared `top` value would stack every pinned\n * row/detail item onto the same edge. Heights are measured, not assumed — they follow content and\n * spacing.\n */\nimport { useCallback, useLayoutEffect, useRef, useState } from \"react\";\n\ninterface PinnedRowOffsets {\n top: number[];\n bottom: number[];\n}\n\nconst NONE: PinnedRowOffsets = { top: [], bottom: [] };\n\nexport interface PinnedRowMeasurer {\n offsets: PinnedRowOffsets;\n registerTopRow: (index: number) => (element: Element | null) => void;\n registerBottomRow: (index: number) => (element: Element | null) => void;\n}\n\nexport function usePinnedRowOffsets(topCount: number, bottomCount: number): PinnedRowMeasurer {\n const [offsets, setOffsets] = useState<PinnedRowOffsets>(NONE);\n const topRows = useRef<Array<Element | null>>([]);\n const bottomRows = useRef<Array<Element | null>>([]);\n const topCallbacks = useRef<Array<(element: Element | null) => void>>([]);\n const bottomCallbacks = useRef<Array<(element: Element | null) => void>>([]);\n const observerRef = useRef<ResizeObserver | null>(null);\n\n /**\n * How many items of each end actually reached the screen. Mirrored in a layout effect, never\n * read from the props while measuring: refs are shared between the current tree and a\n * work-in-progress one, so a transition React renders and then throws away — a sibling suspends\n * — would otherwise take a row that is still on screen out of the measurement, and its ref\n * callback would never run again to put it back.\n */\n const committedCounts = useRef({ bottom: bottomCount, top: topCount });\n\n const measure = useCallback(() => {\n const cumulative = (elements: Array<Element | null>, count: number) => {\n const result: number[] = [];\n let sum = 0;\n\n for (let index = 0; index < count; index += 1) {\n result.push(sum);\n sum += elements[index]?.getBoundingClientRect().height ?? 0;\n }\n\n return result;\n };\n\n // Only what is on screen is measured, and all of it: an element registered for a row that has\n // not committed yet is not part of the layout, and a row that has is, whether or not anything\n // has re-attached its element since.\n const counts = committedCounts.current;\n\n // Bottom rows stack upward: the LAST bottom-pinned row sits at 0, the ones above it offset\n // by the heights below them.\n const bottom: number[] = [];\n let below = 0;\n\n for (let index = counts.bottom - 1; index >= 0; index -= 1) {\n bottom[index] = below;\n below += bottomRows.current[index]?.getBoundingClientRect().height ?? 0;\n }\n\n const next = { top: cumulative(topRows.current, counts.top), bottom };\n\n setOffsets(previous => previous.top.join(\",\") === next.top.join(\",\") && previous.bottom.join(\",\") === next.bottom.join(\",\")\n ? previous\n : next);\n }, []);\n\n useLayoutEffect(() => {\n const observer = new ResizeObserver(measure);\n observerRef.current = observer;\n\n for (const element of [...topRows.current, ...bottomRows.current]) {\n if (element) {\n observer.observe(element);\n }\n }\n\n measure();\n\n return () => {\n observerRef.current = null;\n observer.disconnect();\n };\n }, [measure]);\n\n /**\n * A real change in how many items are pinned: the counts the measurement works from move here,\n * in the commit phase, and the rows that left take their elements with them. Then everything\n * still there is measured again, because what stays has moved.\n */\n useLayoutEffect(() => {\n const counts = committedCounts.current;\n\n if (counts.top === topCount && counts.bottom === bottomCount) {\n return;\n }\n\n committedCounts.current = { bottom: bottomCount, top: topCount };\n topRows.current.length = topCount;\n bottomRows.current.length = bottomCount;\n measure();\n });\n\n const register = useCallback(\n (\n elements: { current: Array<Element | null> },\n callbacks: { current: Array<(element: Element | null) => void> },\n index: number\n ) => {\n const existing = callbacks.current[index];\n\n if (existing) {\n return existing;\n }\n\n let currentElement: Element | null = null;\n\n const callback = (element: Element | null) => {\n if (element === currentElement) {\n return;\n }\n\n if (currentElement) {\n observerRef.current?.unobserve(currentElement);\n }\n\n currentElement = element;\n // Written whatever the array's length is: a row growing the list attaches its element\n // during the same commit that carries the new count, and the effect above has not run\n // yet. The effect is what trims anything the screen no longer holds.\n elements.current[index] = element;\n\n if (element) {\n observerRef.current?.observe(element);\n }\n\n measure();\n };\n\n callbacks.current[index] = callback;\n\n return callback;\n },\n [measure]\n );\n\n const registerTopRow = useCallback(\n (index: number) => register(topRows, topCallbacks, index),\n [register]\n );\n\n const registerBottomRow = useCallback(\n (index: number) => register(bottomRows, bottomCallbacks, index),\n [register]\n );\n\n return {\n offsets,\n registerTopRow,\n registerBottomRow\n };\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { Virtualizer } from \"@tanstack/react-virtual\";\nimport type { MouseEvent, ReactNode, RefObject } from \"react\";\n\nimport type { RowReorderTarget } from \"./row-reorder\";\nimport type { Cell, ColumnDef, DataTableInstantEditRenderer, Row, TableInstance } from \"./types\";\nimport type { ColumnWindowView } from \"./use-column-window\";\n\n/**\n * The body: display-row synthesis (detail panels become synthetic rows so every <tr> is exactly\n * one virtual item), spacer-row virtualization in normal table flow, sticky pinned rows, grouped\n * and aggregated cells, tree indentation, skeleton and loader rows. Rows are memoized on\n * explicit volatile props — resizing never re-renders them (widths and pinned offsets are CSS\n * variables).\n */\nimport { ActionIcon, Button, Loader, Table as MantineTable, Skeleton } from \"@mantine/core\";\nimport { flexRender } from \"@tanstack/react-table\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { memo, useCallback, useEffect, useLayoutEffect, useMemo, useReducer } from \"react\";\n\nimport { columnHeaderText, EXPANDER_COLUMN_ID, isInternalColumn, ROW_DRAG_COLUMN_ID, SELECTION_COLUMN_ID } from \"./build-columns\";\nimport { canEditCell, CellEditor, RowCellEditor } from \"./cell-editor\";\nimport { useDataTableContext } from \"./context\";\nimport { cellValue, normalizeEdit } from \"./edit-meta\";\nimport { mergeElementProps, resolveElementProps } from \"./element-props\";\nimport { warnOnce } from \"./env\";\nimport { pinnedCellStyle, pinnedEdge } from \"./pinning\";\nimport { syncTruncationTitle } from \"./truncate\";\nimport { renderedColCount, windowRowCells } from \"./use-column-window\";\nimport { usePinnedRowOffsets } from \"./use-pinned-row-offsets\";\nimport { useEventCallback } from \"./utils\";\n\nconst TREE_INDENT_PX = 20;\nconst DEFAULT_ESTIMATED_ROW_HEIGHT = 44;\nconst DEFAULT_OVERSCAN = 8;\n\nexport interface VirtualizationConfig {\n estimateHeight: number;\n overscan: number;\n}\n\nexport type DisplayRow<TData extends RowData>\n = | { kind: \"data\"; key: string; row: Row<TData>; dataIndex: number }\n | { kind: \"detail\"; key: string; row: Row<TData> };\n\n/**\n * Whether any leaf definition declares a merge — the gate that keeps span-index reads (and the\n * per-row span signature) entirely out of tables that never span.\n */\nfunction hasSpanningColumns(columns: Array<ColumnDef<any, any>> | undefined): boolean {\n if (!columns) {\n return false;\n }\n\n return columns.some(column => \"columns\" in column && Array.isArray(column.columns)\n ? hasSpanningColumns(column.columns)\n : column.spanRows !== undefined || column.spanColumns !== undefined);\n}\n\n/**\n * One stable identity for an unoccupied pinned zone, so the display-row memos can hold.\n */\nconst NO_ROWS: Array<Row<any>> = [];\n\nexport function buildDisplayRows<TData extends RowData>(rows: Array<Row<TData>>, withDetailPanels: boolean): Array<DisplayRow<TData>> {\n const display: Array<DisplayRow<TData>> = [];\n let dataIndex = 0;\n\n for (const row of rows) {\n display.push({\n kind: \"data\",\n key: row.id,\n row,\n dataIndex\n });\n dataIndex += 1;\n\n // A grouped row's expansion reveals its children, not a panel — `renderDetailPanel` speaks\n // about a data row (docs/grouping.md#boundaries).\n if (withDetailPanels && row.getIsExpanded() && !row.getIsGrouped()) {\n display.push({\n kind: \"detail\",\n key: `${row.id}:detail`,\n row\n });\n }\n }\n\n return display;\n}\n\n/**\n * The same count without the array. `aria-rowcount` needs the number, not the rows, and building\n * three throwaway `DisplayRow[]`s per render is O(N) allocation the virtualizer then repeats on\n * every scroll range change.\n */\nexport function countDisplayRows<TData extends RowData>(rows: Array<Row<TData>>, withDetailPanels: boolean): number {\n if (!withDetailPanels) {\n return rows.length;\n }\n\n let count = rows.length;\n\n for (const row of rows) {\n if (row.getIsExpanded() && !row.getIsGrouped()) {\n count += 1;\n }\n }\n\n return count;\n}\n\n// ------------------------------------------------------------------------------------------------\n// Cells\n// ------------------------------------------------------------------------------------------------\n\n/**\n * Grouped cell: expander, the grouped value, and the group size.\n */\nfunction GroupCell({ cell }: { cell: Cell<any, unknown> }) {\n const {\n labels,\n icons,\n expansion\n } = useDataTableContext();\n const { row } = cell;\n const expandedGroup = row.getIsExpanded();\n const canExpandGroup = row.getCanExpand();\n\n return (\n <span data-group-cell>\n <ActionIcon\n aria-expanded={expandedGroup}\n aria-label={expandedGroup ? labels.collapseRow : labels.expandRow}\n data-expanded={expandedGroup || undefined}\n size=\"xs\"\n variant=\"subtle\"\n onClick={event => {\n event.stopPropagation();\n expansion?.toggle(row.id, expandedGroup, canExpandGroup);\n }}\n >\n <icons.expandRow size={12} />\n </ActionIcon>\n\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n\n <span data-group-count>\n (\n {row.subRows.length}\n )\n </span>\n </span>\n );\n}\n\n/**\n * The instant-apply host (docs/editing.md#instant-editing): a change in the cell *is* the\n * commit, so no session ever opens. A view of its target in the controller, like the editor\n * hosts are views of their session — what a commit leaves behind must survive the column being\n * hidden, a breakpoint removing it, or a virtual scroll taking the row off screen, none of\n * which are the write landing. The column's own renderer supplies the control; the host owns\n * the chrome around it — the pending loader, the failure alert, and the click fences that keep\n * `onRowClick` out.\n */\nfunction InstantCell({ cell, render }: { cell: Cell<any, unknown>; render: DataTableInstantEditRenderer<any, unknown> }) {\n const { labels, getStyles } = useDataTableContext();\n const { table } = cell.getContext();\n const instant = table.options.meta?.ledger?.editing.instant;\n const rowId = cell.row.id;\n const columnId = cell.column.id;\n\n const [, redraw] = useReducer((token: number) => token + 1, 0);\n const redrawFromTarget = useEventCallback(() => redraw());\n const register = instant?.register;\n\n // Layout, not passive: the registry is what \"on screen right now\" means to the target, and a\n // commit that unmounts this control is followed by microtasks — a settling write among them.\n useLayoutEffect(\n () => register?.(rowId, columnId, { redraw: redrawFromTarget }),\n [register, rowId, columnId, redrawFromTarget]\n );\n\n if (!instant) {\n return null;\n }\n\n const value = instant.value(rowId, columnId, cellValue(cell));\n const pending = instant.pending(rowId, columnId);\n const error = instant.error(rowId, columnId);\n\n return (\n <span\n aria-busy={pending || undefined}\n data-pending={pending || undefined}\n onClick={event => event.stopPropagation()}\n onDoubleClick={event => event.stopPropagation()}\n {...getStyles(\"instantCell\")}\n >\n {render({\n row: cell.row,\n column: cell.column,\n value,\n commit: next => instant.commit(rowId, columnId, next),\n pending,\n error,\n label: labels.editColumn(columnHeaderText(cell.column))\n })}\n\n {/* Out of flow (`instantSpinner`): the control must not move while its write is out. */}\n {pending && <Loader aria-label={labels.editPending} size={12} {...getStyles(\"instantSpinner\")} />}\n {error && <span role=\"alert\">{error}</span>}\n </span>\n );\n}\n\ninterface DataCellProps {\n cell: Cell<any, unknown>;\n editing: boolean;\n /**\n * The whole row is in row-mode editing — every editable cell hosts its editor.\n */\n rowEditing: boolean;\n isFirstDataCell: boolean;\n depth: number;\n /**\n * Merged-cell extents (1 = no span); covered cells are skipped by the row, never rendered.\n */\n rowSpan: number;\n colSpan: number;\n /**\n * Set only under a column window: the cell's 1-based position among ALL visible leaf columns,\n * windowed-out ones included.\n */\n ariaColIndex: number | undefined;\n}\n\nfunction DataCell({\n cell,\n editing,\n rowEditing,\n isFirstDataCell,\n depth,\n rowSpan,\n colSpan,\n ariaColIndex\n}: DataCellProps) {\n const { getStyles } = useDataTableContext();\n const { column, row } = cell;\n const { table } = cell.getContext();\n const ledger = table.options.meta?.ledger;\n const editMode = ledger?.editing.mode ?? \"cell\";\n const { meta } = column.columnDef;\n\n const grouped = cell.getIsGrouped();\n // getIsAggregated() is true for ANY row with subRows — a grouping concept that leaks into\n // trees (getSubRows) and would swallow the expander button and the author's cell renderer\n // on every parent row. Aggregated rendering only exists on real grouping rows.\n const aggregated = cell.getIsAggregated() && row.getIsGrouped();\n const placeholder = cell.getIsPlaceholder();\n // The gate, asked in the render that has to answer it. Ending a session whose eligibility is\n // gone is a side effect, so reconciliation runs after the paint — but whether an editor is on\n // the screen is this render's own question, and this render already knows the gate is shut. Ask\n // it later and the commit that shuts the gate still paints a live editor for one frame, which\n // is a frame the user can type into.\n const gateOpen = !grouped && !aggregated && !placeholder && canEditCell(cell, row);\n const editable = !editing && gateOpen;\n // `editing` / `rowEditing` are the other half: they already mean a live *session*, not merely a\n // slice that names this target — a gate that shut ends the session even when a controlled\n // application declines to close it, and neither editor may become interactive again if that\n // gate reopens (docs/architecture.md).\n const cellEditorActive = editing && gateOpen;\n const rowEditorActive = rowEditing && gateOpen;\n const normalizedEdit = normalizeEdit(meta?.edit);\n const instantEdit = normalizedEdit?.kind === \"instant\" ? normalizedEdit : null;\n\n let content: ReactNode;\n\n if (grouped) {\n content = <GroupCell cell={cell} />;\n } else if (aggregated) {\n content = flexRender(column.columnDef.aggregatedCell ?? column.columnDef.cell, cell.getContext());\n } else if (placeholder) {\n content = null;\n } else if (cellEditorActive) {\n content = <CellEditor cell={cell} />;\n } else if (rowEditorActive) {\n content = <RowCellEditor cell={cell} />;\n } else if (editable && instantEdit && editMode === \"cell\") {\n content = <InstantCell cell={cell} render={instantEdit.render} />;\n } else {\n content = flexRender(column.columnDef.cell, cell.getContext());\n\n if (meta?.truncate) {\n content = (\n <span data-truncate onPointerEnter={syncTruncationTitle}>\n {content}\n </span>\n );\n }\n }\n\n const startEditing\n = editable && !rowEditorActive && (editMode === \"row\" || !instantEdit) && ledger\n ? (event: MouseEvent) => {\n event.stopPropagation();\n\n if (editMode === \"row\") {\n ledger.editing.row.start(row.id, { focusColumnId: column.id });\n } else {\n ledger.editing.start({ rowId: row.id, columnId: column.id });\n }\n }\n : undefined;\n\n if (isFirstDataCell && depth > 0) {\n content = <div style={{ paddingInlineStart: depth * TREE_INDENT_PX }}>{content}</div>;\n }\n\n const selector\n = column.id === SELECTION_COLUMN_ID\n ? \"selectionCell\"\n : column.id === EXPANDER_COLUMN_ID\n ? \"expanderCell\"\n : column.id === ROW_DRAG_COLUMN_ID\n ? \"rowDragCell\"\n : \"cell\";\n // An injected column is a control column: nothing in it activates the row (docs/rows.md). The\n // built-in checkbox and chevron stop their own events, but the column's renderer is\n // overridable (`selectionColumn` / `expanderColumn`), and whatever an application puts there\n // cannot be expected to know that rule — so the host cell holds it instead. A `cellProps`\n // handler still runs: ledger's own is chained ahead of it, not in place of it.\n const stopActivation = isInternalColumn(column.id)\n ? (event: MouseEvent) => event.stopPropagation()\n : undefined;\n\n // Two merges, not one spread. The Styles API answer is a consumer like `cellProps` is — it\n // may carry `attributes` handlers, and those have to run *with* ledger's, not instead of\n // them, while `role` and the structural data-attributes stay ledger's. Spreading the answer\n // into the owned object would let an `attributes.selectionCell.onClick` replace the handler\n // that keeps a control column from activating its row, and rewrite `role` besides.\n const owned = mergeElementProps(getStyles(selector, { style: pinnedCellStyle(column) }), {\n \"aria-colindex\": ariaColIndex,\n \"aria-colspan\": colSpan > 1 ? colSpan : undefined,\n \"aria-rowspan\": rowSpan > 1 ? rowSpan : undefined,\n colSpan: colSpan > 1 ? colSpan : undefined,\n \"data-align\": meta?.align,\n \"data-editable\": editable || undefined,\n \"data-editing\": cellEditorActive || rowEditorActive || undefined,\n \"data-leading\": column.getIsFirstColumn() || undefined,\n \"data-ledger-column-id\": column.id,\n \"data-pinned\": column.getIsPinned() || undefined,\n \"data-pinned-edge\": pinnedEdge(column),\n role: \"cell\",\n rowSpan: rowSpan > 1 ? rowSpan : undefined,\n onClick: stopActivation ?? (ledger?.editTrigger === \"click\" ? startEditing : undefined),\n onDoubleClick: stopActivation ?? (ledger?.editTrigger === \"double-click\" ? startEditing : undefined)\n });\n\n return (\n <MantineTable.Td\n {...mergeElementProps(resolveElementProps(meta?.cellProps, cell), owned)}\n >\n {content}\n </MantineTable.Td>\n );\n}\n\n// ------------------------------------------------------------------------------------------------\n// Rows\n// ------------------------------------------------------------------------------------------------\n\ninterface DataRowProps {\n row: Row<any>;\n dataIndex: number;\n editingColumnId: string | null;\n /**\n * Row-mode editing targets this row — every editable cell mounts its editor.\n */\n editingRow: boolean;\n /**\n * A live reorder lifted this row (docs/rows.md#row-ordering) — it dims in place.\n */\n dragging: boolean;\n /**\n * The lifted row would land on this edge of this row — the drop indicator.\n */\n dropSide: \"before\" | \"after\" | null;\n selected: boolean;\n active: boolean;\n expanded: boolean;\n depth: number;\n pinKey: string;\n columnsKey: string;\n /**\n * Merged cells active for this table (never under virtualization).\n */\n spanning: boolean;\n /**\n * Per-row span signature — spans depend on NEIGHBOR rows, which this row's own props cannot\n * see, so the signature busts the memo when an adjacent change reshapes the merge.\n */\n spanKey: string;\n /**\n * Stable memo token for column definitions and editing behavior that cells read indirectly\n * through the stable TanStack table instance.\n */\n renderVersion: object;\n /**\n * The live column window — `null` renders every visible cell. Window shifts change its\n * identity, which is exactly when a row must redraw.\n */\n columnWindow: ColumnWindowView | null;\n pinnedPosition?: \"top\" | \"bottom\";\n /**\n * Sticky offset for pinned rows — measured cumulative height of the pinned rows before it.\n */\n pinnedOffset?: number;\n virtualIndex?: number;\n measureRef?: (element: Element | null) => void;\n ariaRowIndex?: number;\n}\n\nfunction DataRowImpl({\n row,\n dataIndex,\n editingColumnId,\n editingRow,\n dragging,\n dropSide,\n selected,\n active,\n expanded,\n depth,\n spanning,\n columnWindow,\n pinnedPosition,\n pinnedOffset,\n virtualIndex,\n measureRef,\n ariaRowIndex\n}: DataRowProps) {\n const {\n getStyles,\n onRowClick,\n onRowActivate,\n onRowDoubleClick,\n onRowContextMenu,\n rowProps,\n activeRowEnabled,\n setActiveRow\n } = useDataTableContext();\n\n const cells = row.getVisibleCells();\n const firstDataCellIndex = cells.findIndex(cell => !isInternalColumn(cell.column.id));\n\n /* The body scroller holds no header, so top offsets start at the scroller's own edge. */\n const pinnedStyle\n = pinnedPosition === \"top\"\n ? { top: `${pinnedOffset ?? 0}px` }\n : pinnedPosition === \"bottom\"\n ? { bottom: `${pinnedOffset ?? 0}px` }\n : undefined;\n\n const handler = (callback?: (row: Row<any>, event: MouseEvent) => void) => callback ? (event: MouseEvent) => callback(row, event) : undefined;\n\n // A click makes the row current before the consumer's own handlers see it. A click is also an\n // activation, so both fire here — `onRowClick` first, as the more specific of the two.\n const handleClick = onRowClick || onRowActivate || activeRowEnabled\n ? (event: MouseEvent) => {\n if (activeRowEnabled) {\n setActiveRow?.(row.id);\n }\n\n onRowClick?.(row, event);\n onRowActivate?.(row, event);\n }\n : undefined;\n\n return (\n <MantineTable.Tr\n ref={measureRef}\n {...mergeElementProps(resolveElementProps(rowProps, row), {\n \"aria-current\": active || undefined,\n \"aria-rowindex\": ariaRowIndex,\n \"aria-selected\": selected || undefined,\n \"data-active\": active || undefined,\n \"data-clickable\": handleClick ? true : undefined,\n \"data-dragging\": dragging || undefined,\n \"data-drop-side\": dropSide ?? undefined,\n \"data-editing-row\": editingRow || undefined,\n \"data-expanded\": expanded || undefined,\n \"data-index\": virtualIndex,\n \"data-parity\": dataIndex >= 0 ? dataIndex % 2 === 0 ? \"odd\" : \"even\" : undefined,\n \"data-pinned-row\": pinnedPosition,\n \"data-row-id\": row.id,\n \"data-selected\": selected || undefined,\n role: \"row\",\n onClick: handleClick,\n onContextMenu: handler(onRowContextMenu),\n onDoubleClick: handler(onRowDoubleClick),\n ...getStyles(\"row\", { style: pinnedStyle })\n })}\n >\n {renderRowCells()}\n </MantineTable.Tr>\n );\n\n // Cells against the column window: pinned segments in full, the windowed center slice, and\n // spacer cells over the spacer cols (docs/virtualization.md#column-virtualization). Spanning\n // never coexists with a window (the body gates it), so the two branches stay disjoint.\n function renderRowCells(): ReactNode {\n const renderCell = (cell: Cell<any, unknown>, displayIndex: number) => {\n if (spanning && cell.getIsCovered()) {\n return null;\n }\n\n return (\n <DataCell\n key={cell.id}\n ariaColIndex={columnWindow === null ? undefined : displayIndex + 1}\n cell={cell}\n colSpan={spanning ? cell.getColSpan() : 1}\n depth={depth}\n editing={editingColumnId === cell.column.id}\n isFirstDataCell={displayIndex === firstDataCellIndex}\n rowEditing={editingRow}\n rowSpan={spanning ? cell.getRowSpan() : 1}\n />\n );\n };\n\n if (columnWindow === null) {\n return cells.map((cell, index) => renderCell(cell, index));\n }\n\n const segments = windowRowCells(cells, columnWindow);\n const windowedStart = columnWindow.pinnedStartCount + columnWindow.start;\n const trailingStart = cells.length - columnWindow.pinnedEndCount;\n\n return (\n <>\n {segments.leading.map((cell, index) => renderCell(cell, index))}\n {columnWindow.start > 0 && <td aria-hidden data-ledger-spacer />}\n {segments.windowed.map((cell, index) => renderCell(cell, windowedStart + index))}\n {columnWindow.end < columnWindow.centerCount && <td aria-hidden data-ledger-spacer />}\n {segments.trailing.map((cell, index) => renderCell(cell, trailingStart + index))}\n </>\n );\n }\n}\n\nconst DataRow = memo(DataRowImpl) as typeof DataRowImpl;\n\ninterface DetailRowProps {\n row: Row<any>;\n /**\n * The panel renderer of the render that put this row on screen. A prop rather than a context\n * field because an application writes it inline: taking its identity into the context value\n * would rebuild the context on every render and leave nothing below memoized (context.ts).\n */\n renderDetailPanel?: (row: Row<any>) => ReactNode;\n colSpan: number;\n /**\n * The panel dims with its lifted parent, and carries the \"after the pair\" drop indicator\n * (docs/rows.md#row-ordering).\n */\n dragging: boolean;\n dropSide: \"after\" | null;\n pinnedPosition?: \"top\" | \"bottom\";\n pinnedOffset?: number;\n virtualIndex?: number;\n measureRef?: (element: Element | null) => void;\n ariaRowIndex?: number;\n}\n\nfunction DetailRow({\n row,\n renderDetailPanel,\n colSpan,\n dragging,\n dropSide,\n pinnedPosition,\n pinnedOffset,\n virtualIndex,\n measureRef,\n ariaRowIndex\n}: DetailRowProps) {\n const { getStyles } = useDataTableContext();\n const pinnedStyle\n = pinnedPosition === \"top\"\n ? { top: `${pinnedOffset ?? 0}px` }\n : pinnedPosition === \"bottom\"\n ? { bottom: `${pinnedOffset ?? 0}px` }\n : undefined;\n\n return (\n <MantineTable.Tr\n ref={measureRef}\n data-detail-row\n aria-rowindex={ariaRowIndex}\n data-dragging={dragging || undefined}\n data-drop-side={dropSide ?? undefined}\n data-index={virtualIndex}\n data-pinned-row={pinnedPosition}\n role=\"row\"\n {...getStyles(\"row\", { style: pinnedStyle })}\n >\n <MantineTable.Td colSpan={colSpan} role=\"cell\" {...getStyles(\"detailPanel\")}>\n {renderDetailPanel?.(row)}\n </MantineTable.Td>\n </MantineTable.Tr>\n );\n}\n\n// ------------------------------------------------------------------------------------------------\n// Loading rows\n// ------------------------------------------------------------------------------------------------\n\nfunction SkeletonRows({\n rowCount,\n columnCount,\n ariaRowIndexStart\n}: {\n rowCount: number;\n columnCount: number;\n ariaRowIndexStart?: number;\n}) {\n const { getStyles } = useDataTableContext();\n\n return (\n <>\n {Array.from({ length: rowCount }, (_, rowIndex) => (\n <MantineTable.Tr\n key={rowIndex}\n aria-rowindex={ariaRowIndexStart === undefined ? undefined : ariaRowIndexStart + rowIndex}\n role=\"row\"\n {...getStyles(\"row\")}\n >\n {Array.from({ length: columnCount }, (_, columnIndex) => (\n <MantineTable.Td key={columnIndex} role=\"cell\" {...getStyles(\"cell\")}>\n <Skeleton height={10} radius=\"sm\" />\n </MantineTable.Td>\n ))}\n </MantineTable.Tr>\n ))}\n </>\n );\n}\n\nfunction LoaderRow({ colSpan, ariaRowIndex }: { colSpan: number; ariaRowIndex?: number }) {\n const { getStyles, labels } = useDataTableContext();\n\n return (\n <MantineTable.Tr aria-rowindex={ariaRowIndex} role=\"row\" {...getStyles(\"loaderRow\")}>\n <MantineTable.Td colSpan={colSpan} role=\"cell\">\n <div {...getStyles(\"loaderRowContent\")}>\n {/* dots, not the oval arc: the arc's ink orbits its box, so at rest sizes it reads as\n misaligned against the text in any single frame; the dots' mass never moves. */}\n <Loader size=\"xs\" type=\"dots\" />\n <span>{labels.loadingMore}</span>\n </div>\n </MantineTable.Td>\n </MantineTable.Tr>\n );\n}\n\nfunction LoadMoreErrorRow({\n colSpan,\n message,\n ariaRowIndex,\n onRetry\n}: {\n colSpan: number;\n message: ReactNode;\n ariaRowIndex?: number;\n onRetry?: () => void;\n}) {\n const {\n getStyles,\n labels,\n icons\n } = useDataTableContext();\n\n return (\n <MantineTable.Tr data-error aria-rowindex={ariaRowIndex} role=\"row\" {...getStyles(\"loaderRow\")}>\n {/* The alert lives on the message, never on the cell: `role=\"alert\"` would replace\n `role=\"cell\"` and leave the row with no cell in the accessibility tree. */}\n <MantineTable.Td colSpan={colSpan} role=\"cell\">\n <div {...getStyles(\"loaderRowContent\")}>\n <span role=\"alert\">{message === true ? labels.loadMoreError : message}</span>\n\n {onRetry && (\n <Button\n color=\"gray\"\n leftSection={<icons.retry size={14} />}\n size=\"compact-xs\"\n variant=\"subtle\"\n onClick={onRetry}\n >\n {labels.retry}\n </Button>\n )}\n </div>\n </MantineTable.Td>\n </MantineTable.Tr>\n );\n}\n\n// ------------------------------------------------------------------------------------------------\n// Body\n// ------------------------------------------------------------------------------------------------\n\nexport interface TableBodyProps {\n table: TableInstance<any>;\n virtualization: VirtualizationConfig | null;\n /**\n * The live column window (docs/virtualization.md#column-virtualization) — `null` renders\n * every visible leaf column.\n */\n columnWindow: ColumnWindowView | null;\n viewportRef: RefObject<HTMLDivElement | null>;\n loading: boolean;\n loadingMore: boolean;\n loadMoreError: boolean | ReactNode;\n onLoadMoreRetry?: () => void;\n /**\n * The live row-reorder session (docs/rows.md#row-ordering): the lifted row dims, the target\n * row draws the drop indicator. Both `null` while the gate is off or no drag is live.\n */\n reorderSourceId: string | null;\n reorderTarget: RowReorderTarget | null;\n skeletonRowCount: number;\n onVirtualizerChange: (virtualizer: Virtualizer<HTMLDivElement, Element> | null) => void;\n}\n\nexport function TableBody({\n table,\n virtualization,\n columnWindow,\n viewportRef,\n loading,\n loadingMore,\n loadMoreError,\n onLoadMoreRetry,\n reorderSourceId,\n reorderTarget,\n skeletonRowCount,\n onVirtualizerChange\n}: TableBodyProps) {\n const { getStyles, withColumnHeaders } = useDataTableContext();\n const ledger = table.options.meta?.ledger;\n\n const withDetailPanels = Boolean(ledger?.renderDetailPanel);\n const spanningDeclared = useMemo(() => hasSpanningColumns(ledger?.columns), [ledger?.columns]);\n const spanningActive\n = spanningDeclared\n && virtualization === null\n && columnWindow === null\n && !withDetailPanels\n && table.options.enableCellSpanning !== false;\n\n if (spanningDeclared && virtualization !== null) {\n warnOnce(\n \"spanning-virtualized\",\n \"spanRows/spanColumns are ignored while virtualizedRows — a merged cell breaks the one-<tr>-per-virtual-item invariant.\"\n );\n }\n\n if (spanningDeclared && columnWindow !== null) {\n warnOnce(\n \"spanning-virtualized-columns\",\n \"spanRows/spanColumns are ignored while virtualizedColumns — a merged cell would reach across the windowed colgroup.\"\n );\n }\n\n if (spanningDeclared && withDetailPanels) {\n // Spans are computed over data rows only, but a detail panel inserts a synthetic <tr>\n // between them: an unmodified rowSpan would reach across the panel while the covered cell\n // below it is still dropped, tearing the column structure apart.\n warnOnce(\n \"spanning-detail-panel\",\n \"spanRows/spanColumns are ignored while renderDetailPanel is set — a detail row lands inside the span a merged cell would reach across.\"\n );\n }\n\n const rowPinningActive = table.options.enableRowPinning === true;\n // A fresh `[]` per render would defeat the memos below; the empty zone is one stable array.\n const topRows = rowPinningActive ? table.getTopRows() : NO_ROWS;\n const bottomRows = rowPinningActive ? table.getBottomRows() : NO_ROWS;\n const centerRows = rowPinningActive ? table.getCenterRows() : table.getRowModel().rows;\n\n // Every zone uses the same synthesis: an expanded pinned row owns a detail item just like a\n // center row, and the sticky offset engine measures both items independently. Memoized because\n // the virtualizer re-renders this component on every scroll range change: rebuilding the\n // display rows there would make each scroll step O(rows) in a table sized for virtualization.\n // The row arrays are a sufficient key even though the synthesis reads `row.getIsExpanded()`:\n // v9's expanded row model returns the pre-expanded array while nothing is expanded and a\n // freshly built one as soon as something is, so every `expanded` transition changes identity.\n const topDisplayRows = useMemo(() => buildDisplayRows(topRows, withDetailPanels), [topRows, withDetailPanels]);\n const centerDisplayRows = useMemo(() => buildDisplayRows(centerRows, withDetailPanels), [centerRows, withDetailPanels]);\n const bottomDisplayRows = useMemo(() => buildDisplayRows(bottomRows, withDetailPanels), [bottomRows, withDetailPanels]);\n const pinnedRowOffsets = usePinnedRowOffsets(topDisplayRows.length, bottomDisplayRows.length);\n\n /* aria-rowindex numbers header rows first (docs/virtualization.md) — none when they are off. */\n const headerRowCount = withColumnHeaders ? table.getHeaderGroups().length : 0;\n\n /**\n * `getItemKey` sits in virtual-core's `getMeasurementOptions` memo **by reference**, and that\n * memo feeds `getMeasurements`. A fresh closure per render therefore invalidates the whole\n * measurement pass, which then walks every item from index 0 — an O(rows) sweep on each of\n * the re-renders the virtualizer itself triggers while scrolling. It stays stable for as long\n * as the display rows do, which is exactly when the measurements are still valid.\n */\n const getItemKey = useCallback(\n (index: number) => centerDisplayRows[index]?.key ?? index,\n [centerDisplayRows]\n );\n const estimateHeight = virtualization?.estimateHeight ?? DEFAULT_ESTIMATED_ROW_HEIGHT;\n const estimateSize = useCallback(() => estimateHeight, [estimateHeight]);\n\n const virtualizer = useVirtualizer({\n count: centerDisplayRows.length,\n enabled: virtualization !== null,\n estimateSize,\n getItemKey,\n getScrollElement: () => viewportRef.current,\n overscan: virtualization?.overscan ?? DEFAULT_OVERSCAN,\n // The upstream React 19 compatibility setting: with it on, a row measured as its ref\n // attaches (a scrollToIndex landing in unmeasured territory) has the virtualizer calling\n // flushSync inside React's commit — React noops it to a batched update and warns, so the\n // sync flush never actually happened on that path anyway.\n useFlushSync: false\n });\n\n const virtualEnabled = virtualization !== null;\n\n useEffect(() => {\n onVirtualizerChange(virtualEnabled ? virtualizer : null);\n\n return () => onVirtualizerChange(null);\n }, [virtualEnabled, virtualizer, onVirtualizerChange]);\n\n const leafColumnCount = table.getVisibleLeafColumns().length;\n // What a full-width cell (skeleton, detail panel, loader) spans — the rendered cols, spacer\n // cols included, under a column window.\n const fullWidthColSpan = renderedColCount(columnWindow, leafColumnCount);\n const totalDisplayRowCount = topDisplayRows.length + centerDisplayRows.length + bottomDisplayRows.length;\n // Presence, never identity: what a row's cells read from the commit handlers is whether the\n // live mode has one at all — that is the whole of their part in `canEditCell`, and the write\n // itself goes through the controllers, whose event callbacks always reach the latest. An\n // application that writes its handler inline (the ordinary way to write one) hands `meta` a new\n // function on every render, and taking its identity here would put a new token on every row and\n // leave nothing memoized at all.\n const canCommitCell = Boolean(ledger?.onEditCommit);\n const canCommitRow = Boolean(ledger?.onRowEditCommit);\n // The handles read this through the table instance, so it must bust the row memo: when a sort\n // arrives, the rows that happen to keep their position would otherwise keep enabled handles.\n const rowOrderable = ledger?.rowOrdering.orderable === true;\n const renderVersion = useMemo(\n () => {\n return {\n // meta.ledger.columns, never options.columns: v9 re-resolves options per state tick,\n // so the options-side identity would bust the row memo on every state change.\n columns: ledger?.columns,\n editTrigger: ledger?.editTrigger,\n editMode: ledger?.editing.mode,\n enableEditing: ledger?.enableEditing,\n canCommitCell,\n canCommitRow,\n rowOrderable\n };\n },\n [ledger?.columns, ledger?.enableEditing, ledger?.editTrigger, ledger?.editing.mode, canCommitCell, canCommitRow, rowOrderable]\n );\n\n if (loading && totalDisplayRowCount === 0) {\n return (\n <MantineTable.Tbody {...getStyles(\"tbody\")}>\n <SkeletonRows\n ariaRowIndexStart={virtualEnabled ? headerRowCount + 1 : undefined}\n columnCount={fullWidthColSpan}\n rowCount={skeletonRowCount}\n />\n </MantineTable.Tbody>\n );\n }\n\n /* Memo-busting signatures: rows re-render when pinning or the visible column set changes. */\n const pinning = table.atoms.columnPinning.get();\n const pinKey = JSON.stringify([pinning.start, pinning.end]);\n const columnsKey = JSON.stringify([\n table.getVisibleLeafColumns().map(column => column.id),\n columnWindow === null ? null : [columnWindow.start, columnWindow.end]\n ]);\n const editingCell = ledger?.editing.cell ?? null;\n const editingRowId = ledger?.editing.mode === \"row\" ? ledger.editing.row.id : null;\n const activeRowId = ledger?.activeRow.enabled ? ledger.activeRow.id : null;\n\n interface DisplayRowRenderOptions {\n displayIndex: number;\n pinnedPosition?: \"top\" | \"bottom\";\n pinnedOffset?: number;\n virtualIndex?: number;\n measureRef?: (element: Element | null) => void;\n }\n\n const renderDisplayRow = (\n displayRow: DisplayRow<any>,\n options: DisplayRowRenderOptions\n ): ReactNode => {\n const zoneStart\n = options.pinnedPosition === \"top\"\n ? headerRowCount\n : options.pinnedPosition === \"bottom\"\n ? headerRowCount + topDisplayRows.length + centerDisplayRows.length\n : headerRowCount + topDisplayRows.length;\n const ariaRowIndex = virtualEnabled ? zoneStart + options.displayIndex + 1 : undefined;\n\n if (displayRow.kind === \"detail\") {\n return (\n <DetailRow\n key={displayRow.key}\n ariaRowIndex={ariaRowIndex}\n colSpan={fullWidthColSpan}\n dragging={reorderSourceId === displayRow.row.id}\n measureRef={options.measureRef}\n pinnedOffset={options.pinnedOffset}\n pinnedPosition={options.pinnedPosition}\n renderDetailPanel={ledger?.renderDetailPanel}\n row={displayRow.row}\n virtualIndex={options.virtualIndex}\n // \"After\" an expanded row means after the pair — the panel travels with its row, so\n // the panel's bottom edge is where that indicator draws (docs/rows.md#row-ordering).\n dropSide={reorderTarget?.rowId === displayRow.row.id && reorderTarget.side === \"after\"\n ? \"after\"\n : null}\n />\n );\n }\n\n const { row, dataIndex } = displayRow;\n const dropSide\n = reorderTarget?.rowId === row.id\n && !(reorderTarget.side === \"after\" && withDetailPanels && row.getIsExpanded())\n ? reorderTarget.side\n : null;\n const spanKey = spanningActive\n ? row.getVisibleCells()\n .map(cell => cell.getIsCovered() ? \"x\" : `${cell.getRowSpan()}:${cell.getColSpan()}`)\n .join(\" \")\n : \"\";\n\n return (\n <DataRow\n key={displayRow.key}\n active={activeRowId === row.id}\n ariaRowIndex={ariaRowIndex}\n columnsKey={columnsKey}\n columnWindow={columnWindow}\n dataIndex={options.pinnedPosition ? -1 : dataIndex}\n depth={row.depth}\n dragging={reorderSourceId === row.id}\n dropSide={dropSide}\n editingRow={editingRowId === row.id && (ledger?.editing.row.active(row.id) ?? false)}\n expanded={row.getIsExpanded()}\n measureRef={options.measureRef}\n pinKey={pinKey}\n pinnedOffset={options.pinnedOffset}\n pinnedPosition={options.pinnedPosition}\n renderVersion={renderVersion}\n row={row}\n selected={row.getIsSelected()}\n spanKey={spanKey}\n spanning={spanningActive}\n virtualIndex={options.virtualIndex}\n editingColumnId={editingCell?.rowId === row.id && (ledger?.editing.active(row.id, editingCell.columnId) ?? false)\n ? editingCell.columnId\n : null}\n />\n );\n };\n\n let center: ReactNode;\n\n if (virtualEnabled) {\n const items = virtualizer.getVirtualItems();\n const firstItem = items[0];\n const lastItem = items.at(-1);\n const topSpace = firstItem ? firstItem.start : 0;\n const bottomSpace = lastItem ? virtualizer.getTotalSize() - lastItem.end : 0;\n\n center = (\n <>\n {topSpace > 0 && <tr aria-hidden data-ledger-spacer style={{ height: topSpace }} />}\n\n {items.map(item => {\n const displayRow = centerDisplayRows[item.index];\n\n return displayRow\n ? renderDisplayRow(displayRow, {\n displayIndex: item.index,\n virtualIndex: item.index,\n measureRef: virtualizer.measureElement\n })\n : null;\n })}\n\n {bottomSpace > 0 && <tr aria-hidden data-ledger-spacer style={{ height: bottomSpace }} />}\n </>\n );\n } else {\n center = centerDisplayRows.map((displayRow, displayIndex) => renderDisplayRow(displayRow, { displayIndex }));\n }\n\n return (\n <MantineTable.Tbody {...getStyles(\"tbody\")}>\n {topDisplayRows.map((displayRow, displayIndex) => renderDisplayRow(displayRow, {\n displayIndex,\n measureRef: pinnedRowOffsets.registerTopRow(displayIndex),\n pinnedOffset: pinnedRowOffsets.offsets.top[displayIndex],\n pinnedPosition: \"top\"\n }))}\n\n {center}\n\n {bottomDisplayRows.map((displayRow, displayIndex) => renderDisplayRow(displayRow, {\n displayIndex,\n measureRef: pinnedRowOffsets.registerBottomRow(displayIndex),\n pinnedOffset: pinnedRowOffsets.offsets.bottom[displayIndex],\n pinnedPosition: \"bottom\"\n }))}\n\n {loadMoreError\n ? (\n <LoadMoreErrorRow\n ariaRowIndex={virtualEnabled ? headerRowCount + totalDisplayRowCount + 1 : undefined}\n colSpan={fullWidthColSpan}\n message={loadMoreError}\n onRetry={onLoadMoreRetry}\n />\n )\n : loadingMore && (\n <LoaderRow\n ariaRowIndex={virtualEnabled ? headerRowCount + totalDisplayRowCount + 1 : undefined}\n colSpan={fullWidthColSpan}\n />\n )}\n </MantineTable.Tbody>\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Header, TableInstance } from \"./types\";\nimport type { ColumnWindowView } from \"./use-column-window\";\n\n/**\n * Column footers (totals row). Rendered only when at least one column — leaf or group —\n * declares a `footer`; pinned columns keep their sticky offsets so the totals track their\n * columns.\n */\nimport { Table as MantineTable } from \"@mantine/core\";\nimport { flexRender } from \"@tanstack/react-table\";\n\nimport { useDataTableContext } from \"./context\";\nimport { mergeElementProps, resolveElementProps } from \"./element-props\";\nimport { pinnedCellStyle, pinnedEdge } from \"./pinning\";\nimport { windowHeaderCells } from \"./use-column-window\";\n\n/**\n * The footer rows that actually render. `getFooterGroups()` mirrors *every* header level, so a\n * grouped header whose totals live on the leaves yields a trailing group row holding nothing —\n * dead space that still draws row and column borders. A level earns its row by carrying a\n * `footer` of its own, which also lets a group column declare one (previously the leaf-only\n * test dropped the whole region in that case).\n */\nexport function visibleFooterGroups<TData extends RowData>(table: TableInstance<TData>) {\n return table.getFooterGroups().filter(footerGroup => footerGroup.headers.some(\n footer => !footer.isPlaceholder && footer.column.columnDef.footer !== undefined\n ));\n}\n\nexport function tableHasFooter<TData extends RowData>(table: TableInstance<TData>): boolean {\n return visibleFooterGroups(table).length > 0;\n}\n\nexport function TableFooter<TData extends RowData>({\n table,\n ariaRowIndexStart,\n columnWindow\n}: {\n table: TableInstance<TData>;\n ariaRowIndexStart?: number;\n columnWindow: ColumnWindowView | null;\n}) {\n const { getStyles, footerRowProps } = useDataTableContext();\n\n const renderCell = (\n footer: Header<TData, unknown>,\n colSpan: number | undefined,\n ariaColIndex: number | undefined\n ) => (\n <MantineTable.Th\n key={footer.id}\n {...mergeElementProps(resolveElementProps(footer.column.columnDef.meta?.footerCellProps, footer), {\n \"aria-colindex\": ariaColIndex,\n colSpan: colSpan ?? footer.colSpan,\n \"data-align\": footer.column.columnDef.meta?.align,\n // Autosize measures the footer like every other rendered cell, and finds it the\n // same way (docs/sizing.md).\n \"data-ledger-column-id\": footer.column.id,\n \"data-pinned\": footer.column.getIsPinned() || undefined,\n \"data-pinned-edge\": pinnedEdge(footer.column),\n // Totals are data, not headers — under the ARIA table they are plain cells.\n role: \"cell\",\n ...getStyles(\"footerCell\", { style: pinnedCellStyle(footer.column) })\n })}\n >\n {footer.isPlaceholder\n ? null\n : flexRender(footer.column.columnDef.footer, footer.getContext())}\n </MantineTable.Th>\n );\n\n return (\n <MantineTable.Tfoot {...getStyles(\"tfoot\")}>\n {visibleFooterGroups(table).map((footerGroup, groupIndex) => (\n <MantineTable.Tr\n key={footerGroup.id}\n {...mergeElementProps(resolveElementProps(footerRowProps, footerGroup), {\n \"aria-rowindex\": ariaRowIndexStart === undefined ? undefined : ariaRowIndexStart + groupIndex,\n role: \"row\",\n ...getStyles(\"footerRow\")\n })}\n >\n {/* Footer groups mirror header groups, so the same clamp rule tiles them\n (docs/virtualization.md#column-virtualization). */}\n {columnWindow === null\n ? footerGroup.headers.map(footer => renderCell(footer, undefined, undefined))\n : windowHeaderCells(footerGroup.headers, columnWindow).map(cell => cell.kind === \"spacer\"\n ? <th key={`ledger:spacer-${cell.edge}`} aria-hidden data-ledger-spacer />\n : renderCell(cell.header, cell.colSpan, cell.ariaColIndex))}\n </MantineTable.Tr>\n ))}\n </MantineTable.Tfoot>\n );\n}\n","import type { ColumnSizingState } from \"@tanstack/react-table\";\n\nimport type { ResizerSpec } from \"./use-column-resize\";\n\n/**\n * Fit a column to its rendered content (the resizer's double-click). Measures the header cell,\n * every RENDERED body cell of the column — under virtualization that is the current window, which\n * is the industry contract for autosize (unrendered rows have no boxes to measure) — and the\n * footer cell, which is rendered content the column has to hold like any other. Writes the result\n * through `columnSizing`, clamped like an interactive resize.\n *\n * The column, its constraints and whether it carries a filter all arrive from the render that put\n * the handle on screen, for the reason `use-column-resize.ts` gives.\n *\n * Measurement forces `white-space: nowrap` on every cell first and reads afterwards, so the\n * whole pass costs one reflow. Truncating cells clip their own overflow (the td never grows),\n * so the content width is read from the `[data-truncate]` span instead of the cell box.\n */\n\n/**\n * Breathing room over the tightest fit — content flush against the column edge reads clipped.\n */\nconst AUTOSIZE_SLACK_PX = 8;\n\n/**\n * Reserved for the hover-revealed header actions overlay (the filter button) so autosize does\n * not park the drag line underneath it.\n */\nconst HEADER_ACTIONS_ALLOWANCE_PX = 28;\n\n/**\n * Computed lengths always resolve to `Npx`; strip the unit before coercing.\n */\nfunction asPx(value: string): number {\n return Number(value.replace(\"px\", \"\")) || 0;\n}\n\nfunction horizontalPadding(element: HTMLElement): number {\n const style = getComputedStyle(element);\n\n return asPx(style.paddingInlineStart) + asPx(style.paddingInlineEnd);\n}\n\nfunction bodyCellWidth(cell: HTMLElement): number {\n const truncated = cell.querySelector<HTMLElement>(\":scope [data-truncate]\");\n\n return truncated\n ? truncated.scrollWidth + horizontalPadding(cell)\n : cell.scrollWidth;\n}\n\nfunction headerCellWidth(th: HTMLElement, hasFilter: boolean): number {\n // The label's truncate span clips its own overflow, so the th box never reports the full\n // text — read the span, then re-add the chrome around it.\n const labelText = th.querySelector<HTMLElement>(\":scope .ledger-header-label [data-truncate]\");\n\n if (!labelText) {\n return th.scrollWidth;\n }\n\n const indicator = th.querySelector<HTMLElement>(\":scope .ledger-sort-indicator\");\n const indicatorWidth = indicator ? indicator.offsetWidth + 6 : 0;\n\n return labelText.scrollWidth\n + indicatorWidth\n + horizontalPadding(th)\n + (hasFilter ? HEADER_ACTIONS_ALLOWANCE_PX : 0);\n}\n\nexport interface AutosizeSpec extends Pick<ResizerSpec, \"columnId\" | \"minSize\" | \"maxSize\"> {\n /**\n * The column carries a filter control, so the header reserves room for the hover overlay.\n */\n hasFilter: boolean;\n}\n\nexport function autosizeColumn(\n setColumnSizing: (updater: (previous: ColumnSizingState) => ColumnSizingState) => void,\n {\n columnId,\n minSize,\n maxSize,\n hasFilter\n }: AutosizeSpec,\n main: HTMLElement\n): void {\n const selector = `[data-ledger-column-id=\"${CSS.escape(columnId)}\"]`;\n const headerCell = main.querySelector<HTMLElement>(`:scope .ledger-header ${selector}`);\n const bodyCells = [...main.querySelectorAll<HTMLElement>(`:scope .ledger-tbody ${selector}`)];\n // A footer cell that spans columns says nothing about the width of any one of them.\n const footerCells = [...main.querySelectorAll<HTMLElement>(`:scope .ledger-footer ${selector}`)]\n .filter(cell => (cell as HTMLTableCellElement).colSpan <= 1);\n const contentCells = [...bodyCells, ...footerCells];\n const cells = headerCell ? [headerCell, ...contentCells] : contentCells;\n\n if (cells.length === 0) {\n return;\n }\n\n // Write phase, then read phase — the forced nowrap costs one reflow for the whole column.\n const previousWhitespace = cells.map(cell => cell.style.whiteSpace);\n\n for (const cell of cells) {\n cell.style.whiteSpace = \"nowrap\";\n }\n\n let content = headerCell ? headerCellWidth(headerCell, hasFilter) : 0;\n\n for (const cell of contentCells) {\n content = Math.max(content, bodyCellWidth(cell));\n }\n\n for (const [index, cell] of cells.entries()) {\n cell.style.whiteSpace = previousWhitespace[index] ?? \"\";\n }\n\n const next = Math.min(Math.max(Math.round(content + AUTOSIZE_SLACK_PX), minSize), maxSize);\n\n setColumnSizing(previous => previous[columnId] === next ? previous : { ...previous, [columnId]: next });\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { DateRangeFilterValue } from \"./filter-fns\";\nimport type { Column, DataTableFilterConfig } from \"./types\";\n\n/**\n * Header filter UI: a funnel trigger (filled while active) opening a popover with the control\n * `meta.filter` declares. Client mode derives `select`/`multi-select` options from faceted\n * values when none are given; server mode requires explicit options and degrades to the text\n * variant (with a dev warning) when they are missing. Date bounds render an inline\n * `@mantine/dates` range calendar (no nested popover to misread as an outside click);\n * its values are the same `YYYY-MM-DD` strings the filter fn compares.\n *\n * Clearing lives on each control, not on a shared popover row: `select`/`multi-select` use\n * their native clear buttons, `text` clears from its right section, `range` from the end of\n * its input row, and the calendar from a caption under it. Only a custom render-prop filter —\n * a black box that may ship no clear of its own — keeps the popover-level fallback.\n */\nimport { ActionIcon, Button, CloseButton, Group, MultiSelect, NumberInput, Popover, Select, Stack, TextInput } from \"@mantine/core\";\nimport { DatePicker } from \"@mantine/dates\";\nimport { useDebouncedCallback } from \"@mantine/hooks\";\nimport { useEffect, useState } from \"react\";\n\nimport { columnHeaderText } from \"./build-columns\";\nimport { useDataTableContext } from \"./context\";\nimport { warnOnce } from \"./env\";\n\nconst FACETED_OPTIONS_CAP = 100;\n\nexport interface FilterPopoverProps<TData extends RowData> {\n column: Column<TData, unknown>;\n}\n\nexport function FilterPopover<TData extends RowData>({ column }: FilterPopoverProps<TData>) {\n const {\n labels,\n icons,\n getStyles,\n filterMode\n } = useDataTableContext();\n const filter = column.columnDef.meta?.filter;\n\n if (!filter || !column.getCanFilter()) {\n return null;\n }\n\n const active = column.getFilterValue() !== undefined;\n // Every filter control in a header is the same control; only the column tells them apart.\n const name = labels.filterColumn(columnHeaderText(column));\n\n return (\n <Popover trapFocus position=\"bottom-start\" width={240}>\n <Popover.Target>\n <ActionIcon\n aria-label={name}\n data-active={active || undefined}\n size=\"sm\"\n variant={active ? \"light\" : \"subtle\"}\n onClick={event => event.stopPropagation()}\n >\n <icons.filterColumn />\n </ActionIcon>\n </Popover.Target>\n\n <Popover.Dropdown {...getStyles(\"filterPopover\")} onClick={event => event.stopPropagation()}>\n <Stack gap=\"xs\">\n {typeof filter === \"function\"\n ? (\n <>\n {filter(column)}\n\n {active && (\n <Group justify=\"flex-end\">\n <CloseButton\n aria-label={labels.clearFilter}\n size=\"sm\"\n onClick={() => column.setFilterValue(undefined)}\n />\n </Group>\n )}\n </>\n )\n : (\n <VariantFilterControl\n column={column}\n config={typeof filter === \"string\" ? { variant: filter } : filter}\n filterMode={filterMode}\n name={name}\n />\n )}\n </Stack>\n </Popover.Dropdown>\n </Popover>\n );\n}\n\ninterface VariantFilterControlProps<TData extends RowData> {\n column: Column<TData, unknown>;\n config: DataTableFilterConfig;\n filterMode: \"client\" | \"server\";\n /**\n * Accessible name, shared with the funnel trigger — a placeholder is not a label.\n */\n name: string;\n}\n\nfunction VariantFilterControl<TData extends RowData>({\n column,\n config,\n filterMode,\n name\n}: VariantFilterControlProps<TData>) {\n const { labels } = useDataTableContext();\n\n switch (config.variant) {\n case \"text\": {\n return <TextFilter column={column} name={name} placeholder={config.placeholder ?? labels.filterPlaceholder} />;\n }\n\n case \"select\": {\n return <SelectFilter column={column} config={config} filterMode={filterMode} name={name} />;\n }\n\n case \"multi-select\": {\n return <SelectFilter column={column} config={config} filterMode={filterMode} name={name} />;\n }\n\n case \"range\": {\n return <RangeFilter column={column} name={name} />;\n }\n\n case \"date-range\": {\n return <DateRangeFilter column={column} name={name} />;\n }\n }\n}\n\n/**\n * The select family, whose two variants differ only in cardinality — one control, one option\n * source, one degradation path.\n */\nfunction SelectFilter<TData extends RowData>({\n column,\n config,\n filterMode,\n name\n}: {\n column: Column<TData, unknown>;\n config: Extract<DataTableFilterConfig, { variant: \"select\" | \"multi-select\" }>;\n filterMode: \"client\" | \"server\";\n name: string;\n}) {\n const { labels } = useDataTableContext();\n const placeholder = config.placeholder ?? labels.filterPlaceholder;\n // Declared options win; client mode derives them from the faceted values, which server mode has\n // no rows to compute. An explicitly empty list is a declaration like any other.\n const options = config.options ?? (filterMode === \"server\" ? undefined : facetedOptions(column));\n\n if (!options) {\n warnOnce(\n `filter-options-${column.id}`,\n `Column \"${column.id}\" uses a ${config.variant} filter in server mode without options — faceted values need client-side rows. Falling back to a text filter.`\n );\n\n return <TextFilter column={column} name={name} placeholder={placeholder} />;\n }\n\n if (config.variant === \"multi-select\") {\n return (\n <MultiSelect\n clearable\n searchable\n aria-label={name}\n clearButtonProps={{ \"aria-label\": labels.clearFilter }}\n comboboxProps={{ withinPortal: false }}\n data={options}\n placeholder={placeholder}\n value={(column.getFilterValue() as string[] | undefined) ?? []}\n onChange={value => column.setFilterValue(value.length > 0 ? value : undefined)}\n />\n );\n }\n\n return (\n <Select\n clearable\n searchable\n aria-label={name}\n clearButtonProps={{ \"aria-label\": labels.clearFilter }}\n // Inside the filter popover the combobox must not portal out: a portal dropdown\n // reads as an outside click and closes the popover mid-interaction.\n comboboxProps={{ withinPortal: false }}\n data={options}\n placeholder={placeholder}\n value={(column.getFilterValue() as string | undefined) ?? null}\n onChange={value => column.setFilterValue(value ?? undefined)}\n />\n );\n}\n\nfunction TextFilter<TData extends RowData>({\n column,\n name,\n placeholder\n}: { column: Column<TData, unknown>; name: string; placeholder: string }) {\n // Straight from the context, never through a table instance: this control redraws from its\n // own state, in renders the table root has no part in, and the instance it would reach for\n // then is whatever pass wrote it last (context.ts).\n const { labels, subscribeColumnFilters } = useDataTableContext();\n // Only a string is this control's value. A server-mode `select`/`multi-select` that degrades\n // here (no options to build) inherits whatever filter was already set, and a multi-select's is\n // an array — which a TextInput would render as its comma-joined form and then write back as\n // one string.\n const raw = column.getFilterValue();\n const filterValue = typeof raw === \"string\" ? raw : \"\";\n const [value, setValue] = useState(filterValue);\n const apply = useDebouncedCallback(\n (next: string) => column.setFilterValue(next === \"\" ? undefined : next),\n { delay: 200, flushOnUnmount: true }\n );\n\n useEffect(() => subscribeColumnFilters?.(filters => {\n const next = filters.find(filter => filter.id === column.id)?.value;\n\n apply.cancel();\n setValue(typeof next === \"string\" ? next : \"\");\n }), [apply, column.id, subscribeColumnFilters]);\n\n useEffect(() => {\n apply.cancel();\n setValue(filterValue);\n }, [apply, filterValue]);\n\n return (\n <TextInput\n aria-label={name}\n placeholder={placeholder}\n rightSectionPointerEvents=\"all\"\n value={value}\n rightSection={value !== \"\" && (\n <CloseButton\n aria-label={labels.clearFilter}\n size=\"sm\"\n onClick={() => {\n apply.cancel();\n setValue(\"\");\n column.setFilterValue(undefined);\n }}\n />\n )}\n onChange={event => {\n setValue(event.currentTarget.value);\n apply(event.currentTarget.value);\n }}\n />\n );\n}\n\nfunction RangeFilter<TData extends RowData>({ column, name }: { column: Column<TData, unknown>; name: string }) {\n const { labels } = useDataTableContext();\n const [min, max] = (column.getFilterValue() as [number | undefined, number | undefined] | undefined) ?? [\n undefined,\n undefined\n ];\n const [facetMin, facetMax] = column.getFacetedMinMaxValues() ?? [undefined, undefined];\n\n const setBound = (index: 0 | 1) => (raw: number | string) => {\n const bound = typeof raw === \"number\" ? raw : undefined;\n const next: [number | undefined, number | undefined] = index === 0 ? [bound, max] : [min, bound];\n column.setFilterValue(next[0] === undefined && next[1] === undefined ? undefined : next);\n };\n\n const active = min !== undefined || max !== undefined;\n\n return (\n // The pair is one control: the group carries the column's name, the inputs their bound.\n <Group aria-label={name} gap=\"xs\" role=\"group\" wrap=\"nowrap\">\n <NumberInput\n aria-label={labels.filterRangeMin}\n flex={1}\n placeholder={facetMin === undefined ? labels.filterRangeMin : String(facetMin)}\n value={min ?? \"\"}\n onChange={setBound(0)}\n />\n\n <NumberInput\n aria-label={labels.filterRangeMax}\n flex={1}\n placeholder={facetMax === undefined ? labels.filterRangeMax : String(facetMax)}\n value={max ?? \"\"}\n onChange={setBound(1)}\n />\n\n {/* Space is reserved while inactive so the inputs keep their width as the button appears. */}\n <CloseButton\n aria-label={labels.clearFilter}\n size=\"sm\"\n style={{ visibility: active ? undefined : \"hidden\" }}\n onClick={() => column.setFilterValue(undefined)}\n />\n </Group>\n );\n}\n\nfunction DateRangeFilter<TData extends RowData>({ column, name }: { column: Column<TData, unknown>; name: string }) {\n const { labels } = useDataTableContext();\n const filterValue = column.getFilterValue() as DateRangeFilterValue | undefined;\n const value = filterValue ?? [null, null];\n\n return (\n <>\n <DatePicker\n allowSingleDateInRange\n highlightToday\n aria-label={name}\n size=\"xs\"\n type=\"range\"\n value={value}\n onChange={next => column.setFilterValue(!next[0] && !next[1] ? undefined : next)}\n />\n\n {/* The calendar has no input row to host a clear button; a quiet caption under it is the\n date-picker-panel convention instead. */}\n {filterValue !== undefined && (\n <Group justify=\"flex-end\">\n <Button\n color=\"gray\"\n size=\"compact-xs\"\n variant=\"subtle\"\n onClick={() => column.setFilterValue(undefined)}\n >\n {labels.clearFilter}\n </Button>\n </Group>\n )}\n </>\n );\n}\n\nfunction facetedOptions<TData extends RowData>(column: Column<TData, unknown>): string[] {\n const values: string[] = [];\n\n for (const key of column.getFacetedUniqueValues().keys()) {\n if (key === null || key === undefined || key === \"\") {\n continue;\n }\n\n if (Array.isArray(key)) {\n for (const entry of key) {\n if (entry !== null && entry !== undefined) {\n values.push(String(entry));\n }\n }\n } else {\n values.push(String(key));\n }\n }\n\n return [...new Set(values)].toSorted().slice(0, FACETED_OPTIONS_CAP);\n}\n","/**\n * Pointer-based header drag reordering — no drag-and-drop dependency. A press becomes a drag\n * after a 5px threshold, so the sortable header label keeps its click; a completed drag\n * suppresses the click that follows pointerup. Escape and pointercancel abandon the drag, and\n * a mid-drag unmount releases the window listeners. Reordering is limited to single-row\n * headers: with column groups, sibling order inside a group is ambiguous.\n */\nimport type { RowData } from \"@tanstack/react-table\";\nimport type { PointerEvent as ReactPointerEvent } from \"react\";\n\nimport type { ColumnDropTarget } from \"./column-order\";\nimport type { TableInstance } from \"./types\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { isInternalColumn } from \"./build-columns\";\nimport { getColumnZone, reorderColumnWithinZone } from \"./column-order\";\nimport { warnOnce } from \"./env\";\n\nconst DRAG_THRESHOLD_PX = 5;\n\nexport interface ColumnDragState {\n draggedId: string | null;\n targetId: string | null;\n side: \"before\" | \"after\" | null;\n}\n\nconst IDLE: ColumnDragState = {\n draggedId: null,\n targetId: null,\n side: null\n};\n\nexport interface ColumnReorder {\n drag: ColumnDragState;\n getHeaderProps: (columnId: string) => { onPointerDown?: (event: ReactPointerEvent<HTMLElement>) => void };\n /**\n * True exactly once after a completed drag — the header label uses it to swallow the click.\n */\n consumeClickSuppression: () => boolean;\n}\n\ninterface DragSession {\n columnId: string;\n startX: number;\n started: boolean;\n target: ColumnDropTarget | null;\n cleanup: () => void;\n}\n\nexport function useColumnReorder<TData extends RowData>(table: TableInstance<TData>): ColumnReorder {\n const [drag, setDrag] = useState<ColumnDragState>(IDLE);\n const session = useRef<DragSession | null>(null);\n const suppressClick = useRef(false);\n\n // The listeners live on window, so a mid-drag unmount must release them here.\n useEffect(() => () => {\n session.current?.cleanup();\n session.current = null;\n }, []);\n\n const enabledOption = table.options.meta?.ledger?.enableColumnOrdering === true;\n const hasGroupedHeaders = table.getHeaderGroups().length > 1;\n\n if (enabledOption && hasGroupedHeaders) {\n warnOnce(\n \"reorder-grouped-headers\",\n \"enableColumnOrdering is ignored for tables with header groups — sibling order inside a group is ambiguous.\"\n );\n }\n\n const enabled = enabledOption && !hasGroupedHeaders;\n\n const commitReorder = (draggedId: string, target: ColumnDropTarget) => {\n reorderColumnWithinZone(table, draggedId, target);\n };\n\n const getHeaderProps: ColumnReorder[\"getHeaderProps\"] = columnId => {\n if (!enabled || isInternalColumn(columnId)) {\n return {};\n }\n\n return {\n onPointerDown: event => {\n if (\n event.button !== 0\n || session.current\n || (event.target as HTMLElement).closest(\"[data-ledger-no-drag]\")\n ) {\n return;\n }\n\n const onPointerMove = (move: globalThis.PointerEvent) => {\n const { current } = session;\n\n if (!current) {\n return;\n }\n\n if (!current.started) {\n if (Math.abs(move.clientX - current.startX) < DRAG_THRESHOLD_PX) {\n return;\n }\n\n current.started = true;\n }\n\n const headerCell = document\n .elementFromPoint(move.clientX, move.clientY)\n ?.closest<HTMLElement>(\"[data-ledger-column-id]\");\n const targetId = headerCell?.dataset.ledgerColumnId;\n\n let target: DragSession[\"target\"] = null;\n\n if (\n headerCell\n && targetId\n && targetId !== current.columnId\n && !isInternalColumn(targetId)\n && getColumnZone(table, targetId) === getColumnZone(table, current.columnId)\n ) {\n const rect = headerCell.getBoundingClientRect();\n // `before`/`after` are logical, like the drop indicator that renders them: in RTL a\n // cell's leading half is its RIGHT half, so the physical test has to be mirrored\n // (the same reasoning the resize drag applies to its delta).\n const rtl = getComputedStyle(headerCell).direction === \"rtl\";\n const inLeftHalf = move.clientX < rect.left + rect.width / 2;\n\n target = { id: targetId, side: inLeftHalf === rtl ? \"after\" : \"before\" };\n }\n\n current.target = target;\n setDrag({\n draggedId: current.columnId,\n targetId: target?.id ?? null,\n side: target?.side ?? null\n });\n };\n\n const endSession = (commit: boolean) => {\n const { current } = session;\n\n if (!current) {\n return;\n }\n\n current.cleanup();\n session.current = null;\n\n if (current.started) {\n suppressClick.current = true;\n\n if (commit && current.target) {\n commitReorder(current.columnId, current.target);\n }\n }\n\n setDrag(IDLE);\n };\n\n const onPointerUp = () => endSession(true);\n\n const onPointerCancel = () => {\n const { current } = session;\n\n // The browser aborted the pointer stream and no click will follow, so ending the\n // session here must not arm the click suppression.\n if (current) {\n current.started = false;\n }\n\n endSession(false);\n };\n\n const onKeyDown = (key: globalThis.KeyboardEvent) => {\n if (key.key === \"Escape\") {\n endSession(false);\n }\n };\n\n session.current = {\n columnId,\n startX: event.clientX,\n started: false,\n target: null,\n cleanup: () => {\n removeEventListener(\"pointermove\", onPointerMove);\n removeEventListener(\"pointerup\", onPointerUp);\n removeEventListener(\"pointercancel\", onPointerCancel);\n removeEventListener(\"keydown\", onKeyDown);\n }\n };\n\n addEventListener(\"pointermove\", onPointerMove);\n addEventListener(\"pointerup\", onPointerUp);\n addEventListener(\"pointercancel\", onPointerCancel);\n addEventListener(\"keydown\", onKeyDown);\n }\n };\n };\n\n const consumeClickSuppression = () => {\n if (!suppressClick.current) {\n return false;\n }\n\n suppressClick.current = false;\n\n return true;\n };\n\n return {\n drag,\n getHeaderProps,\n consumeClickSuppression\n };\n}\n","import type { ColumnSizingState } from \"@tanstack/react-table\";\nimport type { PointerEvent as ReactPointerEvent } from \"react\";\n\n/**\n * Pointer-based column resizing, exact by construction: the drag starts from the width the\n * engine actually rendered (docs/sizing.md), so a grow column's first drag is 1:1 instead of\n * jumping to a default. Live updates write `columnSizing` (the CSS-variable pipeline keeps this\n * cheap); Escape and pointercancel restore the width the drag started from; direction follows\n * the computed `direction` of the handle, so RTL drags resolve correctly. A mid-drag unmount\n * releases the window listeners without touching table state.\n *\n * Nothing here reaches for the table at event time. Everything a drag decides with — the column,\n * the width on screen, the constraints, the entry to restore — arrives as a `ResizerSpec` from the\n * render that put the handle on screen, because the shared TanStack core carries whatever render\n * pass ran last, a discarded one included (docs/architecture.md).\n */\nimport { useEffect, useRef, useState } from \"react\";\n\nexport interface ResizerSpec {\n columnId: string;\n /**\n * The engine-resolved width this render drew — the edge the user is grabbing.\n */\n width: number;\n minSize: number;\n maxSize: number;\n /**\n * This render's `columnSizing` entry. Escape restores it; absent means a grow column, which\n * Escape returns to having no entry at all.\n */\n sizingEntry: number | undefined;\n}\n\nexport interface ColumnResize {\n resizingId: string | null;\n getResizerProps: (spec: ResizerSpec) => { onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void };\n}\n\ninterface ResizeSession {\n startX: number;\n rtl: boolean;\n /**\n * Whether the handle for this column is still on screen, in *this* table. Asked of the table's\n * own root rather than of a captured handle — that node is replaced whenever the header\n * re-renders, which a live drag does on every move — and scoped to that root rather than to the\n * document, because two tables on a page routinely share a column id and a `name` handle in the\n * other one says nothing about this drag. It is the only signal a window-level pointer stream\n * gets that a real render has taken its column away.\n */\n onScreen: () => boolean;\n cleanup: () => void;\n}\n\nexport function useColumnResize(\n setColumnSizing: (updater: (previous: ColumnSizingState) => ColumnSizingState) => void\n): ColumnResize {\n const [resizingId, setResizingId] = useState<string | null>(null);\n const session = useRef<ResizeSession | null>(null);\n\n // The listeners live on window, so a mid-drag unmount must release them here.\n useEffect(() => () => {\n session.current?.cleanup();\n session.current = null;\n }, []);\n\n const getResizerProps: ColumnResize[\"getResizerProps\"] = ({\n columnId,\n width,\n minSize,\n maxSize,\n sizingEntry\n }) => {\n return {\n onPointerDown: event => {\n if (event.button !== 0 || session.current) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n // Captured now: React clears `currentTarget` once the dispatch returns, and the handlers\n // below outlive it.\n const handle = event.currentTarget;\n const rtl = getComputedStyle(handle).direction === \"rtl\";\n // The table this handle belongs to. `.ledger-main` is structural — it is there for as long\n // as the table is — so it survives the header re-rendering under the drag, while the\n // handle itself does not.\n const root = handle.closest(\".ledger-main\");\n const handleSelector = `.ledger-header [data-ledger-column-id=\"${CSS.escape(columnId)}\"] [data-ledger-resizer]`;\n\n const endSession = (restore: boolean) => {\n const { current } = session;\n\n if (!current) {\n return;\n }\n\n current.cleanup();\n session.current = null;\n setResizingId(null);\n\n if (restore) {\n setColumnSizing(previous => {\n const { [columnId]: _dropped, ...rest } = previous;\n\n return sizingEntry === undefined ? rest : { ...rest, [columnId]: sizingEntry };\n });\n }\n };\n\n const onPointerMove = (move: globalThis.PointerEvent) => {\n const { current } = session;\n\n if (!current) {\n return;\n }\n\n // The column really left the screen mid-drag. There is nothing under the pointer to\n // resize any more, and writing a width for a column the table no longer has is worse\n // than stopping — restoring would be too, since the entry it would restore is for a\n // column that is gone.\n if (!current.onScreen()) {\n endSession(false);\n\n return;\n }\n\n const delta = (move.clientX - current.startX) * (current.rtl ? -1 : 1);\n const next = Math.min(Math.max(Math.round(width + delta), minSize), maxSize);\n\n setColumnSizing(previous => previous[columnId] === next ? previous : { ...previous, [columnId]: next });\n };\n\n const onPointerUp = () => endSession(false);\n\n // The browser aborted the pointer stream (touch pan takeover, OS gesture) — no\n // pointerup will follow, so treat it like Escape and restore.\n const onPointerCancel = () => endSession(true);\n\n const onKeyDown = (key: globalThis.KeyboardEvent) => {\n if (key.key === \"Escape\") {\n endSession(true);\n }\n };\n\n session.current = {\n startX: event.clientX,\n rtl,\n onScreen: () => root !== null && root.isConnected && root.querySelector(handleSelector) !== null,\n cleanup: () => {\n removeEventListener(\"pointermove\", onPointerMove);\n removeEventListener(\"pointerup\", onPointerUp);\n removeEventListener(\"pointercancel\", onPointerCancel);\n removeEventListener(\"keydown\", onKeyDown);\n }\n };\n setResizingId(columnId);\n\n addEventListener(\"pointermove\", onPointerMove);\n addEventListener(\"pointerup\", onPointerUp);\n addEventListener(\"pointercancel\", onPointerCancel);\n addEventListener(\"keydown\", onKeyDown);\n }\n };\n };\n\n return {\n resizingId,\n getResizerProps\n };\n}\n","import type { ColumnSizingState, RowData } from \"@tanstack/react-table\";\nimport type { MouseEvent } from \"react\";\n\nimport type { SortToggleSpec } from \"./toggle-fns\";\nimport type { Header, TableInstance } from \"./types\";\nimport type { ResizerSpec } from \"./use-column-resize\";\nimport type { ColumnWindowView } from \"./use-column-window\";\n\n/**\n * The header: sortable labels (full-area button, shift for multi-sort, order badges), the\n * hover-revealed filter popover, the resize handle on the trailing edge, and drag-reorder\n * plumbing. Every state is a data-attribute; every class is a Styles API selector. Column\n * layout — order, visibility, pinning, width, grouping — belongs to `DataTable.ColumnsPanel`,\n * not to the header (docs/columns.md).\n */\nimport { Table as MantineTable, Tooltip } from \"@mantine/core\";\nimport { flexRender } from \"@tanstack/react-table\";\n\nimport { autosizeColumn } from \"./autosize-column\";\nimport { columnEnableResizing, isInternalColumn } from \"./build-columns\";\nimport { useDataTableContext } from \"./context\";\nimport { mergeElementProps, resolveElementProps } from \"./element-props\";\nimport { FilterPopover } from \"./filter-popover\";\nimport { ledgerCommands } from \"./ledger-commands\";\nimport { pinnedCellStyle, pinnedEdge } from \"./pinning\";\nimport { syncTruncationTitle } from \"./truncate\";\nimport { useColumnReorder } from \"./use-column-reorder\";\nimport { useColumnResize } from \"./use-column-resize\";\nimport { windowHeaderCells } from \"./use-column-window\";\n\n/**\n * `columnWidths` and `columnSizing` arrive as props, not through the context or the table: a drag\n * departs from the edge the user grabbed and restores what that render had, and both belong to\n * the render that drew the handle. Reaching for either at event time reaches the shared core,\n * which carries whatever render pass ran last — a discarded one included\n * (docs/architecture.md).\n */\nexport function TableHeader<TData extends RowData>({\n table,\n columnWidths,\n columnSizing,\n columnWindow\n}: {\n table: TableInstance<TData>;\n columnWidths: Record<string, number>;\n columnSizing: ColumnSizingState;\n columnWindow: ColumnWindowView | null;\n}) {\n const {\n getStyles,\n virtualizedRows,\n headerRowProps\n } = useDataTableContext();\n const reorder = useColumnReorder(table);\n const resize = useColumnResize(table.setColumnSizing);\n\n const renderCell = (\n header: Header<TData, unknown>,\n colSpan: number | undefined,\n ariaColIndex: number | undefined\n ) => (\n <HeaderCell\n key={header.id}\n ariaColIndex={ariaColIndex}\n colSpan={colSpan}\n columnSizing={columnSizing}\n columnWidths={columnWidths}\n header={header}\n reorder={reorder}\n resize={resize}\n table={table}\n />\n );\n\n return (\n <MantineTable.Thead {...getStyles(\"thead\")}>\n {table.getHeaderGroups().map((headerGroup, groupIndex) => (\n <MantineTable.Tr\n key={headerGroup.id}\n {...mergeElementProps(resolveElementProps(headerRowProps, headerGroup), {\n \"aria-rowindex\": virtualizedRows ? groupIndex + 1 : undefined,\n role: \"row\",\n ...getStyles(\"headerRow\")\n })}\n >\n {columnWindow === null\n ? headerGroup.headers.map(header => renderCell(header, undefined, undefined))\n : windowHeaderCells(headerGroup.headers, columnWindow).map(cell => cell.kind === \"spacer\"\n ? <th key={`ledger:spacer-${cell.edge}`} aria-hidden data-ledger-spacer />\n : renderCell(cell.header, cell.colSpan, cell.ariaColIndex))}\n </MantineTable.Tr>\n ))}\n </MantineTable.Thead>\n );\n}\n\ninterface HeaderCellProps<TData extends RowData> {\n header: Header<TData, unknown>;\n table: TableInstance<TData>;\n reorder: ReturnType<typeof useColumnReorder>;\n resize: ReturnType<typeof useColumnResize>;\n columnWidths: Record<string, number>;\n columnSizing: ColumnSizingState;\n /**\n * Both set only under a column window: the clamp rule's colSpan (use-column-window.ts)\n * replaces `header.colSpan`, and the 1-based position covers windowed-out columns too.\n */\n colSpan: number | undefined;\n ariaColIndex: number | undefined;\n}\n\nfunction HeaderCell<TData extends RowData>({\n header,\n table,\n reorder,\n resize,\n columnWidths,\n columnSizing,\n colSpan,\n ariaColIndex\n}: HeaderCellProps<TData>) {\n const {\n getStyles,\n labels,\n icons\n } = useDataTableContext();\n const { column } = header;\n const { meta } = column.columnDef;\n const internal = isInternalColumn(column.id);\n\n const canSort = column.getCanSort();\n const sorted = column.getIsSorted();\n /**\n * The whole of what a sort click applies, resolved here. v9's own handler asks the column\n * again when the click lands — for the gate, for the direction the cycle turns to next — and\n * both of those reads go to the shared core (`toggle-fns.ts`).\n */\n const sortSpec: SortToggleSpec = {\n canMultiSort: column.getCanMultiSort(),\n columnId: column.id,\n maxMultiSortColCount: table.options.maxMultiSortColCount ?? Number.MAX_SAFE_INTEGER,\n nextOrderMulti: column.getNextSortingOrder(true),\n nextOrderSingle: column.getNextSortingOrder(false)\n };\n // v9's own default, restated: the feature's `getDefaultTableOptions` is merged into the core's\n // options, not into the wrapper's, so reading only `table.options` here would silently make\n // every click a single-sort. A consumer override through `tableOptions` still wins.\n const isMultiSortEvent = table.options.isMultiSortEvent ?? ((event: unknown) => (event as MouseEvent).shiftKey);\n const sorting = ledgerCommands(table.options.meta?.ledger)?.sorting;\n const sortCount = table.atoms.sorting.get().length;\n const sortIndex = column.getSortIndex();\n // Ledger's own gate: the TanStack `columnResizingFeature` (and its `getCanResize`) is\n // deliberately unregistered — the drag pipeline is ledger's (docs/sizing.md).\n const canResize\n = table.options.meta?.ledger?.enableColumnResizing === true\n && columnEnableResizing(column.columnDef) !== false\n // Only leaves have a width: the engine resolves and consumes leaf sizing, so a handle on\n // a group header would write a `columnSizing` entry nothing ever reads.\n && column.columns.length === 0;\n const resizing = resize.resizingId === column.id;\n /**\n * Everything a drag or a fit decides with, read here, in the render that draws the handle —\n * the width on screen, the constraints this render's definition carries, the entry Escape puts\n * back, and whether the header reserves room for a filter control. The handler on the DOM then\n * needs nothing from the table at all (docs/architecture.md).\n */\n const resizerSpec: ResizerSpec = {\n columnId: column.id,\n width: columnWidths[column.id] ?? column.getSize(),\n minSize: column.columnDef.minSize ?? 20,\n maxSize: column.columnDef.maxSize ?? Number.MAX_SAFE_INTEGER,\n sizingEntry: columnSizing[column.id]\n };\n\n const dragged = reorder.drag.draggedId === column.id;\n const dropSide = reorder.drag.targetId === column.id ? reorder.drag.side : null;\n\n const ariaSort = sorted === \"asc\" ? \"ascending\" : sorted === \"desc\" ? \"descending\" : undefined;\n\n const handleSortClick = (event: MouseEvent) => {\n if (reorder.consumeClickSuppression()) {\n return;\n }\n\n if (!canSort) {\n return;\n }\n\n sorting?.toggle(sortSpec, sortSpec.canMultiSort && (isMultiSortEvent?.(event) ?? false));\n };\n\n const label = header.isPlaceholder\n ? null\n : flexRender(column.columnDef.header, header.getContext());\n\n return (\n <MantineTable.Th\n {...mergeElementProps(resolveElementProps(meta?.headerCellProps, header), {\n \"aria-colindex\": ariaColIndex,\n \"aria-sort\": canSort ? ariaSort : undefined,\n colSpan: colSpan ?? header.colSpan,\n \"data-align\": internal ? \"center\" : meta?.align,\n \"data-dragging\": dragged || undefined,\n \"data-drop-side\": dropSide ?? undefined,\n \"data-ledger-column-id\": column.id,\n \"data-pinned\": column.getIsPinned() || undefined,\n \"data-pinned-edge\": pinnedEdge(column),\n \"data-resizing\": resizing || undefined,\n \"data-sortable\": canSort || undefined,\n role: \"columnheader\",\n ...getStyles(\"headerCell\", { style: pinnedCellStyle(column) }),\n ...reorder.getHeaderProps(column.id)\n })}\n >\n {header.isPlaceholder\n ? null\n : internal\n // Injected headers (checkbox, expand-all) are controls, not text — the label\n // scaffolding's [data-truncate] span would clip them at the cell's content box.\n ? label\n : (\n <>\n {canSort\n ? (\n // A NATIVE button, reset in ledger's layer: Mantine's UnstyledButton ships an\n // unlayered font-size that defeats the layered `font: inherit` (styling.md).\n <button\n type=\"button\"\n onClick={handleSortClick}\n {...getStyles(\"headerLabel\")}\n data-align={meta?.align}\n >\n <span data-truncate onPointerEnter={syncTruncationTitle}>{label}</span>\n\n <span {...getStyles(\"sortIndicator\")} data-sorted={sorted || undefined}>\n {sorted === \"asc\" && <icons.sortAsc size={14} />}\n {sorted === \"desc\" && <icons.sortDesc size={14} />}\n {sorted === false && <icons.sortable size={14} />}\n {sorted !== false && sortCount > 1 && sortIndex >= 0 && <sup>{sortIndex + 1}</sup>}\n </span>\n </button>\n )\n : (\n <div {...getStyles(\"headerLabel\")} data-align={meta?.align}>\n <span data-truncate onPointerEnter={syncTruncationTitle}>{label}</span>\n </div>\n )}\n\n {meta?.filter !== undefined && (\n <div {...getStyles(\"headerActions\")} data-ledger-no-drag>\n <FilterPopover column={column} />\n </div>\n )}\n\n {canResize && (\n <Tooltip disabled={resizing} label={labels.resizeColumn} openDelay={500}>\n <div\n // A pointer-only affordance, hidden from assistive tech on purpose: it\n // takes no focus and answers no key, and the keyboard route to the same\n // `columnSizing` entry is the columns panel's width field\n // (docs/accessibility.md). Announcing an inoperable control would be worse\n // than announcing nothing; the hint rides a hover Tooltip for the mouse,\n // disabled mid-drag so it never chases the handle.\n aria-hidden\n data-ledger-no-drag\n data-ledger-resizer\n data-resizing={resizing || undefined}\n onClick={event => event.stopPropagation()}\n onDoubleClick={event => {\n const main = event.currentTarget.closest<HTMLElement>(\".ledger-main\");\n\n if (main) {\n autosizeColumn(\n table.setColumnSizing,\n { ...resizerSpec, hasFilter: meta?.filter !== undefined },\n main\n );\n }\n }}\n {...resize.getResizerProps(resizerSpec)}\n {...getStyles(\"resizer\")}\n />\n </Tooltip>\n )}\n </>\n )}\n </MantineTable.Th>\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { Column, TableInstance } from \"./types\";\n\n/**\n * The width engine (docs/sizing.md): every visible leaf column resolves to an exact integer\n * pixel width, so the rendered width, the specified width, and the pinned-offset basis are one\n * number system — the browser never redistributes anything.\n *\n * Rules, in order:\n * - a column with an explicit width (user-resized `columnSizing` entry, else the author's\n * `size`, else `defaultColumn.size`) is fixed at that width, clamped to its declared min/max;\n * - a column without one is a grow column with basis `minSize ?? 80`; container surplus is\n * distributed proportionally to the bases (integer floor, remainder in display order), capped\n * by maxSize; when the container is too small every grow column falls back to its basis and the\n * table overflows into horizontal scroll;\n * - with no grow columns at all, surplus distributes proportionally over every column up to each\n * maxSize. Hard maximums win over filling the viewport.\n *\n * Author sizing comes from the raw-definition registry (`rawColumnSizing`), never from\n * `column.columnDef` — TanStack merges `size: 150, minSize: 20` defaults into every resolved\n * definition, which would make \"unsized\" unrepresentable.\n */\nimport { useCallback, useLayoutEffect, useMemo, useState } from \"react\";\n\nimport { rawColumnSizing } from \"./build-columns\";\n\n/**\n * Grow basis for columns that declare neither `size` nor `minSize`.\n */\nconst DEFAULT_FLEX_BASIS = 80;\n\nexport interface ColumnWidthSpec {\n id: string;\n size: number | undefined;\n minSize: number | undefined;\n maxSize: number | undefined;\n}\n\nexport interface ColumnWidths {\n /**\n * Resolved width per visible leaf column id, integer pixels.\n */\n byId: Record<string, number>;\n /**\n * Sum of all resolved widths — the exact table width.\n */\n total: number;\n}\n\nfunction finiteNumber(value: number | undefined): number | undefined {\n return value !== undefined && Number.isFinite(value) ? value : undefined;\n}\n\nfunction normalizedBound(value: number | undefined): number | undefined {\n const finite = finiteNumber(value);\n\n return finite === undefined ? undefined : Math.max(0, Math.round(finite));\n}\n\nfunction clampWidth(value: number, min: number | undefined, max: number | undefined): number {\n const rounded = Number.isFinite(value) ? Math.max(0, Math.round(value)) : 0;\n\n return Math.min(\n Math.max(rounded, normalizedBound(min) ?? 0),\n normalizedBound(max) ?? Number.MAX_SAFE_INTEGER\n );\n}\n\ninterface SurplusRecipient {\n id: string;\n weight: number;\n max: number | undefined;\n}\n\n/**\n * Weighted water-filling over integer pixels. Columns that hit maxSize leave the active set and\n * the remaining space is redistributed over columns that can still grow. If every column reaches\n * its cap, maxSize wins and the table intentionally stops short of the viewport.\n */\nfunction distributeSurplus(\n byId: Record<string, number>,\n recipients: SurplusRecipient[],\n surplus: number\n): void {\n let remaining = surplus;\n\n while (remaining > 0) {\n const active = recipients.filter(\n recipient => recipient.max === undefined || byId[recipient.id]! < recipient.max\n );\n\n if (active.length === 0) {\n return;\n }\n\n const positiveWeightTotal = active.reduce(\n (total, recipient) => total + Math.max(0, recipient.weight),\n 0\n );\n const equalWeight = positiveWeightTotal === 0;\n const weightTotal = equalWeight ? active.length : positiveWeightTotal;\n let distributed = 0;\n\n for (const recipient of active) {\n const current = byId[recipient.id]!;\n const capacity = recipient.max === undefined\n ? Infinity\n : recipient.max - current;\n const weight = equalWeight ? 1 : Math.max(0, recipient.weight);\n const share = Math.min(capacity, Math.floor((remaining * weight) / weightTotal));\n\n if (share > 0) {\n byId[recipient.id] = current + share;\n distributed += share;\n }\n }\n\n remaining -= distributed;\n\n if (remaining === 0) {\n return;\n }\n\n // Every proportional share rounded to zero. Hand the integer remainder out in display order;\n // this preserves the engine's established \"remainder to the first columns\" determinism.\n if (distributed === 0) {\n for (const recipient of active) {\n const current = byId[recipient.id]!;\n const capacity = recipient.max === undefined\n ? Infinity\n : recipient.max - current;\n\n if (capacity > 0) {\n byId[recipient.id] = current + 1;\n remaining -= 1;\n }\n\n if (remaining === 0) {\n return;\n }\n }\n }\n }\n}\n\nexport function resolveColumnWidths(\n columns: ColumnWidthSpec[],\n columnSizing: Record<string, number>,\n availableWidth: number\n): ColumnWidths {\n const byId: Record<string, number> = {};\n const growColumns: SurplusRecipient[] = [];\n\n for (const column of columns) {\n const sized = finiteNumber(columnSizing[column.id]) ?? finiteNumber(column.size);\n\n if (sized === undefined) {\n const basis = clampWidth(column.minSize ?? DEFAULT_FLEX_BASIS, column.minSize, column.maxSize);\n byId[column.id] = basis;\n growColumns.push({\n id: column.id,\n weight: basis,\n max: normalizedBound(column.maxSize)\n });\n } else {\n byId[column.id] = clampWidth(sized, column.minSize, column.maxSize);\n }\n }\n\n const baseTotal = columns.reduce((total, column) => total + (byId[column.id] ?? 0), 0);\n const targetWidth = Number.isFinite(availableWidth) ? Math.max(0, Math.round(availableWidth)) : 0;\n const surplus = targetWidth - baseTotal;\n\n if (surplus > 0) {\n const recipients = growColumns.length > 0\n ? growColumns\n : columns.map(column => {\n return {\n id: column.id,\n weight: byId[column.id] ?? 0,\n max: normalizedBound(column.maxSize)\n };\n });\n\n distributeSurplus(byId, recipients, surplus);\n }\n\n const total = columns.reduce((sum, column) => sum + (byId[column.id] ?? 0), 0);\n\n return { byId, total };\n}\n\n/**\n * Resolve `tableMinWidth` to pixels. Numbers are pixels; strings are resolved through the\n * body table's computed style (the browser turns rem/em into px there).\n */\nfunction minWidthPx(tableMinWidth: number | string | undefined, viewport: HTMLElement | null): number {\n if (tableMinWidth === undefined) {\n return 0;\n }\n\n if (typeof tableMinWidth === \"number\") {\n return tableMinWidth;\n }\n\n const tableElement = viewport?.querySelector(\"table\");\n\n if (!tableElement) {\n // eslint-disable-next-line unicorn/prefer-number-coercion -- parses CSS lengths (\"60rem\"); Number() would yield NaN\n return Number.parseFloat(tableMinWidth) || 0;\n }\n\n // eslint-disable-next-line unicorn/prefer-number-coercion -- parses the computed \"123px\" string; Number() would yield NaN\n return Number.parseFloat(getComputedStyle(tableElement).minWidth) || 0;\n}\n\nexport function useColumnWidths<TData extends RowData>(\n table: TableInstance<TData>,\n /**\n * Visible leaf columns in DISPLAY order (pinned-aware) — the same order the colgroup renders.\n */\n columns: Array<Column<TData, unknown>>,\n viewport: HTMLDivElement | null,\n tableMinWidth: number | string | undefined\n): ColumnWidths {\n const [availableWidth, setAvailableWidth] = useState(0);\n\n const measure = useCallback(() => {\n if (!viewport) {\n return;\n }\n\n const next = Math.max(viewport.clientWidth, minWidthPx(tableMinWidth, viewport));\n setAvailableWidth(previous => previous === next ? previous : next);\n }, [viewport, tableMinWidth]);\n\n /* Pre-paint measurement: the corrected widths land before the first frame is shown. */\n useLayoutEffect(() => {\n measure();\n\n if (!viewport) {\n return;\n }\n\n const observer = new ResizeObserver(measure);\n observer.observe(viewport);\n\n return () => observer.disconnect();\n }, [viewport, measure]);\n\n const { columnSizing } = table.state;\n const { defaultColumn } = table.options;\n\n const resolved = useMemo(\n () => {\n const specs = columns.map<ColumnWidthSpec>(column => {\n const raw = rawColumnSizing(column.columnDef);\n\n return {\n id: column.id,\n size: raw ? raw.size ?? defaultColumn?.size : column.columnDef.size,\n minSize: raw ? raw.minSize ?? defaultColumn?.minSize : column.columnDef.minSize,\n maxSize: raw ? raw.maxSize ?? defaultColumn?.maxSize : column.columnDef.maxSize\n };\n });\n\n return resolveColumnWidths(specs, columnSizing, availableWidth);\n },\n [columns, columnSizing, availableWidth, defaultColumn]\n );\n\n /* Stable identity while the numbers are unchanged — downstream memos depend on it. */\n const signature = JSON.stringify([resolved.total, Object.entries(resolved.byId)]);\n\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- `signature` fully encodes `resolved`\n return useMemo(() => resolved, [signature]);\n}\n","import type { FilterFn, RowData } from \"@tanstack/react-table\";\n\n/**\n * The canonical TanStack v9 feature set every ledger table runs on (docs/state.md). One static\n * object so `typeof ledgerFeatures` (`LedgerFeatures`) can pre-bind the `TFeatures` generic of\n * every re-exported type — consumers keep writing v8-shaped `ColumnDef<TData>` code.\n *\n * - Every stock feature is registered EXCEPT the two below.\n * - `columnResizingFeature`: ledger owns the resize interaction end to end\n * (`use-column-resize.ts`), so TanStack's drag machinery — and with it the `columnResizing`\n * state slice, `getIsResizing()`, and `getResizeHandler()` — is not registered at all.\n * Feature-gated APIs cannot lie about a pipeline that never runs.\n * - `cellSelectionFeature`: cell selection is deferred until its own design round\n * (docs/DESIGN.md), so the `cellSelection` state slice, `enableCellSelection`, and\n * `cell.getIsSelected()` are likewise absent by the same rule.\n * - Row model factories are registered statically; the `manualX` translations decide at runtime\n * whether a model actually processes rows (client mode) or passes through (server mode).\n * - Every built-in fn ships registered under its conventional name. v9 resolves string ids —\n * `'auto'` included — only against registered functions, and ledger's contract is that every\n * TanStack capability on a raw `ColumnDef` keeps working; a few KB of fns is the price of\n * that promise.\n */\nimport {\n aggregationFn_count,\n aggregationFn_extent,\n aggregationFn_first,\n aggregationFn_last,\n aggregationFn_max,\n aggregationFn_mean,\n aggregationFn_median,\n aggregationFn_min,\n aggregationFn_sum,\n aggregationFn_unique,\n aggregationFn_uniqueCount,\n cellSpanningFeature,\n columnFacetingFeature,\n columnFilteringFeature,\n columnGroupingFeature,\n columnOrderingFeature,\n columnPinningFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createExpandedRowModel,\n createFacetedMinMaxValues,\n createFacetedRowModel,\n createFacetedUniqueValues,\n createFilteredRowModel,\n createGroupedRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n filterFn_arrHas,\n filterFn_arrIncludes,\n filterFn_arrIncludesAll,\n filterFn_arrIncludesSome,\n filterFn_between,\n filterFn_betweenInclusive,\n filterFn_empty,\n filterFn_endsWith,\n filterFn_equals,\n filterFn_equalsString,\n filterFn_equalsStringSensitive,\n filterFn_greaterThan,\n filterFn_greaterThanOrEqualTo,\n filterFn_includesString,\n filterFn_includesStringSensitive,\n filterFn_inDateRange,\n filterFn_inNumberRange,\n filterFn_lessThan,\n filterFn_lessThanOrEqualTo,\n filterFn_notEmpty,\n filterFn_startsWith,\n filterFn_weakEquals,\n globalFilteringFeature,\n rowAggregationFeature,\n rowExpandingFeature,\n rowPaginationFeature,\n rowPinningFeature,\n rowSelectionFeature,\n rowSortingFeature,\n sortFn_alphanumeric,\n sortFn_alphanumericCaseSensitive,\n sortFn_basic,\n sortFn_datetime,\n sortFn_text,\n sortFn_textCaseSensitive,\n tableFeatures,\n createColumnHelper as tanStackCreateColumnHelper\n} from \"@tanstack/react-table\";\n\nimport { ledgerFilterFns } from \"./filter-fns\";\n\nconst builtInFilterFns = {\n arrHas: filterFn_arrHas,\n arrIncludes: filterFn_arrIncludes,\n arrIncludesAll: filterFn_arrIncludesAll,\n arrIncludesSome: filterFn_arrIncludesSome,\n between: filterFn_between,\n betweenInclusive: filterFn_betweenInclusive,\n empty: filterFn_empty,\n endsWith: filterFn_endsWith,\n equals: filterFn_equals,\n equalsString: filterFn_equalsString,\n equalsStringSensitive: filterFn_equalsStringSensitive,\n greaterThan: filterFn_greaterThan,\n greaterThanOrEqualTo: filterFn_greaterThanOrEqualTo,\n inDateRange: filterFn_inDateRange,\n inNumberRange: filterFn_inNumberRange,\n includesString: filterFn_includesString,\n includesStringSensitive: filterFn_includesStringSensitive,\n lessThan: filterFn_lessThan,\n lessThanOrEqualTo: filterFn_lessThanOrEqualTo,\n notEmpty: filterFn_notEmpty,\n startsWith: filterFn_startsWith,\n weakEquals: filterFn_weakEquals\n};\n\nexport const ledgerFeatures = tableFeatures({\n cellSpanningFeature,\n columnFacetingFeature,\n columnFilteringFeature,\n columnGroupingFeature,\n columnOrderingFeature,\n columnPinningFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n globalFilteringFeature,\n rowAggregationFeature,\n rowExpandingFeature,\n rowPaginationFeature,\n rowPinningFeature,\n rowSelectionFeature,\n rowSortingFeature,\n expandedRowModel: createExpandedRowModel(),\n facetedMinMaxValues: createFacetedMinMaxValues(),\n facetedRowModel: createFacetedRowModel(),\n facetedUniqueValues: createFacetedUniqueValues(),\n filteredRowModel: createFilteredRowModel(),\n groupedRowModel: createGroupedRowModel(),\n paginatedRowModel: createPaginatedRowModel(),\n sortedRowModel: createSortedRowModel(),\n aggregationFns: {\n count: aggregationFn_count,\n extent: aggregationFn_extent,\n first: aggregationFn_first,\n last: aggregationFn_last,\n max: aggregationFn_max,\n mean: aggregationFn_mean,\n median: aggregationFn_median,\n min: aggregationFn_min,\n sum: aggregationFn_sum,\n unique: aggregationFn_unique,\n uniqueCount: aggregationFn_uniqueCount\n },\n filterFns: { ...builtInFilterFns, ...ledgerFilterFns },\n sortFns: {\n alphanumeric: sortFn_alphanumeric,\n alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n textCaseSensitive: sortFn_textCaseSensitive\n }\n});\n\nexport type LedgerFeatures = typeof ledgerFeatures;\n\n/**\n * TanStack's column helper, pre-bound to the canonical feature set — consumers keep the v8\n * calling shape (`createColumnHelper<Person>()`), never managing `TFeatures` themselves.\n */\nexport function createColumnHelper<TData extends RowData>() {\n return tanStackCreateColumnHelper<LedgerFeatures, TData>();\n}\n\n/**\n * The per-instance feature object: the canonical set, plus the consumer's `filterFns` registry\n * merged beneath ledger's reserved ids. Read once at mount (the `features` option wires code\n * modules, not reactive state).\n */\nexport function buildLedgerFeatures(\n consumerFilterFns: Record<string, FilterFn<any, any>> | undefined\n): LedgerFeatures {\n if (!consumerFilterFns) {\n return ledgerFeatures;\n }\n\n return {\n ...ledgerFeatures,\n filterFns: {\n ...builtInFilterFns,\n ...consumerFilterFns,\n ...ledgerFilterFns\n }\n };\n}\n","import type { DataTablePersistableSlice, DataTablePersistState } from \"./types\";\n\n/**\n * Opt-in state persistence (`persistState`). Hydration happens once, synchronously, so the first\n * render already shows the restored layout; writes are debounced and the latest pending value\n * flushes on real unmount. Storage content is a trust boundary — values are shape-checked before\n * use, and a stale or corrupt entry degrades to defaults instead of crashing the table.\n */\nimport { useEffect, useRef } from \"react\";\n\nimport { warnOnce } from \"./env\";\n\nconst STORAGE_PREFIX = \"ledger:\";\nconst WRITE_DEBOUNCE_MS = 250;\n\nconst DEFAULT_SLICES: readonly DataTablePersistableSlice[] = [\n \"columnSizing\",\n \"columnVisibility\",\n \"columnOrder\",\n \"columnPinning\"\n];\n\ntype PersistedState = Partial<Record<DataTablePersistableSlice, unknown>>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every(entry => typeof entry === \"string\");\n}\n\nfunction isRecordOf(value: unknown, guard: (entry: unknown) => boolean): boolean {\n return isRecord(value) && Object.values(value).every(entry => guard(entry));\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction isSafeInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value);\n}\n\nfunction isSortingState(value: unknown): boolean {\n if (!Array.isArray(value)) {\n return false;\n }\n\n return value.every(entry => isRecord(entry)\n && typeof entry.id === \"string\"\n && typeof entry.desc === \"boolean\");\n}\n\nfunction isColumnFiltersState(value: unknown): boolean {\n if (!Array.isArray(value)) {\n return false;\n }\n\n return value.every(entry => isRecord(entry)\n && typeof entry.id === \"string\"\n && Object.hasOwn(entry, \"value\"));\n}\n\nfunction isPaginationState(value: unknown): boolean {\n if (!isRecord(value)) {\n return false;\n }\n\n return isSafeInteger(value.pageIndex)\n && value.pageIndex >= 0\n && isSafeInteger(value.pageSize)\n && value.pageSize > 0;\n}\n\nfunction isColumnPinningState(value: unknown): boolean {\n if (!isRecord(value)) {\n return false;\n }\n\n return isStringArray(value.start) && isStringArray(value.end);\n}\n\n/**\n * Start wins an overlap, and each side holds a column once. A pinned id repeated within a side —\n * or claimed by both — would put the same column in the display order twice, which is a duplicate\n * `<col>`, a duplicate cell, and a duplicate React key. The reader is a trust boundary\n * (docs/state.md), so the shape is repaired rather than believed.\n */\nfunction normalizeColumnPinning(value: unknown): unknown {\n if (!isRecord(value) || !isStringArray(value.start) || !isStringArray(value.end)) {\n return value;\n }\n\n const start = new Set(value.start);\n\n return { end: [...new Set(value.end).difference(start)], start: [...start] };\n}\n\n/**\n * The slices whose *valid* shape still needs repairing. Deliberately not every slice: a guard says\n * whether the value can be used at all, and only pinning carries an invariant beyond its shape.\n */\nconst sliceNormalizers: Partial<Record<DataTablePersistableSlice, (value: unknown) => unknown>> = {\n columnPinning: normalizeColumnPinning\n};\n\n/**\n * Per-slice shape guards — storage may hold data written by an older app version.\n */\nconst sliceGuards: Record<DataTablePersistableSlice, (value: unknown) => boolean> = {\n sorting: isSortingState,\n columnFilters: isColumnFiltersState,\n globalFilter: value => typeof value === \"string\",\n pagination: isPaginationState,\n columnVisibility: value => isRecordOf(value, entry => typeof entry === \"boolean\"),\n columnPinning: isColumnPinningState,\n columnOrder: isStringArray,\n columnSizing: value => isRecordOf(value, entry => isFiniteNumber(entry) && entry >= 0),\n grouping: isStringArray\n};\n\nfunction resolveStorage(persist: DataTablePersistState): DataTablePersistState[\"storage\"] {\n if (persist.storage) {\n return persist.storage;\n }\n\n try {\n return typeof localStorage === \"undefined\" ? undefined : localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport function readPersistedState(persist: DataTablePersistState | undefined): PersistedState {\n if (!persist) {\n return {};\n }\n\n try {\n const raw = resolveStorage(persist)?.getItem(STORAGE_PREFIX + persist.key);\n\n if (!raw) {\n return {};\n }\n\n const parsed: unknown = JSON.parse(raw);\n\n if (!isRecord(parsed)) {\n return {};\n }\n\n const slices = persist.slices ?? DEFAULT_SLICES;\n const result: PersistedState = {};\n\n for (const slice of slices) {\n const value = parsed[slice];\n\n if (value !== undefined && sliceGuards[slice](value)) {\n result[slice] = sliceNormalizers[slice]?.(value) ?? value;\n }\n }\n\n return result;\n } catch {\n return {};\n }\n}\n\nfunction serializeSlices(\n slices: readonly DataTablePersistableSlice[],\n state: Record<DataTablePersistableSlice, unknown>\n): string | null {\n try {\n return JSON.stringify(Object.fromEntries(slices.map(slice => [slice, state[slice]])));\n } catch {\n warnOnce(\n \"persist-unserializable\",\n \"persistState skipped a write — a persisted slice holds a value JSON cannot represent (a BigInt, a circular reference, or a throwing toJSON).\"\n );\n\n return null;\n }\n}\n\nexport function usePersistWriter(\n persist: DataTablePersistState | undefined,\n state: Record<DataTablePersistableSlice, unknown>\n): void {\n const slices = persist?.slices ?? DEFAULT_SLICES;\n // Serialized in the render that produced the state, but never *throwing* in it: a filter value\n // may be a BigInt, may refer to itself, or may own a `toJSON` that throws, and any of those\n // would take the whole table down on a keystroke. `null` means \"this state cannot be written\",\n // which cancels the pending write rather than leaving the previous payload to stand in for it.\n const serialized = persist ? serializeSlices(slices, state) : \"\";\n const key = persist?.key;\n const storage = persist?.storage;\n const pendingWriteRef = useRef<(() => void) | null>(null);\n const unmountFlushTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!persist || !key || serialized === null) {\n pendingWriteRef.current = null;\n\n return;\n }\n\n const write = () => {\n if (pendingWriteRef.current !== write) {\n return;\n }\n\n try {\n resolveStorage(persist)?.setItem(STORAGE_PREFIX + key, serialized);\n } catch {\n // Quota/privacy-mode failures degrade to \"not persisted\", never to a crash.\n } finally {\n pendingWriteRef.current = null;\n }\n };\n\n pendingWriteRef.current = write;\n const timer = setTimeout(write, WRITE_DEBOUNCE_MS);\n\n return () => clearTimeout(timer);\n // The `storage` dependency re-targets a pending write when the backend swaps under the\n // same key (e.g. a consent flow upgrading in-memory storage to localStorage).\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- `persist` participates via `key`/`serialized`/`storage`; its object identity is irrelevant\n }, [key, serialized, storage]);\n\n useEffect(() => {\n if (unmountFlushTimer.current !== null) {\n clearTimeout(unmountFlushTimer.current);\n unmountFlushTimer.current = null;\n }\n\n return () => {\n // Defer one tick so React StrictMode's simulated unmount/remount can cancel the flush.\n unmountFlushTimer.current = setTimeout(() => {\n unmountFlushTimer.current = null;\n pendingWriteRef.current?.();\n }, 0);\n };\n }, []);\n}\n","import type { ExpandedState, RowSelectionState, SortDirection, SortingState } from \"@tanstack/react-table\";\n\nimport type { Row } from \"./types\";\n\n/**\n * The state a sort, a selection or an expansion toggle produces — TanStack v9's own updater\n * bodies, transcribed as pure functions.\n *\n * v9 computes half of each toggle *outside* the updater it hands the state setter: the next sort\n * direction, whether the row may be selected at all, whether it is currently expanded, the\n * display order a Shift range walks. Those reads go to the shared core, which carries whatever\n * render pass ran last — a pass React discarded included — while the updater's own `old` is\n * correctly the committed value. So the halves disagree, and six measured defects follow\n * (docs/architecture.md).\n *\n * The fix is the shape the resize handle already uses: what a toggle decides with is resolved by\n * the render that drew the control, and the write itself is this module plus the stable slice\n * setter. Nothing here reads `row.table` — only structural row properties (`id`, `subRows`,\n * `parentId`) and the rules its caller resolved.\n *\n * Kept verbatim on purpose, `Object.create(null)` maps included: row ids are opaque application\n * strings, and a plain object literal would let `__proto__` or `constructor` silently fail to\n * become an own key.\n */\n\nfunction emptyMap<T extends object>(): T {\n return Object.create(null) as T;\n}\n\nfunction hasOwnId(map: Record<string, boolean>, rowId: string): boolean {\n return map[rowId] === true;\n}\n\n// ------------------------------------------------------------------------------------------------\n// Sorting\n// ------------------------------------------------------------------------------------------------\n\n/**\n * Everything a sort click decides with, resolved by the render that drew the header.\n */\nexport interface SortToggleSpec {\n columnId: string;\n /**\n * `column.getCanMultiSort()` — whether this column may join an existing multi-sort.\n */\n canMultiSort: boolean;\n /**\n * `column.getNextSortingOrder(false)` and `column.getNextSortingOrder(true)`. Both are needed\n * because the cycle's removal step depends on `enableMultiRemove`, and whether the event is a\n * multi-sort event is only known when it arrives.\n */\n nextOrderSingle: SortDirection | false;\n nextOrderMulti: SortDirection | false;\n /**\n * `options.maxMultiSortColCount`, already defaulted.\n */\n maxMultiSortColCount: number;\n}\n\nexport function nextSorting(old: SortingState, spec: SortToggleSpec, multi: boolean): SortingState {\n const {\n columnId,\n canMultiSort,\n maxMultiSortColCount\n } = spec;\n const nextSortingOrder = multi && canMultiSort ? spec.nextOrderMulti : spec.nextOrderSingle;\n const existingIndex = old.findIndex(entry => entry.id === columnId);\n const existingSorting = existingIndex === -1 ? undefined : old[existingIndex];\n const nextDesc = nextSortingOrder === \"desc\";\n const isMultiMode = Boolean(old.length > 0 && canMultiSort && multi);\n\n let sortAction: \"add\" | \"remove\" | \"replace\" | \"toggle\";\n\n if (isMultiMode) {\n sortAction = existingSorting ? \"toggle\" : \"add\";\n } else {\n sortAction = existingSorting ? \"toggle\" : \"replace\";\n }\n\n if (sortAction === \"toggle\" && !nextSortingOrder) {\n sortAction = \"remove\";\n }\n\n if (sortAction === \"add\") {\n const newSorting = [...old, { desc: nextDesc, id: columnId }];\n newSorting.splice(0, newSorting.length - maxMultiSortColCount);\n\n return newSorting;\n }\n\n if (sortAction === \"toggle\") {\n return isMultiMode\n ? old.map(entry => entry.id === columnId ? { ...entry, desc: nextDesc } : entry)\n : [{ desc: nextDesc, id: columnId }];\n }\n\n if (sortAction === \"remove\") {\n return isMultiMode ? old.filter(entry => entry.id !== columnId) : [];\n }\n\n return [{ desc: nextDesc, id: columnId }];\n}\n\n// ------------------------------------------------------------------------------------------------\n// Selection\n// ------------------------------------------------------------------------------------------------\n\n/**\n * The three row predicates selection asks, resolved against the committed options rather than\n * against `row.table`. Each mirrors its v9 counterpart, `boolean | (row) => boolean` included.\n */\nexport interface SelectionRules {\n canSelect: (row: Row<any>) => boolean;\n canMultiSelect: (row: Row<any>) => boolean;\n canSelectSubRows: (row: Row<any>) => boolean;\n}\n\nexport function mutateRowIsSelected(\n selection: RowSelectionState,\n row: Row<any>,\n value: boolean,\n rules: SelectionRules,\n /**\n * Whether the write cascades into `subRows`. Not a constant: an ordinary row toggle cascades\n * only when the row accepts company, because a single-select row clears the map before it\n * writes itself — so cascading there would leave the last descendant selected instead of the\n * row that was clicked. A range and a select-all always cascade; only their deselect half\n * differs, and that is `respectCanSelectOnDeselect`.\n */\n options: { includeChildren: boolean; respectCanSelectOnDeselect?: boolean }\n): void {\n if (value) {\n if (!rules.canMultiSelect(row)) {\n for (const key of Object.keys(selection)) {\n delete selection[key];\n }\n }\n\n if (rules.canSelect(row)) {\n selection[row.id] = true;\n }\n } else if (!options.respectCanSelectOnDeselect || rules.canSelect(row)) {\n delete selection[row.id];\n }\n\n if (options.includeChildren && row.subRows.length > 0 && rules.canSelectSubRows(row)) {\n for (const subRow of row.subRows) {\n mutateRowIsSelected(selection, subRow as Row<any>, value, rules, options);\n }\n }\n}\n\nexport function nextRowSelection(\n old: RowSelectionState,\n row: Row<any>,\n value: boolean,\n rules: SelectionRules\n): RowSelectionState {\n const selection = Object.assign(emptyMap<RowSelectionState>(), old);\n mutateRowIsSelected(selection, row, value, rules, { includeChildren: rules.canMultiSelect(row) });\n\n return selection;\n}\n\n/**\n * The inclusive interval between two display-order positions. Non-selectable and\n * non-multi-selectable rows inside it are skipped, exactly as v9 skips them.\n */\nexport function nextRangeSelection(\n old: RowSelectionState,\n rows: Array<Row<any>>,\n range: { anchorIndex: number; rowIndex: number; value: boolean },\n rules: SelectionRules\n): RowSelectionState {\n const {\n anchorIndex,\n rowIndex,\n value\n } = range;\n const selection = Object.assign(emptyMap<RowSelectionState>(), old);\n const start = Math.min(anchorIndex, rowIndex);\n const end = Math.max(anchorIndex, rowIndex);\n\n for (let index = start; index <= end; index += 1) {\n const rangeRow = rows[index];\n\n if (rangeRow && rules.canSelect(rangeRow) && rules.canMultiSelect(rangeRow)) {\n mutateRowIsSelected(selection, rangeRow, value, rules, { includeChildren: true });\n }\n }\n\n return selection;\n}\n\nexport function nextPageSelection(\n old: RowSelectionState,\n pageRows: Array<Row<any>>,\n value: boolean,\n rules: SelectionRules\n): RowSelectionState {\n const selection = Object.assign(emptyMap<RowSelectionState>(), old);\n\n for (const row of pageRows) {\n mutateRowIsSelected(selection, row, value, rules, { includeChildren: true, respectCanSelectOnDeselect: true });\n }\n\n return selection;\n}\n\n/**\n * Select-all over every row, not just the page. Descent is blocked by any ancestor whose\n * `enableSubRowSelection` says so, which is why the ancestor verdict is walked and cached per\n * pass the way v9 walks it.\n */\nexport function nextAllSelection(\n old: RowSelectionState,\n flatRows: Array<Row<any>>,\n rowsById: Record<string, Row<any>>,\n value: boolean,\n rules: SelectionRules\n): RowSelectionState {\n const selection = Object.assign(emptyMap<RowSelectionState>(), old);\n\n if (!value) {\n for (const row of flatRows) {\n if (rules.canSelect(row)) {\n delete selection[row.id];\n }\n }\n\n return selection;\n }\n\n const cache = new Map<string, boolean>();\n\n const reachable = (row: Row<any>): boolean => {\n if (!rules.canSelect(row)) {\n return false;\n }\n\n const visited: string[] = [];\n let selectable = true;\n let currentId = row.parentId;\n\n while (currentId !== undefined) {\n const known = cache.get(currentId);\n\n if (known !== undefined) {\n selectable = known;\n\n break;\n }\n\n visited.push(currentId);\n\n const parent = rowsById[currentId];\n\n if (!parent || !rules.canSelectSubRows(parent)) {\n selectable = false;\n\n break;\n }\n\n currentId = parent.parentId;\n }\n\n for (const id of visited) {\n cache.set(id, selectable);\n }\n\n return selectable;\n };\n\n for (const row of flatRows) {\n if (reachable(row)) {\n selection[row.id] = true;\n }\n }\n\n return selection;\n}\n\n// ------------------------------------------------------------------------------------------------\n// Expansion\n// ------------------------------------------------------------------------------------------------\n\n/**\n * `expanded` is `true` (everything) or a map. Expanding out of `true` has to materialize the map\n * first, which is why the expandable row ids are part of the call.\n */\nexport function nextExpanded(\n old: ExpandedState,\n rowId: string,\n targetExpanded: boolean,\n expandableRowIds: () => string[]\n): ExpandedState {\n const exists = old === true ? true : hasOwnId(old, rowId);\n let oldExpanded: Record<string, boolean>;\n\n if (old === true) {\n oldExpanded = emptyMap<Record<string, boolean>>();\n\n for (const id of expandableRowIds()) {\n oldExpanded[id] = true;\n }\n } else {\n oldExpanded = Object.assign(emptyMap<Record<string, boolean>>(), old);\n }\n\n if (!exists && targetExpanded) {\n oldExpanded[rowId] = true;\n\n return oldExpanded;\n }\n\n if (exists && !targetExpanded) {\n const rest = emptyMap<Record<string, boolean>>();\n\n for (const [id, value] of Object.entries(oldExpanded)) {\n if (id !== rowId && value) {\n rest[id] = true;\n }\n }\n\n return rest;\n }\n\n return old;\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type {\n DataTableEditCommit,\n DataTableEditingCell,\n LedgerCellEditor\n} from \"./types\";\nimport type { CommittedTable } from \"./use-committed-table\";\n\n/**\n * The cell-mode editing session (docs/architecture.md — \"Editing sessions live in the controller,\n * not in the editors\"). Everything an editor for one cell shows, and everything the commit needs\n * to decide with, lives here: an editor is unmounted by a hidden column or a virtual scroll at any\n * moment, and a session is not. A mounted editor is a view of this plus a keyboard surface.\n */\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\n\nimport { editErrorMessage, normalizeEdit } from \"./edit-meta\";\nimport { isPromiseLike, useEventCallback } from \"./utils\";\n\nexport interface UseCellEditingInput<TData extends RowData> {\n editingCell: DataTableEditingCell | null;\n setEditingCell: (cell: DataTableEditingCell | null) => void;\n /**\n * Rows, definitions and the gate as the render that reached the screen left them. Everything a\n * commit decides with comes from here rather than from the cell's own table, which is the shared\n * core and carries whatever pass ran last (see `use-committed-table.ts`).\n */\n committed: CommittedTable;\n onEditCommit: ((change: DataTableEditCommit<TData>) => void | Promise<void>) | undefined;\n}\n\nexport interface CellEditingSession {\n active: (rowId: string, columnId: string) => boolean;\n start: (cell: DataTableEditingCell) => void;\n stop: (options?: { commit?: boolean }) => void;\n clear: () => void;\n commit: () => boolean | Promise<boolean>;\n cancel: () => void;\n read: (rowId: string, columnId: string, source: unknown) => unknown;\n /**\n * Commits and moves to the row's next (or previous) editable cell — the row as the screen has\n * it. Answered here rather than by the editor, which would have to walk the shared core.\n */\n moveTo: (backwards: boolean) => void;\n firstEditable: (rowId: string, skipInstant: boolean) => string | null;\n write: (rowId: string, columnId: string, value: unknown) => void;\n pending: (rowId: string, columnId: string) => boolean;\n error: (rowId: string, columnId: string) => string | null;\n register: (rowId: string, columnId: string, editor: LedgerCellEditor) => () => void;\n}\n\ninterface CellStore {\n rowId: string | null;\n columnId: string | null;\n /**\n * The pending value; null while the session holds nothing the application has not seen.\n */\n draft: { value: unknown } | null;\n /**\n * What this session wrote, against what the data read when it went out. While it stands it is\n * what the cell holds; the effect below retires it for good once the data moves past it.\n */\n written: { value: unknown; source: unknown } | null;\n error: string | null;\n /**\n * The session has sent, or discarded, what it holds. A new value reopens it.\n */\n settled: boolean;\n /**\n * Eligibility was lost during this session. It latches: a gate that reopens before an in-flight\n * write settles is the *next* session's eligibility, not a reprieve for this one.\n */\n gateLost: boolean;\n /**\n * The automatic reconciliation has already answered this session's gate closing.\n */\n reconciled: boolean;\n /**\n * The write currently out, and whether the data has moved since it left. A record is only true\n * while the data has not moved past it, and the moving can happen *during* the request —\n * including out and back again, which comparing at settle time could never see.\n */\n writing: { source: unknown; moved: boolean } | null;\n}\n\nfunction closedStore(): CellStore {\n return {\n columnId: null,\n draft: null,\n error: null,\n gateLost: false,\n reconciled: false,\n rowId: null,\n settled: false,\n writing: null,\n written: null\n };\n}\n\nexport function useCellEditing<TData extends RowData>({\n editingCell,\n setEditingCell,\n committed,\n onEditCommit\n}: UseCellEditingInput<TData>): CellEditingSession {\n const store = useRef<CellStore>(closedStore());\n /**\n * Bumped whenever a session starts or ends without the slice moving — a gate shutting under a\n * controlled application that declines to close it, or an explicit start on the cell already\n * named. Whether an editor may be on screen is part of the render output, so a change in it has\n * to be a change in state; a ref would leave the last render standing.\n */\n const [epoch, setEpoch] = useState(0);\n /**\n * One session, one token: a settled request may only act on the session that issued it.\n */\n const sessionRef = useRef(0);\n const pendingCommit = useRef<{ promise: Promise<boolean>; session: number } | null>(null);\n const pendingRef = useRef(false);\n /**\n * The editors on screen, each with the cell it belongs to — see `register`.\n */\n const editors = useRef(new Map<LedgerCellEditor, DataTableEditingCell>());\n /**\n * Only the latest navigation request may win after an async commit settles.\n */\n const requestRef = useRef(0);\n /**\n * The cell that actually reached the screen — see the layout effect.\n */\n const renderedRef = useRef(editingCell);\n /**\n * The armed unmount commit, with the session and cell whose departure armed it.\n */\n const unmountCommit = useRef<{\n session: number;\n target: DataTableEditingCell;\n timer: ReturnType<typeof setTimeout> | null;\n } | null>(null);\n\n const disarmUnmountCommit = () => {\n const armed = unmountCommit.current;\n\n if (armed === null) {\n return;\n }\n\n unmountCommit.current = null;\n\n if (armed.timer !== null) {\n clearTimeout(armed.timer);\n }\n };\n\n const redraw = useCallback(() => {\n for (const editor of editors.current.keys()) {\n editor.redraw();\n }\n }, []);\n\n /**\n * How many editors for `target` are on screen right now.\n */\n const mountedFor = (target: DataTableEditingCell): number => {\n let count = 0;\n\n for (const owner of editors.current.values()) {\n if (owner.rowId === target.rowId && owner.columnId === target.columnId) {\n count += 1;\n }\n }\n\n return count;\n };\n\n const isSession = (rowId: string, columnId: string) => store.current.rowId === rowId && store.current.columnId === columnId;\n const isSessionRef = useRef(isSession);\n\n /**\n * What the cell holds as far as the application is concerned: the value this session wrote while\n * the data has not moved past it, otherwise the data itself.\n */\n const settledValue = (source: unknown): unknown => {\n const record = store.current.written;\n\n return record && Object.is(record.source, source) ? record.value : source;\n };\n\n const settledValueRef = useRef(settledValue);\n\n /**\n * Whether the cell may still be edited right now — the gate, re-read against the commit.\n */\n const stillEditable = (rowId: string, columnId: string): boolean => committed.canEdit(rowId, columnId);\n\n /**\n * Asks for the session to close. Deliberately not a navigation request: a commit closing the\n * cell it just wrote is the very thing a `start` waiting on that commit is waiting *for*, and\n * cancelling the move it is about to make would strand it. Only explicit navigation — another\n * `start`, or a `stop` — invalidates a pending one.\n */\n const requestClose = useEventCallback(() => setEditingCell(null));\n\n /**\n * Ends whatever session the store holds and opens the one for `target`, or none. Every session\n * boundary goes through here — the render one below, and the in-place restart in `start` — so\n * that a session ends whole: a boundary that disowned only some of what the last one held would\n * leave the rest of it speaking for its successor. A departure that has not fired yet belongs\n * to the session ending here, and a write still out belongs to nobody: its settlement finds a\n * token that no longer matches and touches nothing, so the flag it would have cleared has to be\n * cleared now or the next session opens permanently pending.\n */\n const beginSession = (target: DataTableEditingCell | null) => {\n disarmUnmountCommit();\n sessionRef.current += 1;\n pendingCommit.current = null;\n pendingRef.current = false;\n store.current = target === null\n ? closedStore()\n : {\n ...closedStore(),\n columnId: target.columnId,\n rowId: target.rowId\n };\n };\n\n /**\n * Reconciles the session with the cell that actually reached the screen. Committed in a layout\n * effect, never during render: React may throw a tree away, and a session opened for a cell\n * nobody saw would take the commits meant for the one on screen.\n */\n useLayoutEffect(() => {\n renderedRef.current = editingCell;\n\n const owner = store.current;\n const moved = owner.rowId !== (editingCell?.rowId ?? null) || owner.columnId !== (editingCell?.columnId ?? null);\n\n // Judged against what the store holds, not against a mirror of the prop: a table that renders\n // with `editingCell` already set has a session to open on its very first pass, and comparing\n // mirrors would call that \"unmoved\" and never key the store at all.\n if (!moved) {\n return;\n }\n\n beginSession(editingCell);\n });\n\n const setError = (message: string | null) => {\n store.current.error = message;\n redraw();\n };\n\n const setPending = (pending: boolean) => {\n pendingRef.current = pending;\n redraw();\n };\n\n /**\n * Ends the session as a cancellation: what it held is discarded, and the close is requested.\n */\n const markGateLost = () => {\n if (store.current.gateLost) {\n return;\n }\n\n store.current.gateLost = true;\n setEpoch(token => token + 1);\n };\n\n /**\n * Ends a session whose eligibility is gone. Idempotent per session, which is what makes the\n * automatic path safe to reach from the effect, from a settling write, and from an editor\n * leaving the screen because the gate took it away — an application that ignores the close\n * would otherwise be asked once for each. A command is never this: an Escape, a `stopEditing`,\n * or a `startEditing` that has to leave this cell first is always a fresh request, because an\n * owner that declined the last one still has the cell on screen. Reported back, so that a\n * command finding the session already reconciled can ask again itself.\n */\n const closeLostSession = (): boolean => {\n if (store.current.reconciled) {\n return false;\n }\n\n store.current.reconciled = true;\n store.current.draft = null;\n store.current.error = null;\n store.current.settled = true;\n redraw();\n requestClose();\n\n return true;\n };\n\n const cancel = useEventCallback(() => {\n if (pendingRef.current) {\n return;\n }\n\n store.current.draft = null;\n store.current.error = null;\n store.current.settled = true;\n redraw();\n requestClose();\n });\n\n const commit = useEventCallback((): boolean | Promise<boolean> => {\n const { rowId, columnId } = store.current;\n\n if (rowId === null || columnId === null) {\n return true;\n }\n\n const inFlight = pendingCommit.current;\n\n if (inFlight && inFlight.session === sessionRef.current) {\n return inFlight.promise;\n }\n\n if (store.current.settled) {\n if (store.current.gateLost) {\n // This session was cancelled, not finished, so nothing waiting to move may proceed on\n // the strength of it. Reconciliation has already discarded what it held and asked once\n // for the close; this is a command, so it asks again.\n requestClose();\n\n return false;\n }\n\n // Nothing new to send. Still a request to leave, though: an application that ignored the\n // first one keeps this session open, and asking again is how it is closed.\n requestClose();\n\n return true;\n }\n\n const row = committed.row(rowId);\n\n if (!row) {\n // The row is not in the table — a target that has not arrived, or one the data no longer\n // holds. Nothing about that is a gate closing, so the session is not cancelled and nothing\n // it holds is discarded; but there is nothing to write either, and an explicit stop still\n // has to be able to close a session waiting on a row that never came.\n store.current.settled = true;\n requestClose();\n\n return true;\n }\n\n // Eligibility is re-read here, not trusted from when the session opened: `enableEditing` can\n // switch off, `meta.edit` can be removed, and `edit.enabled(row)` can turn false meanwhile.\n // Committing then would push a value through a gate the application has just shut — and\n // unvalidated, since a closed gate is exactly what `validate` no longer guards. The session\n // is cancelled, which is not the same as finished: nothing waiting to move may do so on it.\n if (!committed.canEdit(rowId, columnId)) {\n markGateLost();\n\n if (!closeLostSession()) {\n requestClose();\n }\n\n return false;\n }\n\n const source = committed.value(rowId, columnId);\n const previousValue = settledValue(source);\n const value = store.current.draft ? store.current.draft.value : previousValue;\n\n if (Object.is(value, previousValue)) {\n store.current.settled = true;\n requestClose();\n\n return true;\n }\n\n const normalized = normalizeEdit(committed.edit(columnId));\n\n try {\n if (normalized?.validate) {\n const validationError = normalized.validate(value, row);\n\n if (validationError !== null) {\n setError(validationError);\n\n return false;\n }\n }\n } catch (error) {\n setError(editErrorMessage(error));\n\n return false;\n }\n\n let result: void | Promise<void>;\n\n try {\n result = onEditCommit?.({\n column: committed.column(columnId),\n previousValue,\n row,\n value\n } as DataTableEditCommit<TData>);\n } catch (error) {\n setError(editErrorMessage(error));\n\n return false;\n }\n\n if (!isPromiseLike(result)) {\n store.current.written = { source, value };\n store.current.draft = null;\n store.current.settled = true;\n requestClose();\n\n return true;\n }\n\n const session = sessionRef.current;\n store.current.writing = { moved: false, source };\n setPending(true);\n\n // The in-flight slot is released inside the handlers rather than in a `finally`: the\n // not-carried branch below commits again, and a settled request must not still be standing\n // there for its own successor to join.\n const promise: Promise<boolean> = Promise.resolve(result).then(\n () => {\n if (session !== sessionRef.current) {\n return false;\n }\n\n pendingCommit.current = null;\n // A custom editor is not disabled while the request is out, so the user can type straight\n // past it. What this write carried is what the next edit departs from; a value typed since\n // is one it never carried.\n const carried = !store.current.draft || Object.is(store.current.draft.value, value);\n // Unless the data moved while the request was out — then what the application holds is\n // its own, and this write has nothing left to be true about.\n store.current.written = store.current.writing?.moved === true ? null : { source, value };\n store.current.writing = null;\n store.current.settled = carried;\n\n if (carried) {\n store.current.draft = null;\n }\n\n setPending(false);\n\n // The gate may have shut while this write was out — and a gate that reopened before it\n // landed does not undo that. The write stands, but the session it belonged to is over, so\n // nothing waiting to move may do so on the strength of it.\n if (store.current.gateLost || !stillEditable(rowId, columnId)) {\n markGateLost();\n closeLostSession();\n\n return false;\n }\n\n if (!carried) {\n // Still on screen: the cell does not close, and whoever was waiting to leave it is told\n // it is not safe to. Gone from the screen: nobody can commit it by hand any more, and an\n // unmount commits rather than discards (docs/editing.md), so this write — which did\n // succeed — is followed by the one it outran. That successor carries the latest value,\n // so it settles `carried` and recurses no further.\n return mountedFor({ columnId, rowId }) > 0 ? false : commit();\n }\n\n requestClose();\n\n return true;\n },\n (error: unknown) => {\n if (session !== sessionRef.current) {\n return false;\n }\n\n pendingCommit.current = null;\n store.current.writing = null;\n setPending(false);\n setError(editErrorMessage(error));\n\n // A gate that shut while the request was out is answered now that it has landed.\n if (store.current.gateLost || !stillEditable(rowId, columnId)) {\n markGateLost();\n closeLostSession();\n }\n\n return false;\n }\n );\n\n pendingCommit.current = { promise, session };\n\n return promise;\n });\n\n /**\n * Losing eligibility mid-session cancels it, and the loss latches: reopening the gate is the\n * next session's eligibility. Automatic reconciliation is idempotent per session — an explicit\n * Escape or `stopEditing` is always a fresh request, because an application that ignored the\n * last one has to be asked again. It also retires the write record once the data moves past it,\n * permanently, so data returning to what the write departed from cannot resurrect it.\n */\n useEffect(() => {\n const { rowId, columnId } = store.current;\n\n if (rowId === null || columnId === null) {\n return;\n }\n\n // The table-level gate is answered first, and without a row: a session whose row has not\n // arrived still loses its gate when editing is switched off or the mode's commit handler is\n // taken away, and must not be found waiting when either comes back.\n if (committed.tableGate()) {\n if (committed.row(rowId) === null) {\n // The row is not in the table: a target that has not arrived, or one the data no longer\n // holds. Neither is an application closing a gate, so the session waits for it.\n return;\n }\n\n const source = committed.value(rowId, columnId);\n const record = store.current.written;\n\n if (record && !Object.is(record.source, source)) {\n store.current.written = null;\n redraw();\n }\n\n // The same watch, for the write still out: it has no record to retire yet, so the movement\n // has to be remembered until it does.\n if (store.current.writing && !Object.is(store.current.writing.source, source)) {\n store.current.writing.moved = true;\n }\n\n if (committed.canEdit(rowId, columnId)) {\n return;\n }\n }\n\n markGateLost();\n\n // The in-flight write passed the gate before it shut; its settlement completes the cancel.\n if (pendingRef.current) {\n return;\n }\n\n closeLostSession();\n });\n\n const clear = useEventCallback(() => {\n if (renderedRef.current !== null) {\n requestClose();\n }\n });\n\n const stop = useEventCallback((options?: { commit?: boolean }) => {\n // An explicit stop overrules a move still waiting on a commit.\n requestRef.current += 1;\n\n if (options?.commit ?? true) {\n void Promise.resolve(commit()).catch(() => false);\n } else {\n cancel();\n }\n });\n\n const start = useEventCallback((target: DataTableEditingCell) => {\n const request = ++requestRef.current;\n const rendered = renderedRef.current;\n\n if (!rendered || (rendered.rowId === target.rowId && rendered.columnId === target.columnId)) {\n if (isSession(target.rowId, target.columnId) && store.current.gateLost) {\n // The session on this cell is over — its gate shut, and a controlled application declined\n // to close it. An explicit start is not that session coming back: it is the next one, so\n // it gets a new token and nothing the old one held. The slice already names this cell, so\n // no render would arrive to do it for us.\n beginSession(target);\n setEpoch(token => token + 1);\n }\n\n setEditingCell(target);\n\n return;\n }\n\n // Not named `committed`: that is the snapshot reader this whole module decides with, and a\n // local shadowing it inside the one function that also commits is a trap for the next reader.\n const outcome = commit();\n\n if (typeof outcome === \"boolean\") {\n if (outcome && requestRef.current === request) {\n setEditingCell(target);\n }\n\n return;\n }\n\n void Promise.resolve(outcome).then(\n success => {\n if (success && requestRef.current === request) {\n setEditingCell(target);\n }\n },\n // Custom editors may still reject despite the boolean-result contract; stay put.\n () => false\n );\n });\n\n /**\n * An editor registers while it is on screen. Its departure arms the unmount commit, deferred one\n * tick so a remount of the same cell — StrictMode's simulated unmount, or the virtualizer\n * re-mounting a row still in view — cancels it; only a real departure commits, and once nothing\n * is mounted any failure degrades to discard because there is nowhere left to report it.\n *\n * Everything here is decided per target: an editor for one cell must not cancel another cell's\n * departure, and the write that departure sends must not clear a cell that has since come back\n * on screen with something new in it.\n */\n const register = useCallback((rowId: string, columnId: string, editor: LedgerCellEditor) => {\n const target = { columnId, rowId };\n const armed = unmountCommit.current;\n\n if (armed && armed.session === sessionRef.current && armed.target.rowId === rowId && armed.target.columnId === columnId) {\n disarmUnmountCommit();\n }\n\n editors.current.set(editor, target);\n\n return () => {\n editors.current.delete(editor);\n\n if (mountedFor(target) > 0) {\n return;\n }\n\n // An editor the gate took off the screen did not depart — the session it belonged to ended,\n // and it has nothing left to commit on the way out.\n if (store.current.gateLost) {\n return;\n }\n\n const rendered = renderedRef.current;\n\n if (rendered?.rowId !== rowId || rendered.columnId !== columnId) {\n return;\n }\n\n // The record identifies itself, so a tick that fires late can only retire its own: two\n // departures in one tick would otherwise have the first one clear the second's record and\n // leave a live timer nothing can cancel.\n const record: { session: number; target: DataTableEditingCell; timer: ReturnType<typeof setTimeout> | null } = {\n session: sessionRef.current,\n target,\n timer: null\n };\n const { session } = record;\n\n record.timer = setTimeout(() => {\n if (unmountCommit.current === record) {\n unmountCommit.current = null;\n }\n\n // The tick waited, and the session may have moved on: a switch commits the cell being\n // left and opens the next one in the same render, so this departure can find a different\n // cell in its place. Read the owner *before* reaching for a commit, which always speaks\n // for whatever session is current — otherwise this closes the cell that replaced it.\n if (session !== sessionRef.current || store.current.rowId !== rowId || store.current.columnId !== columnId) {\n return;\n }\n\n // A session the gate cancelled has nothing left to commit on the way out, and its close\n // has been asked for: this editor did not depart, it was taken off the screen. The\n // cleanup that armed this tick tests the same thing, but it runs at layout time — before\n // the reconciliation that latches the loss.\n if (store.current.gateLost) {\n return;\n }\n\n const settle = () => {\n // Only if this is still the session that departed, and nothing has taken the cell back\n // on screen meanwhile — a remounted editor may be holding a value this write never saw,\n // and a failure it can show.\n if (session !== sessionRef.current || mountedFor(target) > 0) {\n return;\n }\n\n // Nothing is mounted, so a failure — a `validate` rejection, a throw, a rejected\n // promise — has nowhere left to report itself and degrades to discard\n // (docs/editing.md). Discarded rather than merely closed: an application that declines\n // the close would otherwise see the draft and the message come back with the column.\n store.current.draft = null;\n store.current.error = null;\n store.current.settled = true;\n clear();\n };\n\n const result = commit();\n\n if (isPromiseLike(result)) {\n void Promise.resolve(result).then(settle, settle);\n } else {\n settle();\n }\n }, 0);\n\n unmountCommit.current = record;\n };\n }, [commit, clear]);\n\n // Stable identities all the way out: this surface goes into `meta.ledger`, which the render\n // layer memoizes against — a fresh object or a fresh arrow here would re-render every cell in\n // the table on every render. Each of these reads nothing but refs.\n // `source` comes from the caller — the cell of the render doing the drawing, which is the right\n // one for a render and cannot be a discarded pass's: an editor redraws only after it has\n // rendered, and that render is what resolved the value it is holding.\n const read = useCallback((rowId: string, columnId: string, source: unknown) => {\n if (!isSessionRef.current(rowId, columnId)) {\n return source;\n }\n\n return store.current.draft ? store.current.draft.value : settledValueRef.current(source);\n }, []);\n\n const write = useCallback((rowId: string, columnId: string, value: unknown) => {\n if (!isSessionRef.current(rowId, columnId)) {\n return;\n }\n\n store.current.draft = { value };\n store.current.error = null;\n // A new value is a new edit: the session is only still open past a settled commit because the\n // application declined to close it, and what it holds now no write has carried.\n store.current.settled = false;\n redraw();\n }, [redraw]);\n\n const pending = useCallback((rowId: string, columnId: string) => isSessionRef.current(rowId, columnId) && pendingRef.current, []);\n\n const active = useCallback(\n // Asked during render, so a cell the store has not been keyed to yet is a session about to\n // open, which is live by definition; only the one being tracked can have lost its gate. Keyed\n // to the epoch: the answer lives in a ref, so this identity changing is what carries a\n // session starting or ending into the render layer's memo.\n (rowId: string, columnId: string) => isSessionRef.current(rowId, columnId) ? !store.current.gateLost : true,\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- the epoch is the point: see above\n [epoch]\n );\n const error = useCallback((rowId: string, columnId: string) => isSessionRef.current(rowId, columnId) ? store.current.error : null, []);\n\n /**\n * The row's next editable cell in display order, skipping instant columns — a change there is\n * the commit and hosts no editor for a caret to land in (docs/editing.md). Resolved from the\n * render that reached the screen: the order, the gate and each column's editing kind all come\n * from there, so a render nobody saw cannot decide where the caret goes, or that there is\n * nowhere to go.\n */\n const adjacentEditable = (rowId: string, columnId: string | null, backwards: boolean): string | null => {\n const order = committed.visibleColumnIds();\n const step = backwards ? -1 : 1;\n const from = columnId === null ? backwards ? order.length : -1 : order.indexOf(columnId);\n\n for (let index = from + step; index >= 0 && index < order.length; index += step) {\n const candidate = order[index];\n\n if (candidate !== undefined && committed.canEdit(rowId, candidate) && !committed.isInstant(candidate)) {\n return candidate;\n }\n }\n\n return null;\n };\n\n /**\n * Tab / Shift+Tab: commit, and only then move (docs/editing.md keyboard map). The neighbour is\n * resolved *after* the commit succeeds, never before it is sent — an async write leaves the\n * keyboard free, and a real render landing while it is out can hide the column the caret was\n * headed for, shut its gate, or move it somewhere else entirely.\n */\n const moveTo = useEventCallback((backwards: boolean) => {\n const { rowId } = store.current;\n const from = store.current.columnId;\n\n if (rowId === null || from === null) {\n return;\n }\n\n const settle = (succeeded: boolean) => {\n if (!succeeded) {\n return;\n }\n\n const target = adjacentEditable(rowId, from, backwards);\n\n if (target === null) {\n return;\n }\n\n start({ columnId: target, rowId });\n };\n\n const result = commit();\n\n if (isPromiseLike(result)) {\n // Custom editors may still reject despite the boolean-result contract; stay put.\n void Promise.resolve(result).then(settle, () => undefined);\n } else {\n settle(result);\n }\n });\n\n /**\n * The row's first editable cell — where F2 enters (docs/editing.md#keyboard-and-lifecycle).\n * `skipInstant` is the mode: cell mode has no editor to open on an instant column, row mode\n * does.\n */\n const firstEditable = useEventCallback((rowId: string, skipInstant: boolean): string | null => {\n // On screen first: `canEdit` will answer for a row that is filtered out or on another page —\n // a session may legitimately name one — but F2 acts on the row the user is looking at, and\n // opening an editor nobody can see is not that.\n if (!committed.onScreen(rowId)) {\n return null;\n }\n\n const order = committed.visibleColumnIds();\n\n return order.find(columnId => committed.canEdit(rowId, columnId) && (!skipInstant || !committed.isInstant(columnId))) ?? null;\n });\n\n return useMemo(\n () => {\n return {\n active,\n cancel,\n clear,\n commit,\n error,\n firstEditable,\n moveTo,\n pending,\n read,\n register,\n start,\n stop,\n write\n };\n },\n [active, cancel, clear, commit, error, firstEditable, moveTo, pending, read, register, start, stop, write]\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { EditGate } from \"./edit-meta\";\nimport type { Cell, Column, Row, TableInstance } from \"./types\";\n\n/**\n * What the last committed render resolved, kept where a later render cannot rewrite it.\n *\n * TanStack v9's `useTable` calls `table_setOptions` during render (see its source), so the one\n * shared core instance carries whatever the most recent render pass wrote — including a pass React\n * threw away, which happens whenever a transition renders and a sibling suspends. Everything the\n * core derives from those options follows: `getRow` and the row models, `getAllLeafColumns` and\n * every `columnDef` on them, and `options.meta.ledger`. The wrapper `useTable` returns is safe (its\n * `options` is that render's own object), but its methods delegate to the core, so reaching through\n * one at event time reaches the last render rather than the last commit.\n *\n * So ledger resolves its own answers from here instead: rows, columns and the editing gate as the\n * render that reached the screen left them. Mirrored in an insertion effect — the commit phase, and\n * before every layout effect, so a session boundary or an editor registration already sees it.\n *\n * The boundary this does *not* claim: the TanStack objects handed to the application (`row`,\n * `column` in a commit payload) are the ones that render resolved, not reconstructions — and\n * nothing here fixes the upstream mutation itself, only ledger's own reliance on it.\n */\nimport { useCallback, useMemo, useRef } from \"react\";\n\nimport { canEditWith, normalizeEdit } from \"./edit-meta\";\n\ntype ColumnEdit = NonNullable<Cell<any, unknown>[\"column\"][\"columnDef\"][\"meta\"]>[\"edit\"];\n\nexport type CaptureCommitted<TData extends RowData> = (table: TableInstance<TData>, gate: EditGate) => void;\n\nexport interface CommittedTable {\n /**\n * The row as the committed render resolved it — `original` included, which is what a commit\n * departs from.\n */\n row: (rowId: string) => Row<any> | null;\n /**\n * That row's value for a column, through the committed accessor.\n */\n value: (rowId: string, columnId: string) => unknown;\n /**\n * The committed `meta.edit`, never `cell.column.columnDef.meta` — the core rewrites its\n * definitions on every render pass, committed or not.\n */\n edit: (columnId: string) => ColumnEdit;\n /**\n * Whether the committed definitions hold this column at all. A column that left is a layout\n * change; a column whose gate shut is an application closing one, and row mode tells them apart\n * (docs/editing.md#row-mode).\n */\n has: (columnId: string) => boolean;\n /**\n * Every leaf column of the committed definitions, in their own order — the order\n * `row.getAllCells()` walks. Hidden ones included: a column the columns panel hid still holds a\n * draft, and still commits it (docs/editing.md).\n */\n columnIds: () => string[];\n /**\n * The leaf columns that render, in **display** order — start + center + end, the order the\n * header groups and each row's cells are drawn in. `getVisibleLeafColumns` alone ignores\n * pinning (docs/architecture.md), and a keyboard move that used it would step sideways past a\n * pinned column and back.\n */\n visibleColumnIds: () => string[];\n canEdit: (rowId: string, columnId: string) => boolean;\n /**\n * The row is one the committed render actually put on screen — after filtering, pagination and\n * pinning. `row` deliberately reaches further back (a session may name a row that is filtered\n * out, or has not arrived), so anything that means \"the row the user is looking at\" asks this.\n */\n onScreen: (rowId: string) => boolean;\n /**\n * The committed definition declares an instant-apply control — which the keyboard entry\n * points need, because what an instant column *is* depends on the mode (docs/editing.md).\n */\n isInstant: (columnId: string) => boolean;\n /**\n * Whether editing is possible at all: the table switch is on *and* the live mode has a handler\n * to send an edit to. Both are table-level facts, so this is answered without a row — which is\n * what lets a session whose row has not arrived still lose its gate, and keeps \"the row is not\n * here\" apart from \"the application closed the gate\" when they happen together.\n */\n tableGate: () => boolean;\n /**\n * The committed TanStack column, for the payload handed to the application.\n */\n column: (columnId: string) => Column<any, unknown> | null;\n}\n\ninterface Snapshot {\n displayRowIds: Set<string>;\n visibleColumnIds: string[];\n rows: Record<string, Row<any>>;\n coreRows: Record<string, Row<any>>;\n columns: Map<string, Column<any, unknown>>;\n columnIds: string[];\n enableEditing: boolean;\n hasCommitHandler: boolean;\n}\n\nconst EMPTY: Snapshot = {\n displayRowIds: new Set(),\n visibleColumnIds: [],\n columnIds: [],\n columns: new Map(),\n coreRows: {},\n enableEditing: false,\n hasCommitHandler: false,\n rows: {}\n};\n\n/**\n * Returns the readers and the one function that fills them. Taking the snapshot is deliberately\n * the caller's move: the table instance only exists further down `useDataTable`, while the session\n * controllers that read this are built before it — so the readers are handed out first and the\n * capture happens in the same insertion effect that mirrors the instance itself.\n */\nexport function useCommittedTable<TData extends RowData>(): readonly [CommittedTable, CaptureCommitted<TData>] {\n const snapshot = useRef<Snapshot>(EMPTY);\n\n const capture = useCallback<CaptureCommitted<TData>>((table, gate) => {\n const columns = new Map<string, Column<any, unknown>>();\n const columnIds: string[] = [];\n\n for (const column of table.getAllLeafColumns() as Array<Column<any, unknown>>) {\n columns.set(column.id, column);\n columnIds.push(column.id);\n }\n\n // What the body drew, in the same terms the keyboard navigation uses: pinned rows are on\n // screen alongside the page's own, and the row model alone would miss them.\n const displayRows = table.options.enableRowPinning === true\n ? [...table.getTopRows(), ...table.getCenterRows(), ...table.getBottomRows()]\n : table.getRowModel().rows;\n\n snapshot.current = {\n displayRowIds: new Set(displayRows.map(row => row.id)),\n visibleColumnIds: [\n ...table.getStartVisibleLeafColumns(),\n ...table.getCenterVisibleLeafColumns(),\n ...table.getEndVisibleLeafColumns()\n ].map(column => column.id),\n columnIds,\n columns,\n // The same two models `table_getRow(id, true)` consults, in the same order, read here where\n // the options behind them are still the ones this commit rendered from.\n coreRows: table.getCoreRowModel().rowsById as Record<string, Row<any>>,\n enableEditing: gate.enableEditing,\n hasCommitHandler: gate.hasCommitHandler,\n rows: table.getPrePaginatedRowModel().rowsById as Record<string, Row<any>>\n };\n }, []);\n\n // Stable identities: this goes to the session controllers, which memoize against it.\n const row = useCallback((rowId: string) => snapshot.current.rows[rowId] ?? snapshot.current.coreRows[rowId] ?? null, []);\n const column = useCallback((columnId: string) => snapshot.current.columns.get(columnId) ?? null, []);\n const has = useCallback((columnId: string) => snapshot.current.columns.has(columnId), []);\n const columnIds = useCallback(() => snapshot.current.columnIds, []);\n const onScreen = useCallback((rowId: string) => snapshot.current.displayRowIds.has(rowId), []);\n const visibleColumnIds = useCallback(() => snapshot.current.visibleColumnIds, []);\n const edit = useCallback((columnId: string) => snapshot.current.columns.get(columnId)?.columnDef.meta?.edit, []);\n const isInstant = useCallback((columnId: string) => normalizeEdit(snapshot.current.columns.get(columnId)?.columnDef.meta?.edit)?.kind === \"instant\", []);\n const tableGate = useCallback(() => snapshot.current.enableEditing && snapshot.current.hasCommitHandler, []);\n\n const value = useCallback((rowId: string, columnId: string) => {\n const found = snapshot.current.rows[rowId] ?? snapshot.current.coreRows[rowId] ?? null;\n\n // The committed column's accessor over the committed row, rather than `row.getValue` — which\n // resolves the column through `row.table`, and that is the shared core. Upstream caches a\n // row's values after the first read, so in most orders the two agree; depending on that is\n // depending on having read the value already, which nothing here can promise.\n return found === null ? undefined : snapshot.current.columns.get(columnId)?.accessorFn?.(found.original, found.index);\n }, []);\n\n const canEdit = useCallback((rowId: string, columnId: string) => {\n const found = snapshot.current.rows[rowId] ?? snapshot.current.coreRows[rowId] ?? null;\n\n if (!found) {\n return false;\n }\n\n return canEditWith(found, snapshot.current.columns.get(columnId)?.columnDef.meta?.edit, {\n enableEditing: snapshot.current.enableEditing,\n hasCommitHandler: snapshot.current.hasCommitHandler\n });\n }, []);\n\n const committed = useMemo(\n () => {\n return {\n canEdit,\n column,\n columnIds,\n edit,\n has,\n isInstant,\n onScreen,\n row,\n tableGate,\n value,\n visibleColumnIds\n };\n },\n [canEdit, column, columnIds, edit, has, isInstant, onScreen, row, tableGate, value, visibleColumnIds]\n );\n\n return [committed, capture] as const;\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { DataTableEditCommit, LedgerCellEditor, LedgerInstantEditingController } from \"./types\";\nimport type { CommittedTable } from \"./use-committed-table\";\n\n/**\n * The instant-apply controls' transient edits (docs/editing.md). An instant column never enters\n * edit mode — a change *is* the commit — so there is no session to open, hold a draft in, or\n * close. What a commit leaves behind still outlives the control that sent it: a write still out,\n * the failure it came back with, and the value the application now holds. Hiding the column, a\n * responsive breakpoint, or a virtual scroll unmounts that control at any moment, and none of\n * those are the write landing — so it lives here, and the control is a view of it.\n *\n * Addressed by target rather than by session: unlike cell mode, any number of controls can have\n * a write out at once, and each one's pending, failure and record are its own. Nested by row and\n * then column, never a joined key: row and column ids are opaque application strings, and any\n * separator is one an id may contain.\n */\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\n\nimport { editErrorMessage, normalizeEdit } from \"./edit-meta\";\nimport { isPromiseLike, useEventCallback } from \"./utils\";\n\nexport interface UseInstantEditingInput<TData extends RowData> {\n /**\n * Rows, definitions and the gate as the render that reached the screen left them — never the\n * cell's own table, which is the shared core (see `use-committed-table.ts`).\n */\n committed: CommittedTable;\n onEditCommit: ((change: DataTableEditCommit<TData>) => void | Promise<void>) | undefined;\n}\n\ninterface InstantTarget {\n /**\n * The write currently out. `moved` records that the data left what the write departed from\n * while it was still in flight — including leaving and coming back, which comparing once at\n * settle time could never see. `lost` records that the gate shut behind it: the write passed\n * before that and will still land, but the failure it may come back with has nowhere left to be\n * shown, and a gate that reopens is not a reprieve for it.\n */\n request: { token: number; value: unknown; source: unknown; moved: boolean; lost: boolean } | null;\n /**\n * What this target wrote, against what the data read when it went out. While it stands it is\n * what the cell holds — which is what the next commit departs from, so an application whose\n * data has not caught up is not asked to make the same change twice.\n */\n written: { value: unknown; source: unknown } | null;\n error: string | null;\n editors: Set<LedgerCellEditor>;\n}\n\ntype TargetStore = Map<string, Map<string, InstantTarget>>;\n\nfunction findTarget(store: TargetStore, rowId: string, columnId: string): InstantTarget | undefined {\n return store.get(rowId)?.get(columnId);\n}\n\n/**\n * The gate has shut on this target. There is no session to cancel — an instant commit is over\n * the moment it is sent — but the failure it was showing has nowhere left to be shown, and a\n * write still out must not bring one back when the gate reopens. Reports whether anything a\n * control shows changed.\n */\nfunction loseGate(target: InstantTarget): boolean {\n let touched = false;\n\n if (target.error !== null) {\n target.error = null;\n touched = true;\n }\n\n if (target.request) {\n target.request.lost = true;\n }\n\n return touched;\n}\n\nfunction redraw(target: InstantTarget): void {\n for (const editor of target.editors) {\n editor.redraw();\n }\n}\n\n/**\n * What the cell holds as far as the application is concerned.\n */\nfunction effectiveValue(target: InstantTarget | undefined, source: unknown): unknown {\n const record = target?.written;\n\n return record && Object.is(record.source, source) ? record.value : source;\n}\n\nexport function useInstantEditing<TData extends RowData>({\n committed,\n onEditCommit\n}: UseInstantEditingInput<TData>): LedgerInstantEditingController {\n const targets = useRef<TargetStore>(new Map());\n /**\n * One write, one token: only the request still standing for a target may act on it.\n */\n const tokenRef = useRef(0);\n\n const openTarget = (rowId: string, columnId: string): InstantTarget => {\n let columns = targets.current.get(rowId);\n\n if (!columns) {\n columns = new Map();\n targets.current.set(rowId, columns);\n }\n\n let target = columns.get(columnId);\n\n if (!target) {\n target = {\n editors: new Set(),\n error: null,\n request: null,\n written: null\n };\n columns.set(columnId, target);\n }\n\n return target;\n };\n\n /**\n * A target that has nothing left to remember and nothing on screen is not a target.\n */\n const dropIfEmpty = (rowId: string, columnId: string, target: InstantTarget) => {\n if (target.editors.size > 0 || target.request || target.written || target.error !== null) {\n return;\n }\n\n const columns = targets.current.get(rowId);\n\n columns?.delete(columnId);\n\n if (columns?.size === 0) {\n targets.current.delete(rowId);\n }\n };\n\n const settle = (rowId: string, columnId: string, token: number, message: string | null) => {\n const target = findTarget(targets.current, rowId, columnId);\n const request = target?.request;\n\n // Only the request still standing here may act: anything else was superseded, or belongs to a\n // target the data no longer holds.\n if (!target || !request || request.token !== token) {\n return;\n }\n\n target.request = null;\n\n if (message === null) {\n // Unless the data moved while the request was out — then what the application holds is its\n // own, and this write has nothing left to be true about.\n if (!request.moved) {\n target.written = { source: request.source, value: request.value };\n }\n } else if (!request.lost) {\n target.error = message;\n }\n\n redraw(target);\n dropIfEmpty(rowId, columnId, target);\n };\n\n const commit = useEventCallback((rowId: string, columnId: string, value: unknown): boolean | Promise<boolean> => {\n const row = committed.row(rowId);\n\n if (!row) {\n return false;\n }\n\n // Eligibility is re-read here, not trusted from the render that put this control on screen:\n // `edit.enabled` is application code, and nothing makes it answer the same way twice, so a\n // click can be the first thing to learn that the gate is shut. Both editing modes' commits\n // re-read it for exactly this reason (docs/architecture.md) — a change is a commit, and the\n // one path that skipped the check would write through a gate the application had closed, and\n // unvalidated besides, since a closed gate is what `validate` no longer guards. Asked before\n // anything is opened, so that a change which does not pass leaves nothing behind at all.\n if (!committed.canEdit(rowId, columnId)) {\n const shut = findTarget(targets.current, rowId, columnId);\n\n if (shut) {\n if (loseGate(shut)) {\n redraw(shut);\n }\n\n dropIfEmpty(rowId, columnId, shut);\n }\n\n return false;\n }\n\n const target = openTarget(rowId, columnId);\n\n // One write at a time per target: the control is disabled while its own is out, and a second\n // request would race the first to describe the same cell. Other targets are unaffected —\n // there is no shared session for them to join.\n if (target.request) {\n return false;\n }\n\n const source = committed.value(rowId, columnId);\n // What the application last knew, which after a write it has not fed back is that write —\n // not the data, which would ask it to make the same change twice.\n const previousValue = effectiveValue(target, source);\n\n target.error = null;\n\n const normalized = normalizeEdit(committed.edit(columnId));\n\n try {\n if (normalized?.validate) {\n const validationError = normalized.validate(value, row);\n\n if (validationError !== null) {\n target.error = validationError;\n redraw(target);\n\n return false;\n }\n }\n } catch (error) {\n target.error = editErrorMessage(error);\n redraw(target);\n\n return false;\n }\n\n let result: void | Promise<void>;\n\n try {\n result = onEditCommit?.({\n column: committed.column(columnId),\n previousValue,\n row,\n value\n } as DataTableEditCommit<TData>);\n } catch (error) {\n target.error = editErrorMessage(error);\n redraw(target);\n\n return false;\n }\n\n if (!isPromiseLike(result)) {\n target.written = { source, value };\n redraw(target);\n\n return true;\n }\n\n const token = ++tokenRef.current;\n target.request = {\n lost: false,\n moved: false,\n source,\n token,\n value\n };\n redraw(target);\n\n return Promise.resolve(result).then(\n () => {\n settle(rowId, columnId, token, null);\n\n return true;\n },\n (error: unknown) => {\n settle(rowId, columnId, token, editErrorMessage(error));\n\n return false;\n }\n );\n });\n\n /**\n * Reconciles every target with the table it lives in. Two things move under a transient edit:\n * the data can leave what a write departed from — the record retires for good, so data that\n * later returns to it cannot bring the value back with it — and the gate can shut, which takes\n * the control off the screen and with it any failure it was showing.\n *\n * Passive, not layout: nothing has to be keyed before a control can be used. No dependency\n * array, because what it watches is `enableEditing`, the column definitions and every target's\n * own data at once — nothing a list describes.\n */\n useEffect(() => {\n // Iterated live: `dropIfEmpty` deletes from these maps as it goes, which a Map iterator is\n // defined to tolerate — an entry removed before it is reached is simply not visited.\n for (const [rowId, columns] of targets.current) {\n for (const [columnId, target] of columns) {\n const row = committed.row(rowId);\n let touched = false;\n\n if (row) {\n const source = committed.value(rowId, columnId);\n\n if (target.written && !Object.is(target.written.source, source)) {\n target.written = null;\n touched = true;\n }\n\n // The same watch, for the write still out: it has no record to retire yet, so the\n // movement has to be remembered until it does.\n if (target.request && !Object.is(target.request.source, source)) {\n target.request.moved = true;\n }\n }\n\n // A row the table does not hold has not arrived, or the data no longer holds it. Neither\n // is an application shutting a gate; the table-level one — the switch and the mode's\n // commit handler — is, either way, and is answered without needing the row at all.\n const eligible = committed.tableGate() && (row === null || committed.canEdit(rowId, columnId));\n\n if (!eligible) {\n touched = loseGate(target) || touched;\n }\n\n if (touched) {\n redraw(target);\n }\n\n dropIfEmpty(rowId, columnId, target);\n }\n }\n });\n\n // Stable identities all the way out: this surface goes into `meta.ledger`, which the render\n // layer memoizes against. Each of these reads nothing but refs.\n const value = useCallback(\n (rowId: string, columnId: string, source: unknown) => effectiveValue(findTarget(targets.current, rowId, columnId), source),\n []\n );\n const pending = useCallback((rowId: string, columnId: string) => Boolean(findTarget(targets.current, rowId, columnId)?.request), []);\n const error = useCallback((rowId: string, columnId: string) => findTarget(targets.current, rowId, columnId)?.error ?? null, []);\n\n /**\n * A control registers while it is on screen, so the target it belongs to can tell it to draw\n * what it now holds. Bound to the controller and the cell, not to the component's lifetime: in\n * hook mode the table can be swapped for another instance while React keeps this control.\n */\n const register = useCallback((rowId: string, columnId: string, editor: LedgerCellEditor) => {\n openTarget(rowId, columnId).editors.add(editor);\n\n return () => {\n const target = findTarget(targets.current, rowId, columnId);\n\n if (!target) {\n return;\n }\n\n target.editors.delete(editor);\n dropIfEmpty(rowId, columnId, target);\n };\n }, []);\n\n return useMemo(\n () => {\n return {\n commit,\n error,\n pending,\n register,\n value\n };\n },\n [commit, error, pending, register, value]\n );\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type { ColumnDef } from \"./types\";\n\n/**\n * Breakpoint-driven column presence (`meta.hiddenFrom` / `meta.visibleFrom`, the host's own\n * `Box` vocabulary): a hidden column is removed from the definitions before TanStack sees\n * them, so the width engine, the colgroup, and the columns panel all follow — column state\n * keyed by id (`columnVisibility`, persistence) is untouched and reapplies when the column\n * returns.\n *\n * Breakpoint values resolve from Mantine's published CSS variables\n * (`--mantine-breakpoint-*`), falling back to the stock scale — no theme-context dependency,\n * so hook mode works wherever `useDataTable` does. Without `matchMedia` (SSR, jsdom) every\n * column stays visible.\n */\nimport { useEffect, useMemo, useState } from \"react\";\n\nconst STOCK_BREAKPOINTS: Record<string, string> = {\n xs: \"36em\",\n sm: \"48em\",\n md: \"62em\",\n lg: \"75em\",\n xl: \"88em\"\n};\n\nfunction breakpointValue(breakpoint: string): string {\n if (typeof document !== \"undefined\") {\n const fromTheme = getComputedStyle(document.documentElement)\n .getPropertyValue(`--mantine-breakpoint-${breakpoint}`)\n .trim();\n\n if (fromTheme !== \"\") {\n return fromTheme;\n }\n }\n\n return STOCK_BREAKPOINTS[breakpoint] ?? breakpoint;\n}\n\nfunction collectBreakpoints<TData extends RowData>(columns: Array<ColumnDef<TData, any>>, into: Set<string>): void {\n for (const column of columns) {\n if (\"columns\" in column && Array.isArray(column.columns)) {\n collectBreakpoints(column.columns, into);\n continue;\n }\n\n if (column.meta?.hiddenFrom) {\n into.add(column.meta.hiddenFrom);\n }\n\n if (column.meta?.visibleFrom) {\n into.add(column.meta.visibleFrom);\n }\n }\n}\n\nfunction filterColumns<TData extends RowData>(\n columns: Array<ColumnDef<TData, any>>,\n matches: Record<string, boolean>\n): Array<ColumnDef<TData, any>> {\n const result: Array<ColumnDef<TData, any>> = [];\n\n for (const column of columns) {\n if (\"columns\" in column && Array.isArray(column.columns)) {\n const children = filterColumns(column.columns, matches);\n\n // A group whose every child is off-breakpoint disappears with them.\n if (children.length > 0) {\n result.push(children === column.columns\n ? column\n // The ledger alias re-attaches `enableResizing`, which the group's TanStack-typed\n // `columns` slot does not carry — the assertion re-enters the alias.\n : { ...column, columns: children } as ColumnDef<TData, any>);\n }\n\n continue;\n }\n\n const { hiddenFrom, visibleFrom } = column.meta ?? {};\n\n // Host semantics: hiddenFrom hides AT AND ABOVE the breakpoint, visibleFrom shows only\n // there. An unknown match (no matchMedia) resolves to visible.\n if (hiddenFrom && matches[hiddenFrom] === true) {\n continue;\n }\n\n if (visibleFrom && matches[visibleFrom] === false) {\n continue;\n }\n\n result.push(column);\n }\n\n return result;\n}\n\nexport function useResponsiveColumns<TData extends RowData>(\n columns: Array<ColumnDef<TData, any>>\n): Array<ColumnDef<TData, any>> {\n // Serialized, not joined: a breakpoint is any CSS length the author writes, and the ones with\n // commas in them are ordinary (`clamp(30em, 50vw, 60em)`). A separator inside a value would\n // split one breakpoint into several nonsense media queries, none of which ever match.\n const breakpointsKey = useMemo(() => {\n const used = new Set<string>();\n collectBreakpoints(columns, used);\n\n return used.size === 0 ? \"\" : JSON.stringify([...used].toSorted());\n }, [columns]);\n\n const [matches, setMatches] = useState<Record<string, boolean>>({});\n\n useEffect(() => {\n if (breakpointsKey === \"\" || typeof matchMedia !== \"function\") {\n setMatches(previous => Object.keys(previous).length === 0 ? previous : {});\n\n return;\n }\n\n const queries = (JSON.parse(breakpointsKey) as string[]).map(breakpoint => {\n const query = matchMedia(`(min-width: ${breakpointValue(breakpoint)})`);\n const apply = () => setMatches(previous => previous[breakpoint] === query.matches\n ? previous\n : { ...previous, [breakpoint]: query.matches });\n\n apply();\n query.addEventListener(\"change\", apply);\n\n return { query, apply };\n });\n\n return () => {\n for (const { query, apply } of queries) {\n query.removeEventListener(\"change\", apply);\n }\n };\n }, [breakpointsKey]);\n\n return useMemo(() => {\n if (breakpointsKey === \"\") {\n return columns;\n }\n\n const filtered = filterColumns(columns, matches);\n\n // Identity-preserving when nothing is filtered out, so downstream memos stay cold.\n return filtered.length === columns.length && filtered.every((column, index) => column === columns[index])\n ? columns\n : filtered;\n }, [columns, matches, breakpointsKey]);\n}\n","import type { ExpandedState, RowData, RowSelectionState } from \"@tanstack/react-table\";\n\nimport type { SelectionRules } from \"./toggle-fns\";\nimport type { Row, TableInstance } from \"./types\";\nimport type { SliceSetter } from \"./use-slice\";\n\n/**\n * Selection and expansion, answered from the render that reached the screen.\n *\n * Both features decide half of a toggle outside the updater they hand the state setter, and that\n * half reads the shared core (`toggle-fns.ts`). So the controls call these controllers instead:\n * the row objects, the display order and the rules all come from a snapshot taken in an\n * **insertion effect** — the commit phase — and the write goes through the stable slice setter,\n * whose own updater still resolves against the committed value.\n *\n * The controllers are stable for the life of the instance, which is what lets a cell reach one\n * through whatever route it has (a context field, `meta.ledger`) without that route deciding\n * anything.\n */\nimport { useCallback, useMemo, useRef } from \"react\";\n\nimport {\n nextAllSelection,\n nextExpanded,\n nextPageSelection,\n nextRangeSelection,\n nextRowSelection\n} from \"./toggle-fns\";\n\nexport interface LedgerSelectionController {\n /**\n * One checkbox. `range` is the modifier the event carried — a Shift range departs from the\n * last row this table toggled and covers the display order on screen.\n */\n toggle: (row: Row<any>, checked: boolean, range: boolean) => void;\n toggleAll: (scope: \"page\" | \"all\", value: boolean) => void;\n}\n\nexport interface LedgerExpansionController {\n /**\n * `expanded` and `canExpand` are the drawing render's answers — what the chevron shows is what\n * clicking it departs from.\n */\n toggle: (rowId: string, expanded: boolean, canExpand: boolean) => void;\n toggleAll: (value: boolean, canSomeExpand: boolean) => void;\n}\n\ninterface RowSnapshot {\n /**\n * `getRowsInDisplayOrder()` — what a Shift range walks and what `getDisplayIndex` counts.\n */\n displayOrder: Array<Row<any>>;\n pageRows: Array<Row<any>>;\n /**\n * The pre-grouped flat rows a select-all over every row visits.\n */\n flatRows: Array<Row<any>>;\n rowsById: Record<string, Row<any>>;\n /**\n * Resolved on demand: only an `expanded === true` table has to materialize the map, and a\n * per-commit walk of every row would be O(rows) on a table sized for virtualization.\n */\n expandableRowIds: () => string[];\n rules: SelectionRules;\n rangeEnabled: boolean;\n}\n\nconst ALWAYS = () => true;\n\nconst EMPTY: RowSnapshot = {\n displayOrder: [],\n expandableRowIds: () => [],\n flatRows: [],\n pageRows: [],\n rangeEnabled: true,\n rowsById: {},\n rules: {\n canMultiSelect: ALWAYS,\n canSelect: ALWAYS,\n canSelectSubRows: ALWAYS\n }\n};\n\n/**\n * `boolean | (row) => boolean | undefined`, resolved once against the committed options.\n */\nfunction rule(option: unknown): (row: Row<any>) => boolean {\n if (typeof option === \"function\") {\n return row => (option as (row: Row<any>) => boolean)(row) === true;\n }\n\n return () => option !== false;\n}\n\nexport type CaptureRows<TData extends RowData> = (table: TableInstance<TData>) => void;\n\nexport function useRowCommands<TData extends RowData>(\n setRowSelection: SliceSetter<RowSelectionState>,\n setExpanded: SliceSetter<ExpandedState>\n): readonly [LedgerSelectionController, LedgerExpansionController, CaptureRows<TData>] {\n const snapshot = useRef<RowSnapshot>(EMPTY);\n /**\n * The Shift anchor. v9 keeps it on the core instance (`_lastSelectedRowId`), which is the one\n * object a discarded render also writes.\n */\n const anchorId = useRef<string | null>(null);\n\n const capture = useCallback<CaptureRows<TData>>(table => {\n const { options } = table;\n const canExpand = (row: Row<any>): boolean => options.getRowCanExpand?.(row as never) ?? ((options.enableExpanding ?? true) && row.subRows.length > 0);\n const rowModelRows = table.getRowModel().rowsById as Record<string, Row<any>>;\n\n // Every read here is an identity check on a memoized answer, so a commit costs O(1). The\n // display order in particular is memoized upstream on the three things that move it — the\n // pre-paginated rows, `paginateExpandedRows`, and `expanded` in the mode that interleaves\n // descendants — so an unrelated state tick never walks the rows (a guardrail test pins it).\n snapshot.current = {\n displayOrder: table.getRowsInDisplayOrder() as Array<Row<any>>,\n expandableRowIds: () => Object.values(rowModelRows).filter(row => canExpand(row)).map(row => row.id),\n flatRows: table.getPreGroupedRowModel().flatRows as Array<Row<any>>,\n pageRows: table.getRowModel().rows as Array<Row<any>>,\n rangeEnabled: options.enableRowRangeSelection !== false,\n rowsById: table.getCoreRowModel().rowsById as Record<string, Row<any>>,\n rules: {\n canMultiSelect: rule(options.enableMultiRowSelection),\n canSelect: rule(options.enableRowSelection),\n canSelectSubRows: rule(options.enableSubRowSelection)\n }\n };\n }, []);\n\n const selection = useMemo<LedgerSelectionController>(\n () => {\n return {\n toggle: (row, checked, range) => {\n const {\n displayOrder,\n rules,\n rangeEnabled\n } = snapshot.current;\n\n if (!rules.canSelect(row)) {\n return;\n }\n\n const anchor = anchorId.current;\n const anchorIndex = anchor === null ? -1 : displayOrder.findIndex(candidate => candidate.id === anchor);\n const rowIndex = displayOrder.findIndex(candidate => candidate.id === row.id);\n const rangeRow = displayOrder[rowIndex];\n\n // Both endpoints must still be in the order on screen and both must accept company,\n // or the interaction falls back to an ordinary toggle — v9's own conditions.\n const asRange\n = range\n && rangeEnabled\n && anchorIndex !== -1\n && rowIndex !== -1\n && rangeRow !== undefined\n && rules.canMultiSelect(displayOrder[anchorIndex] as Row<any>)\n && rules.canMultiSelect(row);\n\n if (asRange) {\n setRowSelection(previous => nextRangeSelection(\n previous,\n displayOrder,\n {\n anchorIndex,\n rowIndex,\n value: checked\n },\n rules\n ));\n } else {\n setRowSelection(previous => nextRowSelection(previous, row, checked, rules));\n }\n\n anchorId.current = row.id;\n },\n toggleAll: (scope, value) => {\n const {\n pageRows,\n flatRows,\n rowsById,\n rules\n } = snapshot.current;\n anchorId.current = null;\n\n setRowSelection(previous => scope === \"page\"\n ? nextPageSelection(previous, pageRows, value, rules)\n : nextAllSelection(previous, flatRows, rowsById, value, rules));\n }\n };\n },\n [setRowSelection]\n );\n\n const expansion = useMemo<LedgerExpansionController>(\n () => {\n return {\n toggle: (rowId, expanded, canExpand) => {\n const target = !expanded;\n\n if (target && !canExpand) {\n return;\n }\n\n setExpanded(previous => nextExpanded(previous, rowId, target, snapshot.current.expandableRowIds));\n },\n toggleAll: (value, canSomeExpand) => {\n if (value && !canSomeExpand) {\n return;\n }\n\n setExpanded(() => value ? true : Object.create(null) as ExpandedState);\n }\n };\n },\n [setExpanded]\n );\n\n return [selection, expansion, capture] as const;\n}\n","import type { RowData } from \"@tanstack/react-table\";\n\nimport type {\n DataTableRowEditCommit,\n LedgerRowEditingController,\n LedgerRowEditor,\n Row\n} from \"./types\";\nimport type { CommittedTable } from \"./use-committed-table\";\n\n/**\n * The row-mode editing session (docs/editing.md#row-mode). The third of the three sessions, and\n * the same shape as the other two: everything the row's editors show, and everything its atomic\n * commit decides with, lives here rather than in the editors — a hidden column or a virtual\n * scroll unmounts an editor at any moment, and a session is not (docs/architecture.md).\n *\n * What is particular to row mode: one commit covers every editable column at once, so the drafts\n * are a store rather than a single value, and the baseline the commit departs from is snapshotted\n * when the row opens — a responsive breakpoint can take a column out of the definitions before\n * commit time, leaving no cell to read a previous value from.\n */\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\n\nimport { editErrorMessage, normalizeEdit } from \"./edit-meta\";\nimport { useEventCallback } from \"./utils\";\n\nexport interface UseRowEditingInput<TData extends RowData> {\n editingRowId: string | null;\n setEditingRowId: (rowId: string | null) => void;\n /**\n * Rows, definitions and the gate as the render that reached the screen left them. Everything a\n * commit decides with comes from here rather than from the cell's own table, which is the shared\n * core and carries whatever pass ran last (see `use-committed-table.ts`).\n */\n committed: CommittedTable;\n onRowEditCommit: ((change: DataTableRowEditCommit<TData>) => void | Promise<void>) | undefined;\n}\n\n/**\n * The controller's surface minus `id`, which is the slice itself and belongs to whoever owns it.\n * Declared as the public contract minus that one key so the two cannot drift apart.\n */\nexport type RowEditingSession = Omit<LedgerRowEditingController, \"id\">;\n\nexport function useRowEditing<TData extends RowData>({\n committed,\n editingRowId,\n onRowEditCommit,\n setEditingRowId\n}: UseRowEditingInput<TData>): RowEditingSession {\n // Drafts live here, not in editors: a virtualized editing row that scrolls out unmounts its\n // editors, and the pending values must survive until the atomic commit.\n const rowDrafts = useRef<{\n rowId: string | null;\n values: Map<string, unknown>;\n /**\n * Every editable column's value as the row's edit began, or null while the row itself is\n * not in the table yet — see `openRowDrafts`.\n */\n baseline: Map<string, unknown> | null;\n /**\n * What this session has already written, per column, against the value the data held when\n * it went out — see `previousRowValue`.\n */\n committed: Map<string, { value: unknown; source: unknown }>;\n /**\n * Eligibility was lost during this session. It latches: a gate that reopens before an\n * in-flight write settles is the *next* session's eligibility, not a reprieve for this one.\n */\n gateLost: boolean;\n /**\n * The automatic reconciliation has already answered this session's gate closing.\n */\n reconciled: boolean;\n /**\n * The write currently out, per column, and whether the data has moved since it left. A record\n * is only true while the data has not moved past it, and the moving can happen *during* the\n * request — including out and back again, which comparing at settle time could never see.\n */\n writing: Map<string, { source: unknown; moved: boolean }> | null;\n }>({\n rowId: null,\n values: new Map(),\n baseline: new Map(),\n committed: new Map(),\n gateLost: false,\n reconciled: false,\n writing: null\n });\n const rowEditors = useRef(new Map<string, LedgerRowEditor>());\n /**\n * Bumped whenever a row session starts or ends without the slice moving — a gate shutting under\n * a controlled application that declines to close it, or an explicit start on the row already\n * named. Whether an editor may be on screen is part of the render output, so a change in it has\n * to be a change in state; a ref would leave the last render standing.\n */\n const [rowSessionEpoch, setRowSessionEpoch] = useState(0);\n /**\n * What the row's editors show that is not a value: a write still out, and the reason the last\n * one failed. Session state, not editor state — an editor is unmounted by a hidden column or a\n * virtual scroll at any moment, and one that came back knowing neither would take input during\n * a write and let the user send a second one, while a rejection arriving with no editor mounted\n * would have had nowhere to go at all.\n */\n const rowPresentation = useRef<{\n pending: boolean;\n /**\n * `columnId: null` is the row's own failure — a rejected commit belongs to no cell, and which\n * column shows it is decided when an editor renders (`rowErrorColumnId`).\n */\n error: { columnId: string | null; message: string } | null;\n }>({\n error: null,\n pending: false\n });\n const rowFocusColumn = useRef<string | null>(null);\n const editingRowRef = useRef(editingRowId);\n /**\n * One editing session, one token. An async commit captures it and may only act on what it\n * finds afterwards if the token still matches: cancelling the row, finishing it, or opening\n * another one all end the session, and a settled request from the previous one must not close\n * the editor that replaced it (nor report its error onto that editor's first field).\n */\n const rowSessionRef = useRef(0);\n /**\n * The in-flight row commit, so repeated `stopEditing({ commit: true })` calls wait on one\n * result instead of firing `onRowEditCommit` again — the single-flight guarantee cell mode\n * already makes (docs/editing.md). It carries its owner: a request belonging to a session\n * that has ended is not a request the next row may join, or its own write would never be sent.\n */\n const rowPendingCommit = useRef<{ session: number; rowId: string; promise: Promise<boolean> } | null>(null);\n const rowStartRequestRef = useRef(0);\n\n /**\n * Ends the session: whatever is in flight stops owning the row, and stops speaking for it.\n */\n const endRowSession = () => {\n rowSessionRef.current += 1;\n rowPendingCommit.current = null;\n };\n\n /**\n * Every editable value of `rowId` as it stands now, or null while that row is not in the\n * table: an application can name the row it wants edited before the fetch carrying it lands,\n * and \"this row has no previous values\" is a different answer from \"there is no row to ask\".\n */\n const snapshotEditableValues = (rowId: string): Map<string, unknown> | null => {\n if (committed.row(rowId) === null) {\n return null;\n }\n\n const baseline = new Map<string, unknown>();\n\n for (const columnId of committed.columnIds()) {\n if (committed.canEdit(rowId, columnId)) {\n baseline.set(columnId, committed.value(rowId, columnId));\n }\n }\n\n return baseline;\n };\n\n /**\n * Opens the draft store on a row. The baseline is snapshotted now, while every editable\n * column still exists: a responsive breakpoint removes a column from the definitions before\n * TanStack ever sees it, so by commit time its cell is gone and there is nothing left to read\n * a previous value from. A row the table does not hold yet leaves the baseline unrecorded for\n * the effect below to take once it arrives.\n */\n const openRowDrafts = (rowId: string | null) => {\n rowDrafts.current = {\n rowId,\n values: new Map(),\n baseline: rowId === null ? new Map() : snapshotEditableValues(rowId),\n committed: new Map(),\n gateLost: false,\n reconciled: false,\n writing: null\n };\n rowPresentation.current = { error: null, pending: false };\n };\n\n /**\n * The drafts held for `rowId`. A read, never a write: editors read their draft while\n * rendering, and a render can be thrown away (a transition that suspends), so re-keying the\n * store from here would let an abandoned render erase the values on screen. The effect below\n * is the store's only keyer. A caller asking about another row gets nothing, which is the\n * truth.\n */\n const draftsFor = (rowId: string | null): Map<string, unknown> => rowDrafts.current.rowId === rowId ? rowDrafts.current.values : new Map();\n\n /**\n * What the application last knew this column to hold — the value the row is editing away from.\n * A session can outlive its own writes: a controlled application may decline to close the row,\n * and the data it feeds back arrives whenever it arrives. Until then `source` — what the cell\n * read when the write went out — still matches, and the value written is the newer truth. Once\n * the data moves, it wins: it may be our write applied, normalised, or somebody else's.\n */\n const previousRowValue = (columnId: string, source: unknown): unknown => {\n const written = rowDrafts.current.committed.get(columnId);\n\n return written && Object.is(written.source, source) ? written.value : source;\n };\n\n /**\n * Takes back the pending values a write actually carried, leaving anything typed since. What it\n * carried is recorded as committed instead; a draft left standing over it would go on beating\n * the data the application feeds back — including a value it normalized on the way in.\n */\n const consumeCommittedRowDrafts = (rowId: string, sent: Record<string, unknown>) => {\n if (rowDrafts.current.rowId !== rowId) {\n return;\n }\n\n for (const [columnId, value] of rowDrafts.current.values) {\n if (Object.hasOwn(sent, columnId) && Object.is(value, sent[columnId])) {\n rowDrafts.current.values.delete(columnId);\n }\n }\n };\n\n /**\n * Records a write that went through, so the next commit departs from it rather than from data\n * that has not caught up. The entry is retired by `reconcileRowEligibility` the moment the data\n * moves — see `previousRowValue`.\n */\n const recordRowCommit = (rowId: string, values: Record<string, unknown>, sources: Map<string, unknown>) => {\n if (rowDrafts.current.rowId !== rowId) {\n return;\n }\n\n const { writing } = rowDrafts.current;\n\n for (const [columnId, value] of Object.entries(values)) {\n // A column whose data moved while the request was out has nothing for this write to still\n // be true about: what the application holds there is its own.\n if (writing?.get(columnId)?.moved === true) {\n rowDrafts.current.committed.delete(columnId);\n\n continue;\n }\n\n rowDrafts.current.committed.set(columnId, { value, source: sources.get(columnId) });\n }\n\n rowDrafts.current.writing = null;\n };\n\n /**\n * Whether the row holds a value the write that just settled never carried. A custom editor is\n * not disabled while a request is out, so the user can type straight past it; leaving on that\n * write's word would drop what they typed.\n */\n const hasUncommittedRowEdits = (rowId: string, sent: Record<string, unknown>): boolean => {\n if (rowDrafts.current.rowId !== rowId) {\n return false;\n }\n\n for (const [columnId, value] of rowDrafts.current.values) {\n if (!Object.hasOwn(sent, columnId) || !Object.is(value, sent[columnId])) {\n return true;\n }\n }\n\n return false;\n };\n\n /**\n * Throws the whole pending edit away — what cancelling means. The mounted editors are put back\n * alongside the store because the row can stay on screen: a controlled application may decline\n * to close it, and an editor still showing a value the store no longer holds is one nothing\n * would commit. What they show once the store is empty is the store's answer again — the value\n * the session has written, or the data — so they are only asked to draw themselves anew.\n */\n const discardRowEdits = (rowId: string | null) => {\n if (rowId === null || rowDrafts.current.rowId !== rowId) {\n return;\n }\n\n rowDrafts.current.values.clear();\n rowPresentation.current.error = null;\n\n for (const editor of rowEditors.current.values()) {\n editor.redraw();\n }\n };\n\n /**\n * Asks for the row edit to end. A request, not the ending itself: `editingRowId` is a\n * controlled slice, and an application may answer `onEditingRowIdChange` by leaving the prop\n * exactly where it was. The row then stays on screen, and a row on screen is one the user can\n * still type into — so the session, its ownership of an in-flight commit, and the draft store\n * all stay with it until a render says otherwise.\n */\n const finishRowEditing = useEventCallback(() => {\n rowFocusColumn.current = null;\n setEditingRowId(null);\n });\n\n /**\n * Reconciles the session with the row that actually reached the screen. Every change of\n * `editingRowId` lands here, ledger's own requests included, because it is a controlled\n * slice: `startRowEditing` and `finishRowEditing` can only ask, and an application may move\n * the edit itself, answer with a different row, or decline to move it at all. Committing the\n * boundary anywhere else would leave the session speaking for a row nobody is editing.\n *\n * It is a layout effect and not a render-phase check because ending a session is a real side\n * effect — it invalidates an in-flight commit's ownership — and React may render a tree it\n * never commits (a transition that suspends). Refs are shared between the current tree and\n * the work-in-progress one, so a render for a row the user never saw would otherwise strand\n * the row still on screen: its commit disowned, its editors pending forever. Layout, not\n * passive: the drafts store has to be keyed before anything can be typed into it.\n *\n * No dependency array on purpose. The comparison is against what was committed last time,\n * which no dependency list describes.\n */\n useLayoutEffect(() => {\n const moved = editingRowRef.current !== editingRowId;\n\n if (moved) {\n endRowSession();\n\n if (editingRowId !== null) {\n // A `startRowEditing` still waiting on a commit was going to open a row, and the edit\n // has landed on a different one — that request is overruled. Landing on *no* row is the\n // ordinary end of the very commit it is waiting for, and must not cancel it.\n rowStartRequestRef.current += 1;\n }\n\n editingRowRef.current = editingRowId;\n }\n\n if (moved || rowDrafts.current.rowId !== editingRowId) {\n // The second test also catches the first pass, where the ref already agrees with the prop\n // but the store has never been keyed: a controlled row open from the very first render\n // still needs its baseline, and the table instance only exists once the hook body has run.\n openRowDrafts(editingRowId);\n } else if (editingRowId !== null && rowDrafts.current.baseline === null) {\n // The row was not in the table when the edit opened. Data arriving later is the first\n // chance to record what the user is editing away from; anything typed meanwhile stays.\n rowDrafts.current.baseline = snapshotEditableValues(editingRowId);\n }\n });\n\n /**\n * Reconciles the row being edited with the table it lives in. Three things can move under an\n * open row, and only one of them ends it:\n *\n * - the data moves past a value this session wrote — the overlay entry retires for good, so\n * data that later returns to what the write departed from cannot bring our value back with\n * it (`previousRowValue` tests the same thing, for the reads that happen before this runs);\n * - a column's gate shuts (`meta.edit` removed, `edit.enabled(row)` turning false) — its\n * pending value goes now rather than at commit time, so a gate that reopens cannot bring back\n * a draft nothing was showing;\n * - a column simply leaves the definitions, a responsive breakpoint crossing — nothing shut,\n * the layout changed, and its draft still commits against the baseline (docs/editing.md).\n *\n * So the row ends when the table switch is off, or when the gate shut on a column this session\n * was editing and none is left editable. A row the table does not hold yet has not arrived,\n * which is not the same as a row that may not be edited.\n *\n */\n const markRowGateLost = () => {\n if (rowDrafts.current.gateLost) {\n return;\n }\n\n rowDrafts.current.gateLost = true;\n setRowSessionEpoch(epoch => epoch + 1);\n };\n\n /**\n * Cancels the session: what it holds is discarded — it never passed a gate — and the close is\n * asked for.\n */\n const cancelLostRowSession = (rowId: string) => {\n rowDrafts.current.reconciled = true;\n discardRowEdits(rowId);\n finishRowEditing();\n };\n\n /**\n * Ends a session whose eligibility is gone, once nothing is still out on its behalf. Returns\n * whether it ended the row: a session that stops because the gate shut was cancelled, not\n * finished, so nothing waiting on a commit may move on the strength of it.\n */\n const endLostRowSession = (rowId: string): boolean => {\n if (!rowDrafts.current.gateLost) {\n return false;\n }\n\n // The write already out passed the gate before it shut; its settlement calls this again and\n // completes the cancel. The loss is recorded either way, so a gate reopening cannot undo it.\n if (rowPendingCommit.current) {\n return false;\n }\n\n // Once per session. This runs after every render, and an application that ignores the close\n // would otherwise be asked again on each one — reconciliation, not nagging. An explicit stop\n // or start goes its own way and is always a fresh request.\n if (rowDrafts.current.reconciled) {\n return false;\n }\n\n cancelLostRowSession(rowId);\n\n return true;\n };\n\n const reconcileRowEligibility = useEventCallback((): boolean => {\n const rowId = editingRowRef.current;\n\n if (rowId === null) {\n return false;\n }\n\n // The table-level gate — the switch and the mode's commit handler — is answered before the row\n // is even looked for. A session opened on a row whose data has not arrived would otherwise\n // survive it closing, and one that reopened before the data landed would find the old session\n // waiting.\n if (!committed.tableGate()) {\n markRowGateLost();\n }\n\n const row = committed.row(rowId);\n\n if (!row) {\n // Not in the table: a row that has not arrived, or one the data no longer holds. Neither is\n // a gate closing, so the session stands — but a switch that shut above still ends it.\n return endLostRowSession(rowId);\n }\n\n const { baseline } = rowDrafts.current;\n let editable = false;\n let gateShut = false;\n\n for (const columnId of committed.columnIds()) {\n const source = committed.value(rowId, columnId);\n const written = rowDrafts.current.committed.get(columnId);\n\n if (written && !Object.is(written.source, source)) {\n rowDrafts.current.committed.delete(columnId);\n }\n\n // The same watch, for a write still out: it has no record to retire yet, so the movement\n // has to be remembered until it does.\n const writing = rowDrafts.current.writing?.get(columnId);\n\n if (writing && !Object.is(writing.source, source)) {\n writing.moved = true;\n }\n\n if (committed.canEdit(rowId, columnId)) {\n editable = true;\n\n // The last effective previous this session saw for the column, refreshed while it is\n // here to be seen: `previousValues` means what the application last knew, and a column\n // whose definition later disappears has nothing else left to answer with. Recording it\n // on every sighting also gives the session its membership — which is how a gate shutting\n // on a column it was editing is told apart from a breakpoint taking one away.\n baseline?.set(columnId, previousRowValue(columnId, source));\n } else {\n gateShut ||= baseline?.has(columnId) ?? false;\n rowDrafts.current.values.delete(columnId);\n }\n }\n\n // What keeps a row editing: a cell it can edit now, or values it still owes a commit for a\n // column whose *definition* left — a breakpoint crossing, which shut no gate. A gate really\n // shutting on a column this session was editing ends it, and so does a session that never had\n // anything to edit at all (no `meta.edit`, or no handler for the mode).\n if (!(editable || (!gateShut && (baseline?.size ?? 0) > 0))) {\n markRowGateLost();\n }\n\n return endLostRowSession(rowId);\n });\n\n /**\n * Passive, not layout: nothing has to be keyed before the user can type, and this must not race\n * the session boundary above. No dependency array, because what it watches is `enableEditing`,\n * the column definitions and the row's own data at once — nothing a list describes.\n */\n useEffect(() => {\n reconcileRowEligibility();\n });\n\n /**\n * Whether the request issued under `session` still speaks for `rowId`. Sessions end the moment\n * the rendered row changes, so the two tests agree by construction; the row id is spelled out\n * because acting on another row's editors is precisely what a stale settlement must not do.\n */\n const isCurrentRowSession = (session: number, rowId: string) => rowSessionRef.current === session && editingRowRef.current === rowId;\n\n /**\n * The column currently showing the row's failure: the one it names, or for a row-level failure\n * the first editable column with an editor on screen, in the row's own cell order. Resolved on\n * every read rather than fixed when the failure is reported, so a message follows the screen\n * when the column under it is hidden or scrolls away.\n */\n const rowErrorColumnId = (rowId: string): string | null => {\n const { error } = rowPresentation.current;\n\n if (!error) {\n return null;\n }\n\n if (error.columnId !== null) {\n return error.columnId;\n }\n\n return committed\n .columnIds()\n .find(columnId => committed.canEdit(rowId, columnId) && rowEditors.current.has(columnId)) ?? null;\n };\n\n // Stable, and reads nothing but refs — so `registerRowEditor` can close over it directly rather\n // than through a mirror written during render, which is the very thing this round forbade.\n const redrawRowEditors = useCallback(() => {\n for (const editor of rowEditors.current.values()) {\n editor.redraw();\n }\n }, []);\n\n /**\n * Only a row-level failure is projected onto whoever is on screen, so only that has to be\n * redrawn when the registry changes; everything else an editor shows it already reads for\n * itself as it renders.\n */\n const redrawRowLevelError = useCallback(() => {\n if (rowPresentation.current.error?.columnId === null) {\n redrawRowEditors();\n }\n }, [redrawRowEditors]);\n\n const setRowPending = (pending: boolean) => {\n rowPresentation.current.pending = pending;\n redrawRowEditors();\n };\n\n /**\n * Records a failure on the session, so it outlives the editors: one that is unmounted when the\n * message arrives shows it when it comes back. `columnId: null` is the row's own — a rejected\n * commit belongs to no cell.\n */\n const reportRowError = (rowId: string, columnId: string | null, message: string) => {\n rowPresentation.current.error = { columnId, message };\n redrawRowEditors();\n\n const shown = rowErrorColumnId(rowId);\n\n if (shown !== null) {\n rowEditors.current.get(shown)?.focus();\n }\n };\n\n const commitRow = useEventCallback((): boolean | Promise<boolean> => {\n const rowId = editingRowRef.current;\n\n if (rowId === null) {\n return true;\n }\n\n // Idempotent while pending: a second Enter, a blur behind it, or the application calling\n // `stopEditing` again all join the request already in flight rather than issuing another\n // write. Only the owner may join — a request left over from a row the controller has moved\n // on from would otherwise stand in for this row's write, which would then never be sent.\n const inFlight = rowPendingCommit.current;\n\n if (inFlight && inFlight.session === rowSessionRef.current && inFlight.rowId === rowId) {\n return inFlight.promise;\n }\n\n // Eligibility is re-read here, not trusted from when the session opened: `enableEditing` can\n // switch off, `meta.edit` can be removed, and `edit.enabled(row)` — application code, which\n // nothing makes answer the same way twice — can turn false with no render in between, which\n // makes this commit the first thing to learn of it. The same reconciliation the effect runs,\n // so the table-level switch, a gate closing on a column this session was editing, and a\n // breakpoint merely taking a column away are told apart exactly once, in one place.\n //\n // A session cancelled that way did not finish: what it held never passed a gate and is\n // discarded rather than promoted (a draft whose column also left the definitions has no cell\n // left to test it against, and the baseline path below would otherwise reconstruct and send\n // it), and nothing waiting to move may proceed on the strength of it.\n const cancelledNow = reconcileRowEligibility();\n\n if (rowDrafts.current.gateLost) {\n if (!cancelledNow) {\n // Reconciliation is once per session; a command is not. An owner that declined the close\n // still has this row on screen, so it is asked again.\n cancelLostRowSession(rowId);\n }\n\n return false;\n }\n\n const row = committed.row(rowId);\n\n if (!row) {\n // The row left the data set mid-edit — there is nothing to commit onto.\n finishRowEditing();\n return true;\n }\n\n rowPresentation.current.error = null;\n redrawRowEditors();\n\n // Every editable column, not just the visible ones (docs/api.md: \"every editable column,\n // drafts merged in\"). Hiding a column mid-edit — the columns panel, or a responsive\n // breakpoint crossing on a window resize — must not silently drop the value typed into it,\n // still less make `changed` false and discard the whole commit.\n const presentColumnIds = committed.columnIds();\n const editableColumnIds = presentColumnIds.filter(columnId => committed.canEdit(rowId, columnId));\n const drafts = draftsFor(rowId);\n const values: Record<string, unknown> = {};\n const previousValues: Record<string, unknown> = {};\n // What the data itself reads, so a write that goes through can later be told apart from the\n // data catching up with it.\n const sources = new Map<string, unknown>();\n let changed = false;\n\n for (const columnId of editableColumnIds) {\n const source = committed.value(rowId, columnId);\n const previous = previousRowValue(columnId, source);\n const value = drafts.has(columnId) ? drafts.get(columnId) : previous;\n sources.set(columnId, source);\n values[columnId] = value;\n previousValues[columnId] = previous;\n changed ||= !Object.is(value, previous);\n }\n\n // Drafts whose column produced no entry above fall into two very different cases.\n for (const [columnId, value] of drafts) {\n if (Object.hasOwn(values, columnId)) {\n continue;\n }\n\n if (committed.has(columnId)) {\n // The column is still here, it simply stopped being editable mid-edit — `meta.edit`\n // removed, or `edit.enabled(row)` now false for this row. Committing that draft would\n // push a value through a gate the application just closed, and unvalidated besides (the\n // validation pass below only walks editable cells). The pending value is dropped, not\n // promoted. (The reconciliation at the entry to `commitRow` has usually done this\n // already; a column whose gate shut between the two is why it is still tested here.)\n drafts.delete(columnId);\n\n continue;\n }\n\n // The other case: the column left the definitions entirely — a responsive breakpoint\n // crossing removes it before TanStack ever sees it, so there is no cell to read. The value\n // the user typed is still theirs and commits against the baseline captured at edit start.\n // Its `validate` cannot run, because the definition that carried it is gone.\n const source = rowDrafts.current.baseline?.get(columnId);\n const previous = previousRowValue(columnId, source);\n sources.set(columnId, source);\n values[columnId] = value;\n previousValues[columnId] = previous;\n changed ||= !Object.is(value, previous);\n }\n\n // First validation failure focuses its editor and blocks the whole row.\n for (const columnId of editableColumnIds) {\n const normalized = normalizeEdit(committed.edit(columnId));\n\n if (!normalized?.validate) {\n continue;\n }\n\n let message: string | null;\n\n try {\n message = normalized.validate(values[columnId], row);\n } catch (error) {\n message = editErrorMessage(error);\n }\n\n if (message !== null) {\n reportRowError(rowId, columnId, message);\n\n return false;\n }\n }\n\n if (!changed) {\n finishRowEditing();\n return true;\n }\n\n let result: void | Promise<void>;\n\n try {\n // Single erasure, the same boundary the render layer crosses: the committed resolver speaks\n // the erased shape, and v9's `in out` generics make Row invariant in TData.\n result = onRowEditCommit?.({\n row: row as Row<TData>,\n values,\n previousValues\n });\n } catch (error) {\n reportRowError(rowId, null, editErrorMessage(error));\n return false;\n }\n\n if (result && typeof result.then === \"function\") {\n const session = rowSessionRef.current;\n rowDrafts.current.writing = new Map(\n [...sources].map(([columnId, source]) => [columnId, { moved: false, source }])\n );\n setRowPending(true);\n\n const pending = Promise.resolve(result).then(\n () => {\n // Everything below touches the editors on screen, so a request whose session has\n // ended stops here: its row was cancelled or replaced, and the editors it would\n // close or un-pend belong to whoever came next. It reports failure, because the\n // caller waiting on it wanted to leave *that* row and that row is already gone —\n // navigating on its word would move an edit the controller has since redirected.\n if (!isCurrentRowSession(session, rowId)) {\n return false;\n }\n\n rowPendingCommit.current = null;\n recordRowCommit(rowId, values, sources);\n consumeCommittedRowDrafts(rowId, values);\n setRowPending(false);\n\n // The gate may have shut while this write was out; the test was held off until the\n // write it let through had landed. If it did shut, the row has just been cancelled —\n // it did not finish here, and a switch waiting on this commit must not open a row\n // nobody may edit.\n if (reconcileRowEligibility()) {\n return false;\n }\n\n if (hasUncommittedRowEdits(rowId, values)) {\n // Typed straight past the request while it was out. The write did go through, but\n // this row is not finished — and whoever was waiting to leave it must not.\n return false;\n }\n\n finishRowEditing();\n\n return true;\n },\n (error: unknown) => {\n if (!isCurrentRowSession(session, rowId)) {\n return false;\n }\n\n rowPendingCommit.current = null;\n rowDrafts.current.writing = null;\n setRowPending(false);\n reportRowError(rowId, null, editErrorMessage(error));\n reconcileRowEligibility();\n\n return false;\n }\n );\n\n rowPendingCommit.current = {\n session,\n rowId,\n promise: pending\n };\n\n return pending;\n }\n\n recordRowCommit(rowId, values, sources);\n consumeCommittedRowDrafts(rowId, values);\n finishRowEditing();\n return true;\n });\n\n /**\n * Focuses a mounted editor of the row being edited. A column not yet on screen — hidden, or\n * scrolled out of the virtual window — is left to `shouldFocus` when its editor mounts.\n */\n const focusRowColumn = (columnId: string | undefined) => {\n if (columnId !== undefined) {\n rowEditors.current.get(columnId)?.focus();\n }\n };\n\n const startRowEditing = useEventCallback((rowId: string, startOptions?: { focusColumnId?: string }) => {\n if (editingRowRef.current === rowId) {\n rowFocusColumn.current = startOptions?.focusColumnId ?? rowFocusColumn.current;\n\n if (rowDrafts.current.gateLost) {\n // The session on this row is over — its gate shut, and a controlled application declined\n // to close it. An explicit start is not that session coming back: it is the next one, so\n // it gets a new token and a fresh baseline, and nothing the old one held survives. The\n // slice already names this row, so no render would arrive to do it for us.\n endRowSession();\n openRowDrafts(rowId);\n setRowSessionEpoch(epoch => epoch + 1);\n }\n\n // A live session focuses the column asked for: the editors are already mounted, and the\n // slice is not moving, so nothing else would.\n redrawRowEditors();\n focusRowColumn(startOptions?.focusColumnId);\n\n return;\n }\n\n // Like `finishRowEditing`, a request: the session boundary is taken by the effect above,\n // once a render has actually put this row on screen.\n const begin = () => {\n rowFocusColumn.current = startOptions?.focusColumnId ?? null;\n setEditingRowId(rowId);\n };\n\n if (editingRowRef.current === null) {\n begin();\n return;\n }\n\n // Another row is mid-edit: commit it first (commit, never discard); only success moves on,\n // and only the latest start request may win after an async commit settles.\n const request = ++rowStartRequestRef.current;\n const outcome = commitRow();\n\n if (typeof outcome === \"boolean\") {\n if (outcome) {\n begin();\n }\n\n return;\n }\n\n void outcome.then(success => {\n if (success && rowStartRequestRef.current === request) {\n begin();\n }\n });\n });\n\n const stopRowEditing = useEventCallback((stopOptions?: { commit?: boolean }) => {\n if (stopOptions?.commit ?? true) {\n void commitRow();\n } else {\n discardRowEdits(editingRowRef.current);\n finishRowEditing();\n }\n });\n\n const shouldFocusRowColumn = useCallback((columnId: string) => rowFocusColumn.current === columnId, []);\n\n /**\n * Whether this row has a live editing session. The slice naming a row is not enough: its gate\n * may have shut while a controlled application declined to close it, and a session whose\n * eligibility is gone must not put an interactive editor back on screen when the gate reopens.\n */\n const rowSessionActive = useCallback(\n // Asked during render, so it cannot consult the committed mirror — that still names the row\n // this one is replacing. A row the store has not been keyed to yet is a session about to\n // open, which is live by definition; only the one being tracked can have lost its gate.\n //\n // Keyed to the epoch: the answer lives in a ref, so this identity changing is what carries a\n // session starting or ending into the render layer's memo.\n (rowId: string) => rowDrafts.current.rowId === rowId ? !rowDrafts.current.gateLost : true,\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- the epoch is the point: see above\n [rowSessionEpoch]\n );\n\n const registerRowEditor = useCallback((columnId: string, editor: LedgerRowEditor) => {\n rowEditors.current.set(columnId, editor);\n redrawRowLevelError();\n\n return () => {\n if (rowEditors.current.get(columnId) !== editor) {\n return;\n }\n\n rowEditors.current.delete(columnId);\n redrawRowLevelError();\n };\n }, [redrawRowLevelError]);\n\n /**\n * The store is what a row editor shows, rather than a value it copies at mount: what the row\n * holds moves under it — the application feeds a write back, normalizes it, or another writer\n * changes it — and an editor with its own copy would go on showing a value the row left behind.\n * Editors name the row they belong to instead of reading it from a shared mutable ref, because\n * two rows' editors can be on screen at once while React reconciles a switch.\n */\n const rowDraftsApi = useRef({\n pending: (rowId: string) => rowDrafts.current.rowId === rowId && rowPresentation.current.pending,\n error: (rowId: string, columnId: string) => {\n if (rowDrafts.current.rowId !== rowId || rowErrorColumnId(rowId) !== columnId) {\n return null;\n }\n\n return rowPresentation.current.error?.message ?? null;\n },\n read: (rowId: string, columnId: string, source: unknown) => {\n if (rowDrafts.current.rowId !== rowId) {\n return source;\n }\n\n return rowDrafts.current.values.has(columnId)\n ? rowDrafts.current.values.get(columnId)\n : previousRowValue(columnId, source);\n },\n write: (rowId: string, columnId: string, value: unknown) => {\n if (rowDrafts.current.rowId !== rowId) {\n return;\n }\n\n rowDrafts.current.values.set(columnId, value);\n\n // Typing answers the complaint the field is showing, and only that one: another column's\n // message is still true, and its editor is not the one being redrawn.\n if (rowErrorColumnId(rowId) === columnId) {\n rowPresentation.current.error = null;\n }\n }\n }).current;\n\n // Stable identities all the way out: this surface goes into `meta.ledger`, which the render\n // layer memoizes against — a fresh object or a fresh arrow here would re-render every cell in\n // the table on every render. Each of these reads nothing but refs.\n return useMemo(\n () => {\n return {\n active: rowSessionActive,\n commit: commitRow,\n drafts: rowDraftsApi,\n register: registerRowEditor,\n shouldFocus: shouldFocusRowColumn,\n start: startRowEditing,\n stop: stopRowEditing\n };\n },\n [rowSessionActive, commitRow, rowDraftsApi, registerRowEditor, shouldFocusRowColumn, startRowEditing, stopRowEditing]\n );\n}\n","import type { Updater } from \"@tanstack/react-table\";\n\n/**\n * One state slice of the table, following the canonical React controlled/uncontrolled contract\n * (docs/state.md): controlled `value` / uncontrolled `defaultValue` / observer `onChange`\n * receiving the resolved value. TanStack hands us `Updater`s; they are resolved here so consumer\n * callbacks never see a function.\n */\nimport { useUncontrolled } from \"@mantine/hooks\";\nimport { functionalUpdate } from \"@tanstack/react-table\";\nimport { useCallback, useInsertionEffect, useRef } from \"react\";\n\nexport type SliceSetter<T> = (updater: Updater<T>) => void;\n\nexport interface UseSliceInput<T> {\n value: T | undefined;\n defaultValue: T | undefined;\n onChange: ((value: T) => void) | undefined;\n /**\n * Internal notification for every resolved set attempt, including no-op values that React does\n * not render. Used by debounced controls to observe an external reset to the current value.\n */\n onSet?: (value: T) => void;\n fallback: T;\n}\n\nexport function useSlice<T>({\n value,\n defaultValue,\n onChange,\n onSet,\n fallback\n}: UseSliceInput<T>): readonly [T, SliceSetter<T>] {\n const [current, setCurrent, controlled] = useUncontrolled<T>({\n value,\n defaultValue,\n finalValue: fallback,\n onChange\n });\n\n /**\n * What actually reached the screen, and the handlers of the render that put it there. Mirrored\n * in an effect rather than during render: refs are shared between the current tree and a\n * work-in-progress one, so a transition React renders and then throws away — a sibling\n * suspends — would otherwise leave updaters resolving against a value nobody ever saw, and\n * calling the abandoned render's `onChange`. Insertion phase, so that a layout effect setting\n * a slice already sees this render's values; `useEventCallback` mirrors its handler the same\n * way, for the same reason.\n */\n const committedRef = useRef(current);\n const setCurrentRef = useRef(setCurrent);\n const onSetRef = useRef(onSet);\n const controlledRef = useRef(controlled);\n\n /**\n * The value already asked for and not yet seen on screen, so updaters resolve against each\n * other rather than against a snapshot the last one has already moved past. How long it may\n * stand depends on who owns the state.\n */\n const requestedRef = useRef<{ value: T; controlled: boolean } | null>(null);\n\n useInsertionEffect(() => {\n const previous = committedRef.current;\n committedRef.current = current;\n\n // What ends a request depends on who owns the state, because only one of them can answer one.\n //\n // Controlled: the owner is the authority, and `value` moving *is* it answering — to what was\n // asked for, to a normalization of it, or to something else entirely. Any move ends the\n // request, and the next updater departs from the answer. Only silence leaves one standing,\n // because silence is a refusal and a deferral at once and nothing tells them apart; `set`\n // bounds that with a microtask.\n //\n // Uncontrolled: the value is ours, so only a commit that actually carries it ends the\n // request. React renders lanes it has not been asked to flush yet — an urgent update commits\n // without the transition queued behind it — and an update still sitting in that queue is one\n // React will apply, so it goes on counting until it does.\n //\n // A slice that has changed hands drops it either way: what the last owner asked for is\n // nothing the new one agreed to.\n const request = requestedRef.current;\n\n if (request\n && (request.controlled !== controlled\n || Object.is(current, request.value)\n || (controlled && !Object.is(current, previous)))) {\n requestedRef.current = null;\n }\n\n setCurrentRef.current = setCurrent;\n onSetRef.current = onSet;\n controlledRef.current = controlled;\n });\n\n const set = useCallback<SliceSetter<T>>(updater => {\n // A request the other owner made says nothing about this one's value.\n const requested = requestedRef.current?.controlled === controlledRef.current ? requestedRef.current : null;\n const next = functionalUpdate(updater, requested ? requested.value : committedRef.current);\n\n // Uncontrolled state always takes the update. React renders it when it chooses — a\n // transition renders on a task of its own — so the value stands until the render carrying it\n // commits, and the insertion effect above is what ends it.\n //\n // A controlled owner may instead answer by leaving `value` exactly where it was, and nothing\n // tells that refusal apart from an acceptance it has deferred: both look like silence. So\n // there the value stands for the event that asked for it and no longer, dropped by a\n // microtask queued when the burst starts. An owner deferring inside a transition therefore\n // sees the next event depart from what is on screen rather than from what it has not applied\n // — building on a value it may never take is the worse of the two mistakes.\n if (requested === null && controlledRef.current) {\n queueMicrotask(() => {\n requestedRef.current = null;\n });\n }\n\n requestedRef.current = { controlled: controlledRef.current, value: next };\n onSetRef.current?.(next);\n setCurrentRef.current(next);\n }, []);\n\n return [current, set] as const;\n}\n","import type {\n ColumnFiltersState,\n ColumnOrderState,\n ColumnPinningState,\n ColumnSizingState,\n ExpandedState,\n GroupingState,\n PaginationState,\n RowData,\n RowPinningState,\n RowSelectionState,\n SortingState,\n TableOptions,\n TableState,\n Updater\n} from \"@tanstack/react-table\";\n\nimport type { LedgerInternalMeta, LedgerSortingController } from \"./ledger-commands\";\nimport type { LedgerFeatures } from \"./ledger-features\";\nimport type {\n DataTableEditingCell,\n TableInstance,\n UseDataTableOptions\n} from \"./types\";\n\n/**\n * The behavior core (docs/api.md): assembles the canonical v9 feature set (plus consumer\n * `filterFns`), translates `*Mode: \"server\"` into TanStack's manual flags, injects the\n * selection/expander columns, normalizes every state slice into the controlled/uncontrolled\n * trio, and carries ledger-private state through `table.options.meta.ledger`. Returns the bare\n * TanStack table instance.\n */\nimport { functionalUpdate, useTable } from \"@tanstack/react-table\";\nimport { useCallback, useEffect, useInsertionEffect, useMemo, useRef, useState } from \"react\";\n\nimport { buildColumns, EXPANDER_COLUMN_ID, isInternalColumn, SELECTION_COLUMN_ID } from \"./build-columns\";\nimport { isDev, warnOnce } from \"./env\";\nimport { ledgerFilterFns } from \"./filter-fns\";\nimport { buildLedgerFeatures } from \"./ledger-features\";\nimport { readPersistedState, usePersistWriter } from \"./persist\";\nimport { nextSorting } from \"./toggle-fns\";\nimport { useCellEditing } from \"./use-cell-editing\";\nimport { useCommittedTable } from \"./use-committed-table\";\nimport { useInstantEditing } from \"./use-instant-editing\";\nimport { useResponsiveColumns } from \"./use-responsive-columns\";\nimport { useRowCommands } from \"./use-row-commands\";\nimport { useRowEditing } from \"./use-row-editing\";\nimport { useSlice } from \"./use-slice\";\n\n/* Stable fallbacks — a fresh identity per render would defeat TanStack's memoization. */\nconst NO_SORTING: SortingState = [];\nconst NO_COLUMN_FILTERS: ColumnFiltersState = [];\nconst NO_ROW_SELECTION: RowSelectionState = {};\nconst NO_EXPANDED: ExpandedState = {};\nconst NO_VISIBILITY: Record<string, boolean> = {};\nconst NO_PINNING: ColumnPinningState = { start: [], end: [] };\nconst NO_COLUMN_ORDER: ColumnOrderState = [];\nconst NO_COLUMN_SIZING: ColumnSizingState = {};\nconst NO_GROUPING: GroupingState = [];\nconst NO_ROW_PINNING: RowPinningState = { top: [], bottom: [] };\nconst DEFAULT_PAGINATION: PaginationState = { pageIndex: 0, pageSize: 20 };\n\nexport function useDataTable<TData extends RowData>(options: UseDataTableOptions<TData>): TableInstance<TData> {\n const {\n data,\n columns,\n getRowId,\n enableSorting = true,\n enableMultiSort = true,\n enableSortingRemoval = true,\n enableColumnFilters = true,\n enableGlobalFilter = false,\n enablePagination = false,\n enableRowSelection = false,\n enableMultiRowSelection = true,\n enableColumnResizing = false,\n enableColumnPinning = true,\n enableColumnOrdering = false,\n enableHiding = true,\n enableEditing = true,\n enableGrouping = false,\n enableRowPinning = false,\n enableCellSpanning = true,\n getSubRows,\n renderDetailPanel,\n selectionColumn,\n expanderColumn,\n sortingMode = \"client\",\n filterMode = \"client\",\n paginationMode = \"client\",\n rowCount,\n editTrigger = \"double-click\",\n editMode = \"cell\",\n onEditCommit,\n onRowEditCommit,\n enableActiveRow = false,\n enableRowOrdering = false,\n onRowReorder,\n rowDragColumn,\n persistState,\n defaultColumn,\n tableOptions\n } = options;\n\n /* ---- the feature set: canonical modules + the consumer's filterFns, fixed at mount ---- */\n const [features] = useState<LedgerFeatures>(() => buildLedgerFeatures(options.filterFns));\n\n if (isDev && options.filterFns) {\n for (const filterFnId of Object.keys(ledgerFilterFns)) {\n if (Object.hasOwn(options.filterFns, filterFnId)) {\n warnOnce(\n `filterFns.${filterFnId}`,\n `filterFns.${filterFnId} is reserved by ledger and has been overridden.`\n );\n }\n }\n }\n\n /* ---- persistence hydrates uncontrolled slices, once, synchronously ---- */\n const [persisted] = useState(() => readPersistedState(persistState));\n const filterSetListeners = useRef({\n columnFilters: new Set<(value: ColumnFiltersState) => void>(),\n globalFilter: new Set<(value: string) => void>()\n });\n\n /* ---- state slices: controlled x / uncontrolled defaultX / observer onXChange ---- */\n const [sorting, setSorting] = useSlice({\n value: options.sorting,\n defaultValue: (persisted.sorting as SortingState | undefined) ?? options.defaultSorting,\n onChange: options.onSortingChange,\n fallback: NO_SORTING\n });\n const [columnFilters, setColumnFilters] = useSlice({\n value: options.columnFilters,\n defaultValue: (persisted.columnFilters as ColumnFiltersState | undefined) ?? options.defaultColumnFilters,\n onChange: options.onColumnFiltersChange,\n onSet: value => {\n for (const listener of filterSetListeners.current.columnFilters) {\n listener(value);\n }\n },\n fallback: NO_COLUMN_FILTERS\n });\n const [globalFilter, setGlobalFilter] = useSlice({\n value: options.globalFilter,\n defaultValue: (persisted.globalFilter as string | undefined) ?? options.defaultGlobalFilter,\n onChange: options.onGlobalFilterChange,\n onSet: value => {\n for (const listener of filterSetListeners.current.globalFilter) {\n listener(value);\n }\n },\n fallback: \"\"\n });\n const [pagination, setPagination] = useSlice({\n value: options.pagination,\n defaultValue: (persisted.pagination as PaginationState | undefined) ?? options.defaultPagination,\n onChange: options.onPaginationChange,\n fallback: DEFAULT_PAGINATION\n });\n const [rowSelection, setRowSelection] = useSlice({\n value: options.rowSelection,\n defaultValue: options.defaultRowSelection,\n onChange: options.onRowSelectionChange,\n fallback: NO_ROW_SELECTION\n });\n const [expanded, setExpanded] = useSlice({\n value: options.expanded,\n defaultValue: options.defaultExpanded,\n onChange: options.onExpandedChange,\n fallback: NO_EXPANDED\n });\n const [columnVisibility, setColumnVisibility] = useSlice({\n value: options.columnVisibility,\n defaultValue: (persisted.columnVisibility as Record<string, boolean> | undefined) ?? options.defaultColumnVisibility,\n onChange: options.onColumnVisibilityChange,\n fallback: NO_VISIBILITY\n });\n const [columnPinning, setColumnPinning] = useSlice({\n value: options.columnPinning,\n defaultValue: (persisted.columnPinning as ColumnPinningState | undefined) ?? options.defaultColumnPinning,\n onChange: options.onColumnPinningChange,\n fallback: NO_PINNING\n });\n const [columnOrder, setColumnOrder] = useSlice({\n value: options.columnOrder,\n defaultValue: (persisted.columnOrder as ColumnOrderState | undefined) ?? options.defaultColumnOrder,\n onChange: options.onColumnOrderChange,\n fallback: NO_COLUMN_ORDER\n });\n const [columnSizing, setColumnSizing] = useSlice({\n value: options.columnSizing,\n defaultValue: (persisted.columnSizing as ColumnSizingState | undefined) ?? options.defaultColumnSizing,\n onChange: options.onColumnSizingChange,\n fallback: NO_COLUMN_SIZING\n });\n const [grouping, setGrouping] = useSlice({\n value: options.grouping,\n defaultValue: (persisted.grouping as GroupingState | undefined) ?? options.defaultGrouping,\n onChange: options.onGroupingChange,\n fallback: NO_GROUPING\n });\n const [rowPinning, setRowPinning] = useSlice({\n value: options.rowPinning,\n defaultValue: options.defaultRowPinning,\n onChange: options.onRowPinningChange,\n fallback: NO_ROW_PINNING\n });\n const [editingCell, setEditingCell] = useSlice<DataTableEditingCell | null>({\n value: options.editingCell,\n defaultValue: undefined,\n onChange: options.onEditingCellChange,\n fallback: null\n });\n const [editingRowId, setEditingRowId] = useSlice<string | null>({\n value: options.editingRowId,\n defaultValue: undefined,\n onChange: options.onEditingRowIdChange,\n fallback: null\n });\n const [activeRowId, setActiveRowSlice] = useSlice<string | null>({\n value: options.activeRowId,\n defaultValue: options.defaultActiveRowId,\n onChange: options.onActiveRowIdChange,\n fallback: null\n });\n const setActiveRowId = useCallback(\n (id: string | null) => setActiveRowSlice(id),\n [setActiveRowSlice]\n );\n const setNormalizedGlobalFilter = useCallback((updater: Updater<unknown>) => {\n setGlobalFilter(previous => {\n const next = functionalUpdate(updater, previous);\n\n return typeof next === \"string\" ? next : \"\";\n });\n }, [setGlobalFilter]);\n\n /* ---- editing controller (docs/editing.md) ---- */\n // Rows, definitions and the gate as the render that reached the screen left them: everything the\n // editing paths decide with is resolved from here, never from the shared core, which carries\n // whatever pass ran last — a discarded one included (see `use-committed-table.ts`).\n const [committed, captureCommitted] = useCommittedTable<TData>();\n\n // The cell session lives in its own module: everything an editor shows, and everything its\n // commit decides with, has to outlive an editor that a hidden column or a virtual scroll can\n // unmount at any moment (docs/architecture.md).\n const cellSession = useCellEditing<TData>({\n committed,\n editingCell,\n onEditCommit,\n setEditingCell\n });\n\n // An instant column commits on change instead of opening an editor, but what a commit leaves\n // behind — a write still out, its failure, the value the application now holds — outlives the\n // control just as a session outlives its editor (docs/architecture.md).\n const instantSession = useInstantEditing<TData>({\n committed,\n onEditCommit\n });\n\n /* ---- row editing controller (editMode: \"row\", docs/editing.md#row-mode) ---- */\n // In its own module for the reason the other two sessions are: what the row's editors show, and\n // what its atomic commit decides with, has to outlive editors a hidden column or a virtual\n // scroll can unmount at any moment (docs/architecture.md).\n const rowSession = useRowEditing<TData>({\n committed,\n editingRowId,\n onRowEditCommit,\n setEditingRowId\n });\n\n if (isDev && editMode === \"row\") {\n if (options.editingCell !== undefined || options.onEditingCellChange) {\n warnOnce(\"row-mode-editing-cell\", \"editingCell is a cell-mode slice — editMode: \\\"row\\\" tracks editingRowId instead.\");\n }\n\n if (onEditCommit) {\n warnOnce(\"row-mode-on-edit-commit\", \"onEditCommit never fires under editMode: \\\"row\\\" — use onRowEditCommit.\");\n }\n }\n\n const [selectionCommands, expansionCommands, captureRows] = useRowCommands<TData>(setRowSelection, setExpanded);\n const sortingCommands = useMemo<LedgerSortingController>(\n () => {\n return {\n toggle: (spec, multi) => setSorting(previous => nextSorting(previous, spec, multi))\n };\n },\n [setSorting]\n );\n\n const subscribeColumnFilters = useCallback((listener: (value: ColumnFiltersState) => void) => {\n const listeners = filterSetListeners.current.columnFilters;\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n }, []);\n const subscribeGlobalFilter = useCallback((listener: (value: string) => void) => {\n const listeners = filterSetListeners.current.globalFilter;\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n }, []);\n\n const selectAllScope: \"page\" | \"all\"\n = enablePagination || paginationMode === \"server\" ? \"page\" : \"all\";\n\n /* ---- columns: breakpoint filter + injected row-drag/selection/expander + meta.filter wiring ---- */\n const responsiveColumns = useResponsiveColumns(columns);\n const withExpander = Boolean(renderDetailPanel || getSubRows);\n // The static row-ordering gate (docs/rows.md#row-ordering): without a handler nothing could\n // apply a move — row order is data order — and tree data has no flat order to move within.\n const withRowDrag = enableRowOrdering && onRowReorder !== undefined && !getSubRows;\n\n if (isDev && enableRowOrdering && getSubRows) {\n warnOnce(\"row-ordering-tree\", \"enableRowOrdering supports flat data only — getSubRows disables it (docs/rows.md#row-ordering).\");\n }\n\n const processedColumns = useMemo(\n () => buildColumns({\n columns: responsiveColumns,\n withRowDrag,\n withSelection: Boolean(enableRowSelection),\n withExpander,\n rowDragColumn,\n selectionColumn,\n expanderColumn\n }),\n [responsiveColumns, withRowDrag, enableRowSelection, withExpander, rowDragColumn, selectionColumn, expanderColumn]\n );\n\n // The live half of the gate: while something else controls the visible order, a \"reorder\"\n // has no data-order meaning — the handles disable and say why (labels.rowOrderingUnavailable).\n const rowOrderable = withRowDrag\n && sorting.length === 0\n && columnFilters.length === 0\n && !globalFilter\n && grouping.length === 0;\n\n const ledger: LedgerInternalMeta<TData> = useMemo(\n () => {\n return {\n columns: processedColumns,\n sorting: sortingCommands,\n selection: selectionCommands,\n expansion: expansionCommands,\n editing: {\n mode: editMode,\n cell: editingCell,\n active: cellSession.active,\n start: cellSession.start,\n stop: cellSession.stop,\n clear: cellSession.clear,\n commit: cellSession.commit,\n cancel: cellSession.cancel,\n moveTo: cellSession.moveTo,\n drafts: {\n error: cellSession.error,\n pending: cellSession.pending,\n read: cellSession.read,\n write: cellSession.write\n },\n register: cellSession.register,\n firstEditable: cellSession.firstEditable,\n instant: instantSession,\n // The slice is the hook's, the session is the controller's — spread so the two cannot\n // drift out of the shape `LedgerRowEditingController` declares.\n row: { id: editingRowId, ...rowSession }\n },\n filtering: {\n subscribeColumnFilters,\n subscribeGlobalFilter\n },\n editTrigger,\n enableEditing,\n onEditCommit,\n onRowEditCommit,\n renderDetailPanel,\n selectAllScope,\n activeRow: {\n enabled: enableActiveRow,\n id: activeRowId,\n set: setActiveRowId\n },\n enableColumnOrdering,\n enableColumnResizing,\n enablePagination,\n rowOrdering: {\n enabled: withRowDrag,\n orderable: rowOrderable,\n onRowReorder\n }\n };\n },\n [\n sortingCommands,\n selectionCommands,\n expansionCommands,\n processedColumns,\n editingCell,\n cellSession,\n instantSession,\n editMode,\n editingRowId,\n rowSession,\n subscribeColumnFilters,\n subscribeGlobalFilter,\n editTrigger,\n enableEditing,\n onEditCommit,\n onRowEditCommit,\n renderDetailPanel,\n selectAllScope,\n enableActiveRow,\n activeRowId,\n setActiveRowId,\n enableColumnOrdering,\n enableColumnResizing,\n enablePagination,\n withRowDrag,\n rowOrderable,\n onRowReorder\n ]\n );\n\n /* Injected columns are always pinned to the start, invisibly merged over the consumer's slice. */\n const mergedColumnPinning = useMemo<ColumnPinningState>(() => {\n const internal: string[] = [];\n\n if (enableRowSelection) {\n internal.push(SELECTION_COLUMN_ID);\n }\n\n if (withExpander) {\n internal.push(EXPANDER_COLUMN_ID);\n }\n\n const start = columnPinning.start.filter(id => !internal.includes(id));\n\n return { start: [...internal, ...start], end: columnPinning.end };\n }, [columnPinning, enableRowSelection, withExpander]);\n\n // The write side of that invisibility: `column.pin()` resolves against the merged state, so a\n // call on (or alongside) an injected column would land a `ledger:*` id in the consumer's slice\n // — and from there in `onColumnPinningChange` and persisted layout. Internal ids are stripped\n // from the resolved value instead; a write that stripping turns into a no-op keeps the old\n // value's identity, so the uncontrolled state never re-renders for it.\n const setPublicColumnPinning = useCallback((updater: Updater<ColumnPinningState>) => {\n setColumnPinning(old => {\n const next = functionalUpdate(updater, old);\n const start = next.start.filter(id => !isInternalColumn(id));\n const end = next.end.filter(id => !isInternalColumn(id));\n\n if (start.length === next.start.length && end.length === next.end.length) {\n return next;\n }\n\n const unchanged = start.length === old.start.length\n && end.length === old.end.length\n && start.every((id, index) => id === old.start[index])\n && end.every((id, index) => id === old.end[index]);\n\n return unchanged ? old : { end, start };\n });\n }, [setColumnPinning]);\n\n /* ---- dev guard rails (docs/state.md) ---- */\n if (isDev && (enableRowSelection || withExpander) && !getRowId) {\n warnOnce(\n \"missing-get-row-id\",\n \"Row selection/expansion is enabled without getRowId — index-based row ids corrupt state across refetches.\"\n );\n }\n\n const churn = useRef({\n renders: 0,\n columnChanges: 0,\n previousColumns: columns\n });\n\n if (isDev) {\n const tracker = churn.current;\n tracker.renders += 1;\n\n if (columns !== tracker.previousColumns) {\n tracker.columnChanges += 1;\n tracker.previousColumns = columns;\n }\n\n if (tracker.renders >= 10 && tracker.columnChanges >= tracker.renders - 2) {\n warnOnce(\n \"columns-identity\",\n \"`columns` has a new identity on almost every render — memoize it, or the table re-initializes continuously.\"\n );\n }\n }\n\n /* ---- client/server translation + auto-reset policy (docs/state.md) ---- */\n const manualSorting = sortingMode === \"server\";\n const manualFiltering = filterMode === \"server\";\n const serverPagination = paginationMode === \"server\";\n /**\n * v9 runs the paginated row model unless the factory is absent or `manualPagination` is set\n * (`getRowModel` → `getPrePaginatedRowModel`). The factory is part of the canonical feature\n * set and features are read once at mount, so the switch that stays reactive is this one:\n * with pagination off every row has to reach the body, which is the same short-circuit the\n * server mode takes. It is inert elsewhere — `paginateExpandedRows` defaults to `true`, so\n * the expanded row model is unaffected, and the upstream page-reset default it also gates is\n * meaningless while there are no pages.\n */\n const bypassPaginatedRowModel = serverPagination || !enablePagination;\n\n const shouldAutoResetPageIndex\n = tableOptions?.autoResetAll ?? tableOptions?.autoResetPageIndex ?? true;\n const previousResetInputs = useRef({\n columnFilters,\n globalFilter,\n sorting\n });\n\n useEffect(() => {\n const previous = previousResetInputs.current;\n const inputsChanged\n = previous.columnFilters !== columnFilters\n || previous.globalFilter !== globalFilter\n || previous.sorting !== sorting;\n previousResetInputs.current = {\n columnFilters,\n globalFilter,\n sorting\n };\n\n if (!serverPagination || !shouldAutoResetPageIndex || !inputsChanged) {\n return;\n }\n\n setPagination(previous => previous.pageIndex === 0 ? previous : { ...previous, pageIndex: 0 });\n }, [\n columnFilters,\n globalFilter,\n sorting,\n serverPagination,\n setPagination,\n shouldAutoResetPageIndex\n ]);\n\n // ---- reset targets ----\n // TanStack's slice reset APIs restore `table.initialState`. The live state remains fully\n // controlled; this object exists only to preserve ledger's `defaultX`/fallback contract.\n // Persisted values stay excluded so reset remains useful after hydration.\n const resetInitialState: Partial<TableState<LedgerFeatures>> = {\n sorting: options.defaultSorting ?? NO_SORTING,\n columnFilters: options.defaultColumnFilters ?? NO_COLUMN_FILTERS,\n globalFilter: options.defaultGlobalFilter ?? \"\",\n pagination: options.defaultPagination ?? DEFAULT_PAGINATION,\n rowSelection: options.defaultRowSelection ?? NO_ROW_SELECTION,\n expanded: options.defaultExpanded ?? NO_EXPANDED,\n columnVisibility: options.defaultColumnVisibility ?? NO_VISIBILITY,\n columnPinning: options.defaultColumnPinning ?? NO_PINNING,\n columnOrder: options.defaultColumnOrder ?? NO_COLUMN_ORDER,\n columnSizing: options.defaultColumnSizing ?? NO_COLUMN_SIZING,\n grouping: options.defaultGrouping ?? NO_GROUPING,\n rowPinning: options.defaultRowPinning ?? NO_ROW_PINNING\n };\n\n /* ---- assemble: tableOptions is the base layer, ledger-managed keys override (docs/state.md) ---- */\n const managed = {\n data,\n columns: processedColumns,\n features,\n ...getRowId && { getRowId },\n ...defaultColumn && { defaultColumn },\n initialState: resetInitialState,\n state: {\n sorting,\n columnFilters,\n globalFilter,\n pagination,\n rowSelection,\n expanded,\n columnVisibility,\n columnPinning: mergedColumnPinning,\n columnOrder,\n columnSizing,\n grouping,\n rowPinning\n },\n onSortingChange: setSorting,\n onColumnFiltersChange: setColumnFilters,\n onGlobalFilterChange: setNormalizedGlobalFilter,\n onPaginationChange: setPagination,\n onRowSelectionChange: setRowSelection,\n onExpandedChange: setExpanded,\n onColumnVisibilityChange: setColumnVisibility,\n onColumnPinningChange: setPublicColumnPinning,\n onColumnOrderChange: setColumnOrder,\n onColumnSizingChange: setColumnSizing,\n onGroupingChange: setGrouping,\n onRowPinningChange: setRowPinning,\n enableSorting,\n enableMultiSort,\n enableSortingRemoval,\n enableColumnFilters,\n enableGlobalFilter,\n enableRowSelection,\n enableMultiRowSelection,\n enableColumnPinning,\n enableHiding,\n enableGrouping,\n enableRowPinning,\n enableCellSpanning,\n enableExpanding: withExpander || enableGrouping,\n ...getSubRows && { getSubRows },\n ...renderDetailPanel && { getRowCanExpand: () => true },\n manualSorting,\n manualFiltering,\n manualPagination: bypassPaginatedRowModel,\n ...serverPagination && rowCount !== undefined && { rowCount },\n ...serverPagination && {\n // `autoResetAll` outranks `autoResetPageIndex` inside TanStack. Consume it here so the\n // deterministic server reset remains authoritative, while preserving its only other\n // upstream effects through the feature-specific options.\n autoResetAll: undefined,\n autoResetExpanded: tableOptions?.autoResetAll ?? tableOptions?.autoResetExpanded,\n autoResetSorting: tableOptions?.autoResetAll ?? tableOptions?.autoResetSorting,\n autoResetPageIndex: false\n },\n meta: { ...tableOptions?.meta, ledger }\n } satisfies Partial<TableOptions<LedgerFeatures, TData>>;\n\n if (isDev && tableOptions) {\n for (const key of Object.keys(tableOptions)) {\n const isConsumedPaginationPolicy = serverPagination\n && (key === \"autoResetAll\" || key === \"autoResetExpanded\" || key === \"autoResetSorting\" || key === \"autoResetPageIndex\");\n\n if (key !== \"meta\" && !isConsumedPaginationPolicy && Object.hasOwn(managed, key)) {\n warnOnce(\n `tableOptions.${key}`,\n `tableOptions.${key} is managed by ledger and has been overridden — use the first-class option instead.`\n );\n }\n }\n }\n\n const table = useTable<LedgerFeatures, TData>({ ...tableOptions, ...managed } as TableOptions<LedgerFeatures, TData>);\n\n /**\n * What the editing paths and the row commands answer from. v9's `useTable` returns a fresh\n * wrapper whenever options or state change — `useMemo(() => ({ ...table, options, state }))` —\n * so neither that wrapper nor the shared core beneath it can be read at event time: a\n * transition React renders and then throws away leaves the core holding options nothing on\n * screen is using, and a commit would then be gated by an `enableEditing` the user never saw.\n *\n * Taken in the insertion phase, which is the commit — a render React throws away never reaches\n * one, so it never gets to say what the editing paths saw — and before every layout effect, so\n * a session boundary or an editor registration already sees this render's answers.\n */\n useInsertionEffect(() => {\n captureCommitted(table, {\n enableEditing,\n hasCommitHandler: Boolean(editMode === \"row\" ? onRowEditCommit : onEditCommit)\n });\n captureRows(table);\n });\n\n usePersistWriter(persistState, {\n sorting,\n columnFilters,\n globalFilter,\n pagination,\n columnVisibility,\n columnPinning,\n columnOrder,\n columnSizing,\n grouping\n });\n\n return table;\n}\n","import type { GetStylesApi } from \"@mantine/core\";\n\nimport type { DataTableFactory } from \"./data-table\";\n\n/**\n * Keeps one identity for the Styles API for as long as it resolves the same answers.\n *\n * Mantine's `useStyles` re-resolves theme, `classNames`, `styles`, `vars`, `attributes` and the\n * props those read on every render, and returns a fresh getter each time. Neither obvious thing to\n * do with that getter works: handing it to a context rebuilds the context value on every render, so\n * nothing below stays memoized; pinning it behind a ref keeps the identity but freezes the answers,\n * so a real `styles.row` change never reaches a memoized row — and writing that ref during render\n * lets a transition React throws away restyle the tree on screen.\n *\n * The way out is to compare what the getter *resolves* rather than the getter itself. Two getters\n * that answer identically for every selector are interchangeable, so the committed one is kept and\n * nothing below re-renders. The moment an answer differs, this render's getter is returned, and\n * because it goes into a context value that identity change reaches even a `React.memo`ed row.\n *\n * The comparison covers each selector's `className`, `style` and attributes, plus the provenance a\n * per-call option is resolved against — `getStyles(selector, { style })` merges that style through\n * `resolveStyle(style, theme)`, which the answers alone would not reveal (docs/styling.md).\n *\n * Committed in an insertion effect, never during render: a render React discards must not be able\n * to say what the tree on screen is styled with.\n */\nimport {\n useMantineClassNamesPrefix,\n useMantineIsHeadless,\n useMantineStylesTransform,\n useMantineTheme,\n useMantineWithStaticClasses\n} from \"@mantine/core\";\nimport { useInsertionEffect, useRef } from \"react\";\n\ntype Styles = GetStylesApi<DataTableFactory>;\n\ntype Selector = Parameters<Styles>[0];\n\n/**\n * One selector's resolved props: whatever `attributes` put there, plus `className` and `style`.\n */\ntype Answer = Record<string, unknown>;\n\ntype Answers = Partial<Record<Selector, Answer>>;\n\n/**\n * Own string keys, compared by identity. Never serialized: `attributes` carries whatever the\n * application put in it — event handlers, objects that refer to themselves — and writing answers\n * down as text would silently drop a replaced handler and throw on the rest.\n */\nfunction sameShallow(previous: unknown, next: unknown): boolean {\n if (Object.is(previous, next)) {\n return true;\n }\n\n if (typeof previous !== \"object\" || typeof next !== \"object\" || previous === null || next === null) {\n return false;\n }\n\n const previousKeys = Object.keys(previous);\n\n if (previousKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n return previousKeys.every(key => Object.hasOwn(next, key) && Object.is((previous as Answer)[key], (next as Answer)[key]));\n}\n\nfunction sameAnswer(previous: Answer, next: Answer): boolean {\n const previousKeys = Object.keys(previous);\n\n if (previousKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n return previousKeys.every(key => {\n if (!Object.hasOwn(next, key)) {\n return false;\n }\n\n // Mantine builds a fresh `style` object on every render, so identity says nothing there; one\n // level of its own keys does. Everything else is compared by identity, which is what makes a\n // replaced handler a real change — and what makes an object-valued attribute conservatively\n // count as one.\n return key === \"style\"\n ? sameShallow(previous[key], next[key])\n : Object.is(previous[key], next[key]);\n });\n}\n\nfunction resolveAnswers(getStyles: Styles, selectors: readonly Selector[]): Answers {\n const answers: Answers = {};\n\n for (const selector of selectors) {\n answers[selector] = getStyles(selector) as Answer;\n }\n\n return answers;\n}\n\nfunction sameAnswers(previous: Answers, next: Answers, selectors: readonly Selector[]): boolean {\n return selectors.every(selector => {\n const before = previous[selector];\n const after = next[selector];\n\n return before !== undefined && after !== undefined && sameAnswer(before, after);\n });\n}\n\nexport function useStylesRevision(getStyles: Styles, selectors: readonly Selector[]): Styles {\n // The inputs the returned getter closes over that its own answers do not expose: a per-call\n // `options.style` is resolved against the theme, and the rest decide how class names are built.\n const provenance = [\n useMantineTheme(),\n useMantineClassNamesPrefix(),\n useMantineWithStaticClasses(),\n useMantineIsHeadless(),\n useMantineStylesTransform()\n ];\n const answers = resolveAnswers(getStyles, selectors);\n const committed = useRef<{ answers: Answers; provenance: unknown[]; getStyles: Styles }>({\n answers,\n getStyles,\n provenance\n });\n\n const unchanged\n = committed.current.provenance.every((value, index) => Object.is(value, provenance[index]))\n && sameAnswers(committed.current.answers, answers, selectors);\n const revision = unchanged ? committed.current.getStyles : getStyles;\n\n useInsertionEffect(() => {\n committed.current = {\n answers,\n getStyles: revision,\n provenance\n };\n });\n\n return revision;\n}\n","import type {\n BoxProps,\n ElementProps,\n Factory,\n MantineColor,\n MantineRadius,\n MantineSpacing,\n StylesApiProps,\n TableTrProps\n} from \"@mantine/core\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport type { Virtualizer } from \"@tanstack/react-virtual\";\nimport type { ComponentProps, JSX, MouseEvent, KeyboardEvent as ReactKeyboardEvent, ReactNode, Ref } from \"react\";\n\nimport type { DataTableContextValue } from \"./context\";\nimport type { DataAttributes, DataTableElementProps } from \"./element-props\";\nimport type { DataTableIcons } from \"./icons\";\nimport type { DataTableLabels } from \"./labels\";\nimport type { VirtualizationConfig } from \"./table-body\";\nimport type {\n Column,\n DataTableHandle,\n DataTableScrollOptions,\n HeaderGroup,\n Row,\n TableInstance,\n UseDataTableOptions\n} from \"./types\";\nimport type { ColumnWindowView } from \"./use-column-window\";\n\n/**\n * The root component (docs/api.md): a generic Mantine factory with full Styles API,\n * adaptive sizing (the root is a flex column that fills its parent; the ScrollArea is the only\n * elastic region), CSS-variable column geometry, infinite loading, pinned-edge shadows, the\n * built-in pagination bar, and the imperative handle.\n *\n * Sugar mode (`data`/`columns` inline) and hook mode (`table`) render through the same core;\n * the split components below keep the hook call unconditional.\n */\nimport {\n Box,\n Button,\n createVarsResolver,\n EmptyState,\n genericFactory,\n getRadius,\n getThemeColor,\n LoadingOverlay,\n Table as MantineTable,\n ScrollArea,\n useProps,\n useStyles,\n VisuallyHidden\n} from \"@mantine/core\";\nimport { useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from \"react\";\n\nimport { isInternalColumn } from \"./build-columns\";\nimport { DataTableColumnsPanel } from \"./columns-panel\";\nimport { DataTableProvider } from \"./context\";\nimport { mergeElementProps } from \"./element-props\";\nimport { warnOnce } from \"./env\";\nimport { resolveIcons } from \"./icons\";\nimport { resolveLabels } from \"./labels\";\nimport { ledgerCommands } from \"./ledger-commands\";\nimport { DataTablePagination, DEFAULT_PAGE_SIZE_OPTIONS, PaginationBar } from \"./pagination-bar\";\nimport { RowReorderScope, useRowReorder } from \"./row-reorder\";\nimport { DataTableSearch } from \"./search\";\nimport { DataTableSelectionBar } from \"./selection-bar\";\nimport { buildDisplayRows, countDisplayRows, TableBody } from \"./table-body\";\nimport { TableFooter, tableHasFooter, visibleFooterGroups } from \"./table-footer\";\nimport { TableHeader } from \"./table-header\";\nimport { useColumnWidths } from \"./use-column-widths\";\nimport { DEFAULT_COLUMN_OVERSCAN, useColumnWindow } from \"./use-column-window\";\nimport { useDataTable } from \"./use-data-table\";\nimport { useStylesRevision } from \"./use-styles-revision\";\nimport { columnAfterVar, columnStartVar, columnWidthVar, toPx, useEventCallback } from \"./utils\";\n\n// ------------------------------------------------------------------------------------------------\n// Styles API surface\n// ----------------------------------------------------------------------------------------------\n\nexport type DataTableStylesNames\n = | \"root\"\n | \"main\"\n | \"header\"\n | \"scroller\"\n | \"footer\"\n | \"table\"\n | \"thead\"\n | \"tbody\"\n | \"tfoot\"\n | \"headerRow\"\n | \"headerCell\"\n | \"headerLabel\"\n | \"headerActions\"\n | \"sortIndicator\"\n | \"resizer\"\n | \"filterPopover\"\n | \"row\"\n | \"cell\"\n | \"selectionCell\"\n | \"expanderCell\"\n | \"detailPanel\"\n | \"cellEditor\"\n | \"instantCell\"\n | \"instantSpinner\"\n | \"rowDragCell\"\n | \"rowDragOverlay\"\n | \"footerRow\"\n | \"footerCell\"\n | \"empty\"\n | \"loaderRow\"\n | \"loaderRowContent\"\n | \"paginationBar\";\n\nexport interface DataTableCssVariables {\n root: \"--ledger-striped-color\" | \"--ledger-hover-color\" | \"--ledger-border-color\" | \"--ledger-radius\";\n}\n\n/**\n * Static kebab-case classes — the styling contract's public selector map (docs/styling.md).\n */\nconst classes: Record<DataTableStylesNames, string> = {\n root: \"ledger-root\",\n main: \"ledger-main\",\n header: \"ledger-header\",\n scroller: \"ledger-scroller\",\n footer: \"ledger-footer\",\n table: \"ledger-table\",\n thead: \"ledger-thead\",\n tbody: \"ledger-tbody\",\n tfoot: \"ledger-tfoot\",\n headerRow: \"ledger-header-row\",\n headerCell: \"ledger-header-cell\",\n headerLabel: \"ledger-header-label\",\n headerActions: \"ledger-header-actions\",\n sortIndicator: \"ledger-sort-indicator\",\n resizer: \"ledger-resizer\",\n filterPopover: \"ledger-filter-popover\",\n row: \"ledger-row\",\n cell: \"ledger-cell\",\n selectionCell: \"ledger-selection-cell\",\n expanderCell: \"ledger-expander-cell\",\n detailPanel: \"ledger-detail-panel\",\n cellEditor: \"ledger-cell-editor\",\n instantCell: \"ledger-instant-cell\",\n instantSpinner: \"ledger-instant-spinner\",\n rowDragCell: \"ledger-row-drag-cell\",\n rowDragOverlay: \"ledger-row-drag-overlay\",\n footerRow: \"ledger-footer-row\",\n footerCell: \"ledger-footer-cell\",\n empty: \"ledger-empty\",\n loaderRow: \"ledger-loader-row\",\n loaderRowContent: \"ledger-loader-row-content\",\n paginationBar: \"ledger-pagination-bar\"\n};\n\n/**\n * Every selector the Styles API answers for — the comparison set behind the style revision\n * (`use-styles-revision.ts`). Constant, so the cost is per render and never per row.\n */\nconst STYLE_SELECTORS = Object.keys(classes) as DataTableStylesNames[];\n\n/**\n * Stable identity for an unoccupied pinned zone — a fresh `[]` would re-run the announcement.\n */\nconst NO_ARIA_ROWS: never[] = [];\n\n// Mantine styles the EmptyState title as a headline (bright, 600) for full-page empties with\n// description and actions; a bare table caption reads better dimmed.\nconst EMPTY_STATE_STYLES = {\n title: { color: \"var(--mantine-color-dimmed)\", fontWeight: 500 }\n} as const;\n\n// ------------------------------------------------------------------------------------------------\n// Props\n// ----------------------------------------------------------------------------------------------\n\nexport interface DataTableBaseProps<TData extends RowData>\n extends BoxProps,\n StylesApiProps<DataTableFactory>,\n ElementProps<\"div\"> {\n /**\n * Root element ref (React 19 ref-as-prop; genericFactory components receive it here).\n */\n ref?: Ref<HTMLDivElement>;\n\n // Mantine Table appearance (forwarded names; striped/hover are rendered by ledger itself\n // through the --ledger-row-bg pipeline so pinned cells always cover them)\n striped?: boolean | \"odd\" | \"even\";\n stripedColor?: MantineColor;\n highlightOnHover?: boolean;\n highlightOnHoverColor?: MantineColor;\n withTableBorder?: boolean;\n withColumnBorders?: boolean;\n withRowBorders?: boolean;\n borderColor?: MantineColor;\n /**\n * Corner radius of the table box — header, body, and footer as one rounded, clipping box;\n * the `withTableBorder` frame follows it, so a framed table can be its own card (host\n * vocabulary: `Paper.radius`).\n */\n radius?: MantineRadius;\n verticalSpacing?: MantineSpacing;\n horizontalSpacing?: MantineSpacing;\n tabularNums?: boolean;\n\n /* Layout */\n tableMinWidth?: number | string;\n\n /* Scale */\n /**\n * Row virtualization ([virtualization.md](../docs/virtualization.md)): the body renders a\n * measured window of rows between two spacer rows.\n */\n virtualizedRows?: boolean | { estimateHeight?: number; overscan?: number };\n /**\n * Column virtualization ([virtualization.md](../docs/virtualization.md#column-virtualization)):\n * the center zone renders a windowed slice of columns between two spacer cols; pinned columns\n * stay mounted. Widths are the width engine's exact pixels, so there is nothing to estimate.\n */\n virtualizedColumns?: boolean | { overscan?: number };\n onEndReached?: () => void;\n endReachedOffset?: number;\n loadingMore?: boolean;\n /**\n * The last `onEndReached` load failed — replaces the trailing loader row with the message\n * (`true` uses `labels.loadMoreError`) and a retry button that fires `onEndReached` again.\n */\n loadMoreError?: boolean | ReactNode;\n\n /* State presentation */\n loading?: boolean;\n emptyState?: ReactNode;\n /**\n * Loading the data failed — shows an error panel over the body (`true` uses `labels.error`;\n * a node replaces the message). Takes precedence over the empty state.\n */\n error?: boolean | ReactNode;\n /**\n * Renders a retry button in the error panel.\n */\n onRetry?: () => void;\n\n /* Chrome */\n /**\n * Renders the column header region. Turning it off takes the header's own affordances with\n * it — sort controls, filter popovers, resize handles, drag reordering — so name the table\n * some other way ([accessibility.md](../docs/accessibility.md)).\n */\n withColumnHeaders?: boolean;\n withPaginationBar?: boolean;\n pageSizeOptions?: number[];\n\n /* Row interaction */\n /**\n * A literal primary click on the row. Pointer-only by definition — reach for `onRowActivate`\n * when the intent is \"the user chose this row\", so the keyboard reaches it too.\n */\n onRowClick?: (row: Row<TData>, event: MouseEvent) => void;\n /**\n * The row was activated, whatever the input device: a primary click, or `Enter` on the\n * current row while `enableActiveRow` is on ([rows.md](../docs/rows.md#active-row)).\n */\n onRowActivate?: (row: Row<TData>, event: MouseEvent | ReactKeyboardEvent) => void;\n onRowDoubleClick?: (row: Row<TData>, event: MouseEvent) => void;\n onRowContextMenu?: (row: Row<TData>, event: MouseEvent) => void;\n\n /* DOM escape hatches (docs/styling.md#dom-props) */\n /**\n * DOM props for every data row — static, or per row. Synthetic rows (detail panels, loader\n * and skeleton rows) have no `Row` subject and never receive them.\n */\n rowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, Row<TData>>;\n /**\n * DOM props for every header row — static, or per header group (grouped columns render one\n * row per level).\n */\n headerRowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, HeaderGroup<TData>>;\n /**\n * DOM props for every footer row — static, or per footer group.\n */\n footerRowProps?: DataTableElementProps<Omit<TableTrProps, \"ref\">, HeaderGroup<TData>>;\n /**\n * DOM props for the internal scroll viewport — `onScroll`, `data-*`, extra styles. Host\n * vocabulary: `ScrollArea.viewportProps`. ledger owns its scroll listener, its overscroll\n * behavior and (with `enableActiveRow`) its keyboard handling; those compose rather than\n * being replaced.\n */\n viewportProps?: Omit<ComponentProps<\"div\">, \"ref\"> & DataAttributes;\n\n labels?: Partial<DataTableLabels>;\n\n /**\n * Replacements for the chrome's glyphs, merged over the defaults per slot — `lucide-react`\n * components slot in as-is (docs/styling.md#icons).\n */\n icons?: Partial<DataTableIcons>;\n\n /**\n * Imperative handle: `{ table, viewport, scrollToRow, scrollToIndex, scrollToColumn, startEditing, stopEditing }`.\n */\n handleRef?: Ref<DataTableHandle<TData>>;\n}\n\n/**\n * Data source — a discriminated pair: a hook-mode instance XOR inline behavior options.\n */\nexport type DataTableProps<TData extends RowData = RowData> = DataTableBaseProps<TData>\n & (\n | ({ table: TableInstance<TData> } & { data?: never; columns?: never })\n | ({ table?: never } & UseDataTableOptions<TData>)\n );\n\nexport type DataTableFactory = Factory<{\n props: DataTableProps;\n ref: HTMLDivElement;\n stylesNames: DataTableStylesNames;\n vars: DataTableCssVariables;\n signature: <TData extends RowData>(props: DataTableProps<TData>) => JSX.Element;\n staticComponents: {\n Search: typeof DataTableSearch;\n ColumnsPanel: typeof DataTableColumnsPanel;\n Pagination: typeof DataTablePagination;\n SelectionBar: typeof DataTableSelectionBar;\n };\n}>;\n\nconst defaultProps = {\n striped: false,\n highlightOnHover: false,\n withTableBorder: false,\n withColumnBorders: false,\n withRowBorders: true,\n verticalSpacing: \"xs\",\n horizontalSpacing: \"xs\",\n tabularNums: false,\n virtualizedRows: false,\n virtualizedColumns: false,\n endReachedOffset: 240,\n loadingMore: false,\n loading: false,\n withColumnHeaders: true,\n withPaginationBar: true,\n pageSizeOptions: DEFAULT_PAGE_SIZE_OPTIONS\n} satisfies Partial<DataTableProps>;\n\nfunction leafCol(column: { id: string }) {\n return <col key={column.id} style={{ width: `var(${columnWidthVar(column.id)})` }} />;\n}\n\nconst varsResolver = createVarsResolver<DataTableFactory>(\n (theme, {\n stripedColor,\n highlightOnHoverColor,\n borderColor,\n radius\n }) => {\n return {\n root: {\n \"--ledger-striped-color\": stripedColor ? getThemeColor(stripedColor, theme) : undefined,\n \"--ledger-hover-color\": highlightOnHoverColor\n ? getThemeColor(highlightOnHoverColor, theme)\n : undefined,\n // The frame border around header + body lives outside both tables (docs/styling.md).\n \"--ledger-border-color\": borderColor ? getThemeColor(borderColor, theme) : undefined,\n // Rounds root and frame alike (docs/styling.md); absent, the stylesheet's `0` stands.\n \"--ledger-radius\": radius === undefined ? undefined : getRadius(radius)\n }\n };\n }\n);\n\n// ------------------------------------------------------------------------------------------------\n// Option-key partition — sugar mode splits behavior options from presentation props\n// ----------------------------------------------------------------------------------------------\n\nconst OPTION_KEYS = [\n \"data\",\n \"columns\",\n \"getRowId\",\n \"enableSorting\",\n \"enableMultiSort\",\n \"enableSortingRemoval\",\n \"enableColumnFilters\",\n \"enableGlobalFilter\",\n \"enablePagination\",\n \"enableRowSelection\",\n \"enableMultiRowSelection\",\n \"enableColumnResizing\",\n \"enableColumnPinning\",\n \"enableColumnOrdering\",\n \"enableHiding\",\n \"enableEditing\",\n \"enableGrouping\",\n \"enableRowPinning\",\n \"enableCellSpanning\",\n \"getSubRows\",\n \"renderDetailPanel\",\n \"selectionColumn\",\n \"expanderColumn\",\n \"enableRowOrdering\",\n \"onRowReorder\",\n \"rowDragColumn\",\n \"sortingMode\",\n \"filterMode\",\n \"paginationMode\",\n \"rowCount\",\n \"editTrigger\",\n \"editMode\",\n \"onEditCommit\",\n \"onRowEditCommit\",\n \"editingRowId\",\n \"onEditingRowIdChange\",\n \"enableActiveRow\",\n \"activeRowId\",\n \"defaultActiveRowId\",\n \"onActiveRowIdChange\",\n \"sorting\",\n \"defaultSorting\",\n \"onSortingChange\",\n \"columnFilters\",\n \"defaultColumnFilters\",\n \"onColumnFiltersChange\",\n \"globalFilter\",\n \"defaultGlobalFilter\",\n \"onGlobalFilterChange\",\n \"pagination\",\n \"defaultPagination\",\n \"onPaginationChange\",\n \"rowSelection\",\n \"defaultRowSelection\",\n \"onRowSelectionChange\",\n \"expanded\",\n \"defaultExpanded\",\n \"onExpandedChange\",\n \"columnVisibility\",\n \"defaultColumnVisibility\",\n \"onColumnVisibilityChange\",\n \"columnPinning\",\n \"defaultColumnPinning\",\n \"onColumnPinningChange\",\n \"columnOrder\",\n \"defaultColumnOrder\",\n \"onColumnOrderChange\",\n \"columnSizing\",\n \"defaultColumnSizing\",\n \"onColumnSizingChange\",\n \"grouping\",\n \"defaultGrouping\",\n \"onGroupingChange\",\n \"rowPinning\",\n \"defaultRowPinning\",\n \"onRowPinningChange\",\n \"editingCell\",\n \"onEditingCellChange\",\n \"persistState\",\n \"defaultColumn\",\n \"filterFns\",\n \"tableOptions\"\n] as const satisfies ReadonlyArray<keyof UseDataTableOptions<RowData>>;\n\n/**\n * Compile-time exhaustiveness: adding an option without listing it above is a type error.\n */\ntype MissingOptionKeys = Exclude<keyof UseDataTableOptions<RowData>, (typeof OPTION_KEYS)[number]>;\n\ntype AssertNever<T extends never> = T;\n\n// AssertNever<MissingOptionKeys> is `never` while the list is exhaustive; a forgotten key turns\n// it into a constraint violation right here.\nconst OPTION_KEY_SET: ReadonlySet<string> = new Set<AssertNever<MissingOptionKeys> | string>(OPTION_KEYS);\n\n// ------------------------------------------------------------------------------------------------\n// Component\n// ----------------------------------------------------------------------------------------------\n\nfunction DataTableRoot<TData extends RowData>(_props: DataTableProps<TData>) {\n const props = useProps(\"DataTable\", defaultProps as Partial<DataTableProps<TData>>, _props);\n\n if (props.table) {\n const { table, ...presentation } = props;\n\n return (\n <DataTableCore\n presentation={presentation as DataTableBaseProps<TData>}\n stylesProps={props}\n table={table}\n />\n );\n }\n\n return <DataTableFromOptions props={props} />;\n}\n\nexport const DataTable = genericFactory<DataTableFactory>(DataTableRoot);\n\ninterface RoutedProps<TData extends RowData> {\n presentation: DataTableBaseProps<TData>;\n /**\n * Everything the component was given, after `useProps`. The Styles API's callbacks are typed\n * with the component's whole props and Mantine hands them exactly that — so the behaviour half,\n * which the partition below routes to `useDataTable` and keeps off the DOM, still has to reach\n * `useStyles`. Only the DOM partition is `presentation`.\n */\n stylesProps: DataTableProps<TData>;\n table: TableInstance<TData>;\n}\n\n/**\n * The rows and the naming column of one committed render, in the shape the handlers that answer\n * for the screen need them (docs/architecture.md).\n */\nexport interface DisplaySnapshot<TData extends RowData> {\n /**\n * Every row on screen, in display order — pinned top, the page, pinned bottom. What the\n * keyboard steps through and what the announcement counts.\n */\n ordered: Array<Row<TData>>;\n /**\n * The unpinned zone alone, which is what the virtualizer indexes.\n */\n centerRows: Array<Row<TData>>;\n topRows: Array<Row<TData>>;\n bottomRows: Array<Row<TData>>;\n /**\n * The page's own row model — what `scrollToIndex` counts through.\n */\n pageRows: Array<Row<TData>>;\n /**\n * The leading data column, whose accessor names a row for the announcement.\n */\n leadingColumn: Column<TData, unknown> | null;\n /**\n * Detail panels are on, so an expanded row owns a synthetic display item of its own.\n */\n withDetailPanels: boolean;\n}\n\n/**\n * Resolve a row against the exact list owned by the virtualizer. Pinned rows are mounted outside\n * that list, so they deliberately have no scroll index.\n */\nexport function resolveVirtualDisplayIndex<TData extends RowData>(\n snapshot: DisplaySnapshot<TData>,\n rowId: string\n): number | null {\n const pinned = [...snapshot.topRows, ...snapshot.bottomRows].some(row => row.id === rowId);\n\n if (pinned) {\n return null;\n }\n\n const index = buildDisplayRows(snapshot.centerRows, snapshot.withDetailPanels)\n .findIndex(displayRow => displayRow.kind === \"data\" && displayRow.row.id === rowId);\n\n return index === -1 ? null : index;\n}\n\nfunction DataTableFromOptions<TData extends RowData>({ props }: { props: DataTableProps<TData> }) {\n const options: Record<string, unknown> = {};\n const presentation: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n (OPTION_KEY_SET.has(key) ? options : presentation)[key] = value;\n }\n\n // The partition is exhaustive by construction (see the AssertNever check above).\n const table = useDataTable(options as unknown as UseDataTableOptions<TData>);\n\n return (\n <DataTableCore\n presentation={presentation as DataTableBaseProps<TData>}\n stylesProps={props}\n table={table}\n />\n );\n}\n\nfunction DataTableCore<TData extends RowData>({\n presentation,\n stylesProps,\n table\n}: RoutedProps<TData>) {\n const {\n striped,\n // Consumed by varsResolver from raw props; destructured only to keep them off the DOM node.\n stripedColor: _stripedColor,\n highlightOnHover,\n highlightOnHoverColor: _highlightOnHoverColor,\n withTableBorder,\n withColumnBorders,\n withRowBorders,\n borderColor: _borderColor,\n radius: _radius,\n verticalSpacing,\n horizontalSpacing,\n tabularNums,\n tableMinWidth,\n virtualizedRows,\n virtualizedColumns,\n onEndReached,\n endReachedOffset,\n loadingMore,\n loadMoreError,\n loading,\n emptyState,\n error,\n onRetry,\n withColumnHeaders,\n withPaginationBar,\n pageSizeOptions,\n onRowClick,\n onRowActivate,\n onRowDoubleClick,\n onRowContextMenu,\n rowProps,\n headerRowProps,\n footerRowProps,\n viewportProps,\n labels: labelsProp,\n icons: iconsProp,\n handleRef,\n ref: rootRef,\n classNames,\n styles,\n unstyled,\n vars,\n className,\n style,\n attributes,\n // The ARIA table is `main`, not the root — a name left on the root would describe a\n // roleless wrapper and never reach the table. Routed below, never duplicated.\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n ...others\n } = presentation;\n\n const getStyles = useStyles<DataTableFactory>({\n name: \"DataTable\",\n classes,\n props: stylesProps as DataTableProps,\n className,\n style,\n classNames,\n styles,\n unstyled,\n vars,\n attributes,\n varsResolver\n });\n\n /**\n * The Styles API, revised rather than mirrored.\n *\n * `useStyles` resolves theme, `classNames`, `styles`, `vars`, `attributes` and the props they\n * read on every render, and hands back a **new** getter each time. Putting that getter straight\n * into the context would rebuild the context value every render and leave nothing in the body\n * memoized; freezing it behind a ref instead — which this used to do — meant a real change never\n * reached the rows at all, and made the ref a render-phase write a discarded transition could\n * poison.\n *\n * So the getter is compared by what it *resolves*: every selector's className, style and\n * attributes, plus the provenance a per-call `options.style` is resolved against (this table\n * passes no other per-call option, and Mantine resolves that one through the theme alone).\n * Same answers, same getter — the rows never hear about it. Different answers, and this render's\n * getter becomes the context value, which is a context change and therefore reaches even a\n * memoized row. `Object.keys(classes)` is a constant 25-odd selectors, so the cost is per render,\n * never per row.\n */\n const stylesRevision = useStylesRevision(getStyles, STYLE_SELECTORS);\n\n const labels = useMemo(() => resolveLabels(labelsProp), [labelsProp]);\n const icons = useMemo(() => resolveIcons(iconsProp), [iconsProp]);\n\n /* ---- viewport ---- */\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const [viewport, setViewport] = useState<HTMLDivElement | null>(null);\n const assignViewport = useCallback((element: HTMLDivElement | null) => {\n viewportRef.current = element;\n setViewport(element);\n }, []);\n\n // ---- the width engine (docs/sizing.md) ----\n // Display order is pinned-aware (start + center + end) — header groups and row cells\n // already render in it, so the colgroup and every width/offset must follow the same order\n // (`getVisibleLeafColumns` alone ignores pinning). Stabilized by id signature so downstream\n // memos only recompute when the composition or order actually changes.\n const startLeafColumns = table.getStartVisibleLeafColumns();\n const endLeafColumns = table.getEndVisibleLeafColumns();\n const displayColumns = [\n ...startLeafColumns,\n ...table.getCenterVisibleLeafColumns(),\n ...endLeafColumns\n ];\n // Fresh numbers, never memoized off the signature: pinning the current first column changes\n // neither order nor composition, yet moves the zone boundary.\n const pinnedStartCount = startLeafColumns.length;\n const pinnedEndCount = endLeafColumns.length;\n const displayOrderSignature = JSON.stringify(displayColumns.map(column => column.id));\n const ledgerColumns = table.options.meta?.ledger?.columns;\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- the signature encodes order/composition; meta.ledger.columns identity covers definition swaps (options.columns re-resolves per v9 state tick)\n const visibleLeafColumns = useMemo(() => displayColumns, [displayOrderSignature, ledgerColumns]);\n const columnWidths = useColumnWidths(table, visibleLeafColumns, viewport, tableMinWidth);\n\n /* ---- virtualization config ---- */\n const virtualization: VirtualizationConfig | null = virtualizedRows\n ? {\n estimateHeight:\n typeof virtualizedRows === \"object\" && virtualizedRows.estimateHeight !== undefined\n ? virtualizedRows.estimateHeight\n : 44,\n overscan: typeof virtualizedRows === \"object\" && virtualizedRows.overscan !== undefined\n ? virtualizedRows.overscan\n : 8\n }\n : null;\n const virtualEnabled = virtualization !== null;\n\n /* ---- column window (docs/virtualization.md#column-virtualization) ---- */\n const columnVirtualizationEnabled = virtualizedColumns === true || typeof virtualizedColumns === \"object\";\n const centerColumnIds = useMemo(\n () => visibleLeafColumns\n .slice(pinnedStartCount, visibleLeafColumns.length - pinnedEndCount)\n .map(column => column.id),\n [visibleLeafColumns, pinnedStartCount, pinnedEndCount]\n );\n let pinnedStartWidth = 0;\n let pinnedEndWidth = 0;\n\n for (const [index, column] of visibleLeafColumns.entries()) {\n if (index < pinnedStartCount) {\n pinnedStartWidth += columnWidths.byId[column.id] ?? 0;\n } else if (index >= visibleLeafColumns.length - pinnedEndCount) {\n pinnedEndWidth += columnWidths.byId[column.id] ?? 0;\n }\n }\n\n const columnWindowRange = useColumnWindow({\n centerColumnIds,\n enabled: columnVirtualizationEnabled,\n overscan: typeof virtualizedColumns === \"object\" && virtualizedColumns.overscan !== undefined\n ? virtualizedColumns.overscan\n : DEFAULT_COLUMN_OVERSCAN,\n pinnedEndWidth,\n pinnedStartWidth,\n viewport,\n widths: columnWidths.byId\n });\n const displayIndexById = useMemo(\n () => new Map(visibleLeafColumns.map((column, index) => [column.id, index])),\n [visibleLeafColumns]\n );\n const columnWindow = useMemo<ColumnWindowView | null>(\n () => columnWindowRange && {\n ...columnWindowRange,\n centerCount: centerColumnIds.length,\n displayIndexById,\n pinnedEndCount,\n pinnedStartCount,\n totalLeafCount: visibleLeafColumns.length\n },\n [columnWindowRange, centerColumnIds.length, displayIndexById, pinnedEndCount, pinnedStartCount, visibleLeafColumns.length]\n );\n\n /* ---- row interaction handlers with stable identities ---- */\n const rowClickStable = useEventCallback(onRowClick);\n const rowActivateStable = useEventCallback(onRowActivate);\n const rowDoubleClickStable = useEventCallback(onRowDoubleClick);\n const rowContextMenuStable = useEventCallback(onRowContextMenu);\n\n // The context depends on each handler's EXISTENCE, never its identity — the stable wrappers\n // absorb per-render inline arrows, so a fresh `onRowClick` prop must not rebuild the context\n // value (and with it every memoized row). The `*Props` hooks stay raw below: their return\n // values feed the render, so identity is their honest dependency.\n const contextRowClick = onRowClick ? (rowClickStable as DataTableContextValue[\"onRowClick\"]) : undefined;\n const contextRowActivate = onRowActivate\n ? (rowActivateStable as DataTableContextValue[\"onRowActivate\"])\n : undefined;\n const contextRowDoubleClick = onRowDoubleClick\n ? (rowDoubleClickStable as DataTableContextValue[\"onRowDoubleClick\"])\n : undefined;\n const contextRowContextMenu = onRowContextMenu\n ? (rowContextMenuStable as DataTableContextValue[\"onRowContextMenu\"])\n : undefined;\n\n // Normalized once: the prop defaults to true, so an absent value must not read as \"off\" at\n // any of its three use sites (the context, the ARIA row numbering, the render).\n const columnHeadersVisible = withColumnHeaders !== false;\n\n const filterMode: \"client\" | \"server\" = table.options.manualFiltering ? \"server\" : \"client\";\n\n /* The documented single TData erasure (context.ts) — the render layer below is `any`-bound. */\n const erasedTable = table as TableInstance<any>;\n\n // Read from THIS render's wrapper, whose `options` is its own object — never from the shared\n // core, and never mirrored into a ref during render. Each of these is stable for as long as\n // the instance lives, so naming them individually is what lets the context value hold while\n // the wrapper identity changes on every state tick (context.ts).\n const ledger = table.options.meta?.ledger;\n const editing = ledger?.editing;\n const activeRowEnabled = ledger?.activeRow.enabled === true;\n const activeRowId = ledger?.activeRow.id ?? null;\n const setActiveRow = ledger?.activeRow.set;\n const subscribeColumnFilters = ledger?.filtering.subscribeColumnFilters;\n const commands = ledgerCommands(ledger);\n const selectionCommands = commands?.selection;\n const expansionCommands = commands?.expansion;\n\n const instanceId = useId();\n\n // ---- column geometry: the width engine resolves every column to exact integer pixels,\n // written as CSS variables (a resize updates variables, never re-renders rows) ----\n const tableState = table.state;\n\n const columnVars = useMemo(() => {\n const varsMap: Record<string, string> = {};\n let leftOffset = 0;\n\n for (const column of visibleLeafColumns) {\n const width = columnWidths.byId[column.id] ?? 0;\n varsMap[columnWidthVar(column.id)] = `${width}px`;\n\n if (column.getIsPinned() === \"start\") {\n varsMap[columnStartVar(column.id)] = `${leftOffset}px`;\n leftOffset += width;\n }\n }\n\n let rightOffset = 0;\n\n for (let index = visibleLeafColumns.length - 1; index >= 0; index -= 1) {\n const column = visibleLeafColumns[index]!;\n\n if (column.getIsPinned() === \"end\") {\n varsMap[columnAfterVar(column.id)] = `${rightOffset}px`;\n rightOffset += columnWidths.byId[column.id] ?? 0;\n }\n }\n\n return varsMap;\n // getIsPinned reads the pinning slice — columnPinning is its identity in the deps.\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- see comment above\n }, [visibleLeafColumns, columnWidths, tableState.columnPinning]);\n\n // The one colgroup all three synced tables share. Under a column window the hidden center\n // runs collapse into two spacer cols with the exact widths the missing columns add up to, so\n // the table keeps its full scroll width and the pinned offsets stay honest.\n const colElements = columnWindow === null\n ? visibleLeafColumns.map(column => leafCol(column))\n : [\n ...visibleLeafColumns.slice(0, pinnedStartCount).map(column => leafCol(column)),\n columnWindow.start > 0\n && <col key=\"ledger:spacer-leading\" data-ledger-spacer style={{ width: columnWindow.leadingSpace }} />,\n ...visibleLeafColumns\n .slice(pinnedStartCount + columnWindow.start, pinnedStartCount + columnWindow.end)\n .map(column => leafCol(column)),\n columnWindow.end < columnWindow.centerCount\n && <col key=\"ledger:spacer-trailing\" data-ledger-spacer style={{ width: columnWindow.trailingSpace }} />,\n ...pinnedEndCount === 0 ? [] : visibleLeafColumns.slice(-pinnedEndCount).map(column => leafCol(column))\n ];\n\n /* ---- data flags ---- */\n const rowsLength = table.getRowModel().rows.length;\n const errorActive = Boolean(error) && !loading;\n const isEmpty = !loading && !errorActive && rowsLength === 0;\n // Zero rows with an active filter is \"nothing matched\", not \"no data\" — a different message.\n const filtersActive = tableState.columnFilters.length > 0 || tableState.globalFilter !== \"\";\n const paginationEnabled = table.options.meta?.ledger?.enablePagination === true;\n const skeletonRowCount = Math.min(Math.max(tableState.pagination.pageSize, 3), 12);\n\n /* ---- infinite loading ---- */\n // Keyed on the data's identity, not its length: a server-side filter or sort can hand back a\n // different page of the same size, and a length guard would then never re-arm. Consumers\n // already keep `data` referentially stable per snapshot (docs/api.md), so a new array is\n // exactly \"new data\".\n const lastEndReachedData = useRef<unknown>(null);\n const currentData = table.options.data;\n const hasEndReachedHandler = Boolean(onEndReached);\n\n const maybeFireEndReached = useEventCallback(() => {\n const element = viewportRef.current;\n\n // clientHeight 0 = not laid out yet; distance math would fire a phantom page load.\n if (!element || element.clientHeight === 0 || !onEndReached || loading || loadingMore) {\n return;\n }\n\n if (lastEndReachedData.current === currentData) {\n return;\n }\n\n const distance = element.scrollHeight - element.scrollTop - element.clientHeight;\n\n if (distance <= (endReachedOffset ?? 240)) {\n lastEndReachedData.current = currentData;\n onEndReached();\n }\n });\n\n useEffect(() => {\n // Next frame: the virtualizer's first measurement commit must settle before the\n // \"content shorter than the viewport\" check can mean anything.\n const frame = requestAnimationFrame(() => maybeFireEndReached());\n\n return () => cancelAnimationFrame(frame);\n // Each of these can turn a viewport that could not ask for more into one that can: new data,\n // a viewport that just appeared, a load that finished, or a handler mounted after the fact.\n // Probing only on data length left short content stranded with no way to reach the bottom.\n }, [currentData, viewport, loading, loadingMore, hasEndReachedHandler, maybeFireEndReached]);\n\n // Retry re-arms the once-per-data guard — the failed attempt consumed it.\n const retryLoadMore = useEventCallback(() => {\n lastEndReachedData.current = null;\n onEndReached?.();\n });\n\n /* ---- pinned-edge shadows ---- */\n const [scrollEdges, setScrollEdges] = useState({ start: false, end: false });\n\n const updateScrollEdges = useEventCallback(() => {\n const element = viewportRef.current;\n\n if (!element) {\n return;\n }\n\n const max = element.scrollWidth - element.clientWidth;\n const offset = Math.abs(element.scrollLeft);\n const next = { start: offset > 1, end: max > 1 && offset < max - 1 };\n\n setScrollEdges(previous => previous.start === next.start && previous.end === next.end ? previous : next);\n });\n\n /* ---- the header and footer viewports mirror the body's horizontal scroll ---- */\n const headerViewportRef = useRef<HTMLDivElement | null>(null);\n const footerViewportRef = useRef<HTMLDivElement | null>(null);\n const hasFooter = tableHasFooter(table);\n // No header region means no header rows — every aria-rowindex downstream counts from 0.\n const headerRowCount = columnHeadersVisible ? table.getHeaderGroups().length : 0;\n const withDetailPanels = Boolean(ledger?.renderDetailPanel);\n const rowPinningActive = table.options.enableRowPinning === true;\n /**\n * The zones this render draws, read once here. Each array is TanStack-memoized, so holding\n * them costs nothing per scroll step — and every handler below answers from them instead of\n * asking the table again when the key is pressed. A row model reached for at event time is\n * the shared core's, which carries whatever pass rendered last, a discarded one included\n * (docs/architecture.md).\n */\n const pageRows = table.getRowModel().rows;\n const topRows = rowPinningActive ? table.getTopRows() : NO_ARIA_ROWS;\n const bottomRows = rowPinningActive ? table.getBottomRows() : NO_ARIA_ROWS;\n const centerRows = rowPinningActive ? table.getCenterRows() : pageRows;\n // Counting, not building: this runs on every render of a component the virtualizer also\n // re-renders, and three throwaway arrays per scroll step is the same O(rows) cost twice over.\n const logicalDisplayRowCount\n = rowPinningActive\n ? countDisplayRows(topRows, withDetailPanels)\n + countDisplayRows(centerRows, withDetailPanels)\n + countDisplayRows(bottomRows, withDetailPanels)\n : countDisplayRows(pageRows, withDetailPanels);\n\n /**\n * The leading DATA column of the display order — what names a row to a screen reader. The\n * injected columns hold controls, not identity.\n */\n // The first column that can actually name a row: a leading display column (a row number, an\n // actions cluster) has no accessor and would leave every announcement nameless.\n const leadingColumn = useMemo(\n () => visibleLeafColumns.find(column => !isInternalColumn(column.id) && column.accessorFn !== undefined) ?? null,\n [visibleLeafColumns]\n );\n\n /**\n * One object so a `useEventCallback` closure carries the whole display in a single binding:\n * mirrored in an insertion effect, it is always the snapshot of the render that reached the\n * screen (utils.ts). Keyed on the row models themselves — sorting, filtering or paging moves\n * the current row, changes the total, and can take it off the page altogether.\n */\n const displaySnapshot = useMemo<DisplaySnapshot<TData>>(\n () => {\n return {\n bottomRows,\n centerRows,\n leadingColumn,\n ordered: rowPinningActive ? [...topRows, ...centerRows, ...bottomRows] : centerRows,\n pageRows,\n topRows,\n withDetailPanels\n };\n },\n [topRows, centerRows, bottomRows, pageRows, leadingColumn, rowPinningActive, withDetailPanels]\n );\n const bodyAriaRowCount\n = loading && logicalDisplayRowCount === 0\n ? skeletonRowCount\n : logicalDisplayRowCount + (loadMoreError || loadingMore ? 1 : 0);\n // The rendered rows, not every mirrored header level — `aria-rowcount` must match the DOM.\n const footerRowCount = visibleFooterGroups(table).length;\n const ariaRowCount = headerRowCount + bodyAriaRowCount + footerRowCount;\n const footerAriaRowIndexStart = headerRowCount + bodyAriaRowCount + 1;\n\n const mirrorBodyScrollLeft = useEventCallback(() => {\n const element = viewportRef.current;\n\n if (!element) {\n return;\n }\n\n for (const mirror of [headerViewportRef.current, footerViewportRef.current]) {\n if (mirror && mirror.scrollLeft !== element.scrollLeft) {\n // Assigned inside the scroll event, before paint — all regions move in the same frame.\n mirror.scrollLeft = element.scrollLeft;\n }\n }\n });\n\n useEffect(() => {\n updateScrollEdges();\n mirrorBodyScrollLeft();\n }, [viewport, columnVars, hasFooter, updateScrollEdges, mirrorBodyScrollLeft]);\n\n // A dominantly horizontal wheel over the header or footer belongs to the body scroller;\n // vertical-leaning wheels bubble on so the page keeps scrolling naturally.\n useEffect(() => {\n const regions = [headerViewportRef.current, footerViewportRef.current].filter(\n (region): region is HTMLDivElement => region !== null\n );\n\n if (regions.length === 0) {\n return;\n }\n\n const forwardWheel = (event: WheelEvent) => {\n const element = viewportRef.current;\n\n if (!element || Math.abs(event.deltaX) <= Math.abs(event.deltaY)) {\n return;\n }\n\n element.scrollLeft += event.deltaX;\n // Consumed — without this the delta would also scroll a horizontal ancestor.\n event.preventDefault();\n };\n\n // React root wheel listeners are passive; preventDefault needs native non-passive ones.\n for (const region of regions) {\n region.addEventListener(\"wheel\", forwardWheel, { passive: false });\n }\n\n return () => {\n for (const region of regions) {\n region.removeEventListener(\"wheel\", forwardWheel);\n }\n };\n }, [hasFooter]);\n\n const handleScrollPositionChange = useEventCallback(() => {\n mirrorBodyScrollLeft();\n maybeFireEndReached();\n updateScrollEdges();\n });\n\n /* ---- imperative handle ---- */\n const virtualizerRef = useRef<Virtualizer<HTMLDivElement, Element> | null>(null);\n const handleVirtualizerChange = useCallback(\n (virtualizer: Virtualizer<HTMLDivElement, Element> | null) => {\n virtualizerRef.current = virtualizer;\n },\n []\n );\n\n const scrollRowIntoView = useEventCallback(\n (rowId: string, options?: DataTableScrollOptions) => {\n const virtualizer = virtualizerRef.current;\n\n if (virtualizer) {\n const index = resolveVirtualDisplayIndex(displaySnapshot, rowId);\n\n if (index !== null) {\n virtualizer.scrollToIndex(index, {\n align: options?.align ?? \"auto\",\n behavior: options?.behavior\n });\n }\n\n return;\n }\n\n const selector = `[data-row-id=\"${typeof CSS === \"undefined\" ? rowId.replaceAll(\"\\\"\", String.raw`\\\"`) : CSS.escape(rowId)}\"]`;\n const rowElement = viewportRef.current?.querySelector<HTMLElement>(`:scope ${selector}`);\n\n rowElement?.scrollIntoView({\n behavior: options?.behavior,\n block: options?.align === undefined || options.align === \"auto\" ? \"nearest\" : options.align\n });\n }\n );\n\n /**\n * The index counts through the page's own row model — the rows the table holds, before the\n * display order interleaves pinned rows and detail panels around them.\n */\n const scrollIndexIntoView = useEventCallback(\n (index: number, options?: DataTableScrollOptions) => {\n const rowId = displaySnapshot.pageRows[index]?.id;\n\n if (rowId !== undefined) {\n scrollRowIntoView(rowId, options);\n }\n }\n );\n\n /**\n * Pure width-engine math, no DOM measurement: the column's center-zone offset from the same\n * prefix numbers the window uses, against the strip the pinned overlays leave visible. Works\n * with or without a column window — the target column need not be rendered to be reachable.\n */\n const scrollColumnIntoView = useEventCallback(\n (columnId: string, options?: DataTableScrollOptions) => {\n const element = viewportRef.current;\n const index = displayIndexById.get(columnId);\n\n if (!element || index === undefined) {\n return;\n }\n\n // Pinned columns are sticky — always in view, nothing to scroll.\n if (index < pinnedStartCount || index >= visibleLeafColumns.length - pinnedEndCount) {\n return;\n }\n\n let offset = 0;\n\n for (let i = pinnedStartCount; i < index; i += 1) {\n offset += columnWidths.byId[visibleLeafColumns[i]!.id] ?? 0;\n }\n\n const width = columnWidths.byId[columnId] ?? 0;\n const strip = Math.max(0, element.clientWidth - pinnedStartWidth - pinnedEndWidth);\n const current = Math.abs(element.scrollLeft);\n const align = options?.align ?? \"auto\";\n let target: number;\n\n switch (align) {\n case \"start\": {\n target = offset;\n\n break;\n }\n\n case \"end\": {\n target = offset + width - strip;\n\n break;\n }\n\n case \"center\": {\n target = offset + (width - strip) / 2;\n\n break;\n }\n\n default: { if (offset >= current && offset + width <= current + strip) {\n return;\n }\n\n target = offset < current ? offset : offset + width - strip; }\n }\n\n target = Math.max(0, target);\n // RTL viewports scroll into negative territory; the math above is direction-agnostic.\n const rtl = getComputedStyle(element).direction === \"rtl\";\n element.scrollTo({ behavior: options?.behavior, left: rtl ? -target : target });\n }\n );\n\n useImperativeHandle(\n handleRef,\n () => {\n return {\n table,\n get viewport() {\n return viewportRef.current;\n },\n scrollToRow: scrollRowIntoView,\n scrollToIndex: scrollIndexIntoView,\n scrollToColumn: scrollColumnIntoView,\n startEditing: (rowId, columnId) => {\n const editing = table.options.meta?.ledger?.editing;\n\n if (!editing) {\n return;\n }\n\n if (editing.mode === \"row\") {\n editing.row.start(rowId, columnId === undefined ? undefined : { focusColumnId: columnId });\n } else if (columnId === undefined) {\n warnOnce(\"start-editing-column\", \"startEditing needs a columnId in cell mode.\");\n } else {\n editing.start({ rowId, columnId });\n }\n },\n stopEditing: options => {\n const editing = table.options.meta?.ledger?.editing;\n\n if (editing?.mode === \"row\") {\n editing.row.stop(options);\n } else {\n editing?.stop(options);\n }\n }\n };\n },\n [table, scrollRowIntoView, scrollIndexIntoView, scrollColumnIntoView]\n );\n\n /* ---- active row keyboard (docs/rows.md): the body viewport is the focus stop ---- */\n const activeRowAnnouncer = useRef<HTMLSpanElement>(null);\n const rowNavigationHintId = `${instanceId}-row-navigation`;\n // The keyboard model describes the element that actually takes focus — a description is read\n // out for the focused node, and the ARIA table never is one. `aria-describedby` is a global\n // property that any element may carry: `generic` prohibits an accessible *name*, not a\n // description, and referencing an id adds no role and owns nothing. The consumer's own\n // description stays on the table; theirs on the viewport keeps the first read there.\n const viewportDescribedBy = activeRowEnabled\n ? [viewportProps?.[\"aria-describedby\"], rowNavigationHintId].filter(Boolean).join(\" \")\n : viewportProps?.[\"aria-describedby\"];\n\n // Runs once per change of the current row rather than once per render: the row lookup is a\n // scan, and this component re-renders on every scroll step of a virtualized table.\n const announceActiveRow = useEventCallback(() => {\n const target = activeRowAnnouncer.current;\n\n if (!target) {\n return;\n }\n\n if (activeRowId === null) {\n target.textContent = \"\";\n\n return;\n }\n\n const { ordered, leadingColumn: leading } = displaySnapshot;\n const index = ordered.findIndex(row => row.id === activeRowId);\n\n if (index === -1) {\n target.textContent = \"\";\n\n return;\n }\n\n // Through the leading column's own accessor, never `row.getValue`: that resolves the column\n // through `row.table` — the shared core — and reads a cache the row only rebuilds when the\n // data changes (use-committed-table.ts).\n const row = ordered[index] as Row<TData>;\n const value = leading === null ? \"\" : String(leading.accessorFn?.(row.original, row.index) ?? \"\");\n\n target.textContent = labels.currentRow(value === \"\" ? activeRowId : value, index + 1, ordered.length);\n });\n\n useEffect(() => {\n if (activeRowEnabled) {\n announceActiveRow();\n }\n // The snapshot is the dependency in its own right, not the row id: sorting, filtering or\n // paging changes the current row's position, the total, and even whether it is still on the\n // page, and hiding or reordering a column can rename the row without moving it. An id-only\n // dependency would leave the last announcement standing after any of that.\n }, [activeRowId, activeRowEnabled, displaySnapshot, labels, announceActiveRow]);\n\n const handleActiveRowKeyDown = useEventCallback((event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (!activeRowEnabled || !setActiveRow) {\n return;\n }\n\n // Keys inside an interactive child (an editor, a checkbox, the retry button) belong to it.\n if ((event.target as HTMLElement).closest(\"input, button, select, textarea, a, [contenteditable]\")) {\n return;\n }\n\n // F2 is the one key here that needs no row list. The row it acts on is the active-row slice,\n // and where it opens is the editing controller's answer for the render that reached the\n // screen — so a render nobody saw cannot empty the table out from under it. The keys below\n // move *through* the rows the table holds, which is a different question and still asks the\n // core (docs/architecture.md).\n //\n // There is no cell cursor, so the row's first editable cell is the entry point — the cell to\n // edit in cell mode, the cell to focus in row mode; the pattern defines F2 as placing focus\n // in an input, so both modes land the caret somewhere. What a checkbox column is depends on\n // the mode, and so does whether it can be that entry point: in cell mode it commits on toggle\n // and never hosts an editor; in row mode it is a draft-bound editor like any other, and a row\n // whose only editable column is one would otherwise never open at all.\n if (event.key === \"F2\") {\n if (!editing || activeRowId === null) {\n return;\n }\n\n const rowMode = editing.mode === \"row\";\n const target = editing.firstEditable(activeRowId, !rowMode);\n\n if (target === null) {\n return;\n }\n\n event.preventDefault();\n\n if (rowMode) {\n editing.row.start(activeRowId, { focusColumnId: target });\n } else {\n editing.start({ rowId: activeRowId, columnId: target });\n }\n\n return;\n }\n\n const rows = displaySnapshot.ordered;\n\n if (rows.length === 0) {\n return;\n }\n\n const currentIndex = activeRowId === null ? -1 : rows.findIndex(row => row.id === activeRowId);\n\n const moveTo = (index: number) => {\n const row = rows[Math.min(Math.max(index, 0), rows.length - 1)];\n\n if (row) {\n setActiveRow(row.id);\n scrollRowIntoView(row.id);\n }\n };\n\n switch (event.key) {\n case \"ArrowDown\": {\n event.preventDefault();\n moveTo(currentIndex + 1);\n\n break;\n }\n\n case \"ArrowUp\": {\n event.preventDefault();\n moveTo(currentIndex - 1);\n\n break;\n }\n\n case \"Home\": {\n event.preventDefault();\n moveTo(0);\n\n break;\n }\n\n case \"End\": {\n event.preventDefault();\n moveTo(rows.length - 1);\n\n break;\n }\n\n case \"Enter\": {\n const row = currentIndex >= 0 ? rows[currentIndex] : null;\n\n // Only `onRowActivate` is input-agnostic. `onRowClick` stays literal — synthesizing a\n // MouseEvent for it would make its own type signature a lie.\n if (row && onRowActivate) {\n event.preventDefault();\n onRowActivate(row as Row<TData>, event);\n }\n\n break;\n }\n\n // The WAI-APG grid pattern's dedicated edit key. Enter is spoken for here (it activates\n // the row), which is exactly the overload F2 exists to resolve.\n // No default\n }\n });\n\n /* ---- dev guard rails ---- */\n if (paginationEnabled && onEndReached) {\n warnOnce(\n \"pagination-and-end-reached\",\n \"enablePagination and onEndReached are configured together — pagination and infinite loading are mutually exclusive.\"\n );\n }\n\n useEffect(() => {\n if (!virtualEnabled || !viewport || rowsLength <= 50) {\n return;\n }\n\n // Next frame: judged only after the virtualizer's first measurement commit has painted,\n // otherwise the still-empty tbody reads as \"content fits\" and false-alarms.\n const frame = requestAnimationFrame(() => {\n if (viewport.clientHeight > 0 && viewport.scrollHeight <= viewport.clientHeight + 4) {\n warnOnce(\n \"virtualized-unconstrained\",\n \"virtualizedRows is set but the viewport is unconstrained (its height equals the content height) — give the table or an ancestor a definite height.\"\n );\n }\n });\n\n return () => cancelAnimationFrame(frame);\n }, [virtualEnabled, viewport, rowsLength]);\n\n /* ---- render ---- */\n const stripedMode = striped === true ? \"odd\" : striped || undefined;\n\n // Header and body render as separate tables so the vertical scroller owns only the body:\n // identical props, colgroup, and root-level column variables keep their layouts pixel-equal.\n // Semantics come from the ARIA table on `main` — the native tables are presentational.\n // Row/column borders are ledger-owned at cell level (docs/styling.md), so the border props\n // become root data-attributes instead of Mantine Table props.\n const sharedTableProps = {\n horizontalSpacing,\n layout: \"fixed\" as const,\n role: \"presentation\" as const,\n tabularNums,\n verticalSpacing\n };\n // Exact table width (the engine's total) — the browser never redistributes column widths;\n // `border-collapse: separate` is inline because the host's unlayered `collapse` would win,\n // and collapse drops borders on stuck sticky cells (docs/styling.md).\n const tableStyleProps = () => getStyles(\"table\", {\n style: {\n width: columnWidths.total > 0 ? columnWidths.total : undefined,\n minWidth: toPx(tableMinWidth),\n borderCollapse: \"separate\" as const,\n borderSpacing: 0\n }\n });\n\n /* ---- row reordering session (docs/rows.md#row-ordering) ---- */\n const rowOrderingEnabled = ledger?.rowOrdering.enabled === true;\n\n // The same naming the active-row announcement uses — the leading column's own accessor over\n // the committed row — falling back to the row id rather than announcing a nameless lift.\n const nameReorderRow = useEventCallback((row: Row<TData>) => {\n const leading = displaySnapshot.leadingColumn;\n const value = leading === null ? \"\" : String(leading.accessorFn?.(row.original, row.index) ?? \"\");\n\n return value === \"\" ? row.id : value;\n });\n const centerRowsForReorder = useEventCallback(() => displaySnapshot.centerRows);\n const scrollReorderTargetIntoView = useEventCallback((rowId: string) => scrollRowIntoView(rowId));\n\n const rowReorder = useRowReorder<TData>({\n onRowReorder: ledger?.rowOrdering.onRowReorder,\n labels,\n viewportRef,\n getCenterRows: centerRowsForReorder,\n nameRow: nameReorderRow,\n scrollToRow: scrollReorderTargetIntoView\n });\n\n const contextValue = useMemo<DataTableContextValue>(\n () => {\n return {\n activeRowEnabled,\n setActiveRow,\n rowReorderKeyboard: rowOrderingEnabled ? rowReorder.keyboard : undefined,\n selection: selectionCommands,\n expansion: expansionCommands,\n subscribeColumnFilters,\n instanceId,\n getStyles: stylesRevision,\n labels,\n icons,\n filterMode,\n virtualizedRows: virtualEnabled,\n withColumnHeaders: columnHeadersVisible,\n onRowClick: contextRowClick,\n onRowActivate: contextRowActivate,\n onRowDoubleClick: contextRowDoubleClick,\n onRowContextMenu: contextRowContextMenu,\n rowProps: rowProps as DataTableContextValue[\"rowProps\"],\n headerRowProps: headerRowProps as DataTableContextValue[\"headerRowProps\"],\n footerRowProps: footerRowProps as DataTableContextValue[\"footerRowProps\"]\n };\n },\n [\n activeRowEnabled,\n setActiveRow,\n rowOrderingEnabled,\n rowReorder.keyboard,\n selectionCommands,\n expansionCommands,\n subscribeColumnFilters,\n instanceId,\n stylesRevision,\n labels,\n icons,\n filterMode,\n virtualEnabled,\n columnHeadersVisible,\n contextRowClick,\n contextRowActivate,\n contextRowDoubleClick,\n contextRowContextMenu,\n rowProps,\n headerRowProps,\n footerRowProps\n ]\n );\n\n return (\n <DataTableProvider value={contextValue}>\n <RowReorderScope session={rowOrderingEnabled ? rowReorder : null}>\n <Box\n ref={rootRef}\n data-empty={isEmpty || undefined}\n data-error={errorActive || undefined}\n data-highlight-on-hover={highlightOnHover || undefined}\n data-loading={loading || undefined}\n data-scrolled-end={scrollEdges.end || undefined}\n data-scrolled-start={scrollEdges.start || undefined}\n data-striped={stripedMode}\n data-virtualized-columns={columnWindow !== null || undefined}\n data-virtualized-rows={virtualEnabled || undefined}\n data-with-column-borders={withColumnBorders || undefined}\n data-with-row-borders={withRowBorders || undefined}\n data-with-table-border={withTableBorder || undefined}\n {...getStyles(\"root\", { style: columnVars })}\n {...others}\n >\n {activeRowEnabled && (\n <>\n {/* Focus never leaves the viewport when the arrow keys move the current row, so the\n move is visual only unless it is spoken. Written imperatively: a live region wants\n a text change, not a React re-render of the table. Both of these sit outside\n `role=\"table\"` — a table may only own rows. */}\n <VisuallyHidden ref={activeRowAnnouncer} aria-live=\"polite\" role=\"status\" />\n {/* The text the focus stop points at. It sits out here rather than inside the\n table because `aria-describedby` resolves by id from anywhere, while a stray\n element inside `role=\"table\"` would not. */}\n <VisuallyHidden id={rowNavigationHintId}>{labels.rowNavigation}</VisuallyHidden>\n </>\n )}\n\n <div\n // On the element that is the table: `aria-busy` is defined for the widget whose\n // content is being updated, and the root carries no role for it to qualify.\n aria-busy={loading || undefined}\n aria-colcount={columnWindow === null ? undefined : columnWindow.totalLeafCount}\n aria-describedby={ariaDescribedBy}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-rowcount={virtualEnabled ? ariaRowCount : undefined}\n role=\"table\"\n {...getStyles(\"main\")}\n >\n {columnHeadersVisible && (\n <div ref={headerViewportRef} {...getStyles(\"header\")}>\n <MantineTable {...sharedTableProps} {...tableStyleProps()}>\n <colgroup>{colElements}</colgroup>\n\n <TableHeader\n columnSizing={tableState.columnSizing}\n columnWidths={columnWidths.byId}\n columnWindow={columnWindow}\n table={erasedTable}\n />\n </MantineTable>\n </div>\n )}\n\n {/* overscroll-behavior: none — rubber-band overscroll translates the body past its\n clamped scroll position, which the mirrored header/footer can never follow; the\n regions shear apart for the duration of the bounce.\n Transparent track/corner — Mantine tints them on hover through unlayered rules\n that defeat any layered override, so inline is the only seat that wins; the thumb\n is its own element and keeps its background. */}\n <ScrollArea\n {...getStyles(\"scroller\")}\n scrollbars=\"xy\"\n type=\"hover\"\n viewportRef={assignViewport}\n styles={{\n corner: { backgroundColor: \"transparent\" },\n scrollbar: { backgroundColor: \"transparent\" }\n }}\n viewportProps={mergeElementProps(viewportProps, {\n style: { overscrollBehavior: \"none\" as const },\n // With the active row on, the body viewport is the keyboard focus stop, and it\n // carries the description of the keyboard model (`rowNavigationHintId`, composed\n // after any the consumer passed). Deliberately unnamed: this div is `generic`, a\n // role that prohibits an accessible name, and it cannot take a role either —\n // that would break `table`'s owned rows. It stays the focus stop so the browser's\n // own scrolling keys keep reaching the scroller.\n \"aria-describedby\": viewportDescribedBy,\n ...activeRowEnabled && { tabIndex: 0, onKeyDown: handleActiveRowKeyDown }\n })}\n onScrollPositionChange={handleScrollPositionChange}\n >\n <MantineTable {...sharedTableProps} {...tableStyleProps()}>\n <colgroup>{colElements}</colgroup>\n\n <TableBody\n columnWindow={columnWindow}\n loading={loading === true}\n loadingMore={loadingMore === true}\n loadMoreError={loadMoreError ?? false}\n reorderSourceId={rowOrderingEnabled ? rowReorder.sourceId : null}\n reorderTarget={rowOrderingEnabled ? rowReorder.target : null}\n skeletonRowCount={skeletonRowCount}\n table={erasedTable}\n viewportRef={viewportRef}\n virtualization={virtualization}\n onLoadMoreRetry={onEndReached ? retryLoadMore : undefined}\n onVirtualizerChange={handleVirtualizerChange}\n />\n </MantineTable>\n\n {isEmpty && (\n // Polite, not assertive: filtering a table down to nothing is worth announcing,\n // but it must not interrupt the typing that caused it.\n <div\n {...getStyles(\"empty\")}\n data-variant={filtersActive ? \"no-results\" : \"no-data\"}\n role=\"status\"\n >\n {emptyState ?? (\n <EmptyState\n withIndicatorBackground\n size=\"sm\"\n styles={EMPTY_STATE_STYLES}\n title={filtersActive ? labels.noResults : labels.empty}\n // The indicator forces the svg to 1em (40px at `sm`), so the stroke is set for\n // that scale — the default (2, drawn for Lucide's 24px grid) turns chunky here.\n icon={filtersActive\n ? <icons.noResults size={40} strokeWidth={1.5} />\n : <icons.empty size={40} strokeWidth={1.5} />}\n />\n )}\n </div>\n )}\n\n {errorActive && (\n <div\n {...getStyles(\"empty\")}\n data-over-rows={rowsLength > 0 || undefined}\n data-variant=\"error\"\n role=\"alert\"\n >\n <EmptyState\n withIndicatorBackground\n icon={<icons.error size={40} strokeWidth={1.5} />}\n size=\"sm\"\n styles={EMPTY_STATE_STYLES}\n title={error === true ? labels.error : error}\n >\n {onRetry && (\n <Button\n leftSection={<icons.retry size={14} />}\n size=\"xs\"\n variant=\"light\"\n onClick={onRetry}\n >\n {labels.retry}\n </Button>\n )}\n </EmptyState>\n </div>\n )}\n </ScrollArea>\n\n {hasFooter && (\n <div ref={footerViewportRef} {...getStyles(\"footer\")}>\n <MantineTable {...sharedTableProps} {...tableStyleProps()}>\n <colgroup>{colElements}</colgroup>\n\n <TableFooter\n ariaRowIndexStart={virtualEnabled ? footerAriaRowIndexStart : undefined}\n columnWindow={columnWindow}\n table={erasedTable}\n />\n </MantineTable>\n </div>\n )}\n </div>\n\n {loading && rowsLength > 0 && <LoadingOverlay visible overlayProps={{ blur: 1 }} zIndex={20} />}\n\n {paginationEnabled && withPaginationBar\n && <PaginationBar pageSizeOptions={pageSizeOptions ?? DEFAULT_PAGE_SIZE_OPTIONS} table={table} />}\n </Box>\n </RowReorderScope>\n </DataTableProvider>\n );\n}\n\nDataTable.displayName = \"@coldsmirk/ledger-mantine/DataTable\";\nDataTable.classes = classes;\nDataTable.Search = DataTableSearch;\nDataTable.ColumnsPanel = DataTableColumnsPanel;\nDataTable.Pagination = DataTablePagination;\nDataTable.SelectionBar = DataTableSelectionBar;\n","import type { ComboboxData } from \"@mantine/core\";\n\nimport type { DataTableEditRenderer, DataTableInstantEditRenderer } from \"./types\";\n\n/**\n * The shipped editor renderers — conveniences, never the mechanism. Each is an ordinary\n * renderer over the public editing contexts (docs/editing.md#editors), which is the proof the\n * contexts suffice: anything these do, an application's own renderer can do the same way.\n * All are default-variant Mantine inputs — the border marks the cell as an open editor.\n */\nimport { Checkbox, NumberInput, Select, TextInput } from \"@mantine/core\";\n\nconst renderTextEditor: DataTableEditRenderer<any, any> = ({\n value,\n setValue,\n error,\n pending,\n autoFocus,\n label\n}) => (\n <TextInput\n aria-label={label}\n autoFocus={autoFocus}\n disabled={pending}\n error={error}\n size=\"xs\"\n value={value === null || value === undefined ? \"\" : String(value)}\n onChange={event => setValue(event.currentTarget.value)}\n />\n);\n\n/**\n * A plain text editor: `meta.edit: textEditor()`.\n */\nexport function textEditor(): DataTableEditRenderer<any, any> {\n return renderTextEditor;\n}\n\nconst renderNumberEditor: DataTableEditRenderer<any, any> = ({\n value,\n setValue,\n error,\n pending,\n autoFocus,\n label\n}) => (\n <NumberInput\n hideControls\n aria-label={label}\n autoFocus={autoFocus}\n disabled={pending}\n error={error}\n size=\"xs\"\n value={typeof value === \"number\" || typeof value === \"string\" ? value : \"\"}\n onChange={next => setValue(next === \"\" ? null : next)}\n />\n);\n\n/**\n * A numeric editor; an emptied input holds `null`, never `0`.\n */\nexport function numberEditor(): DataTableEditRenderer<any, any> {\n return renderNumberEditor;\n}\n\n/**\n * A single-pick editor over the given options. In cell mode the dropdown opens immediately and\n * picking an option commits at once — one cell is the whole session; in row mode it is one\n * draft-bound field among the row's others, and the row's own commit decides.\n */\nexport function selectEditor(options: ComboboxData): DataTableEditRenderer<any, any> {\n return ({\n value,\n setValue,\n commit,\n error,\n pending,\n mode,\n autoFocus,\n label\n }) => (\n <Select\n aria-label={label}\n autoFocus={autoFocus}\n comboboxProps={{ withinPortal: true }}\n data={options}\n defaultDropdownOpened={mode === \"cell\"}\n disabled={pending}\n error={error}\n size=\"xs\"\n value={value === null || value === undefined ? null : String(value)}\n onChange={next => {\n setValue(next);\n\n if (mode === \"cell\") {\n void commit();\n }\n }}\n />\n );\n}\n\nconst renderCheckboxEditor: DataTableInstantEditRenderer<any, any> = ({\n value,\n commit,\n pending,\n error,\n label\n}) => (\n <Checkbox\n aria-label={label}\n checked={Boolean(value)}\n disabled={pending}\n // Styles only — the instant host renders the message in its own alert region.\n error={Boolean(error)}\n size=\"xs\"\n onChange={event => void commit(event.currentTarget.checked)}\n />\n);\n\n/**\n * A live checkbox for an instant column: `meta.edit: { instant: checkboxEditor() }`. Each\n * toggle commits the flipped value; the host disables it while its own write is out.\n */\nexport function checkboxEditor(): DataTableInstantEditRenderer<any, any> {\n return renderCheckboxEditor;\n}\n"],"mappings":"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"}