argus-table 0.3.0 → 0.4.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.
- package/dist/argus-column-group.js +66 -0
- package/dist/argus-column-group.js.map +1 -0
- package/dist/argus-column.js +4 -25
- package/dist/argus-column.js.map +1 -1
- package/dist/argus-table.js +553 -200
- package/dist/argus-table.js.map +1 -1
- package/dist/attributes.js +21 -0
- package/dist/attributes.js.map +1 -0
- package/dist/cdn/argus-table.js +92 -57
- package/dist/cdn/argus-table.js.map +1 -1
- package/dist/column-registry.js +23 -0
- package/dist/column-registry.js.map +1 -0
- package/dist/controllers/auto-width.js +6 -5
- package/dist/controllers/auto-width.js.map +1 -1
- package/dist/controllers/column-children.js +32 -9
- package/dist/controllers/column-children.js.map +1 -1
- package/dist/controllers/column-window.js +0 -4
- package/dist/controllers/column-window.js.map +1 -1
- package/dist/controllers/plugins.js +25 -6
- package/dist/controllers/plugins.js.map +1 -1
- package/dist/controllers/reorder-drag.js +12 -9
- package/dist/controllers/reorder-drag.js.map +1 -1
- package/dist/controllers/row-measure.js +2 -1
- package/dist/controllers/row-measure.js.map +1 -1
- package/dist/controllers/virtual-controller.js +25 -32
- package/dist/controllers/virtual-controller.js.map +1 -1
- package/dist/core/src/columns/column-groups.js +129 -0
- package/dist/core/src/columns/column-groups.js.map +1 -0
- package/dist/core/src/columns/column-order.js +125 -31
- package/dist/core/src/columns/column-order.js.map +1 -1
- package/dist/core/src/columns/resolve-columns.js +0 -1
- package/dist/core/src/columns/resolve-columns.js.map +1 -1
- package/dist/core/src/columns/spread-width.js +43 -0
- package/dist/core/src/columns/spread-width.js.map +1 -0
- package/dist/core/src/filters/filter.js +6 -8
- package/dist/core/src/filters/filter.js.map +1 -1
- package/dist/core/src/grid/row-layout.js +19 -11
- package/dist/core/src/grid/row-layout.js.map +1 -1
- package/dist/core/src/state/selection.js +2 -1
- package/dist/core/src/state/selection.js.map +1 -1
- package/dist/core/src/table/create-table.js +57 -22
- package/dist/core/src/table/create-table.js.map +1 -1
- package/dist/core/src/table/sorted-row-model.js.map +1 -1
- package/dist/core/src/virtual/row-sizes.js +0 -4
- package/dist/core/src/virtual/row-sizes.js.map +1 -1
- package/dist/custom-elements.json +489 -245
- package/dist/events.js +16 -16
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +273 -127
- package/dist/index.js +3 -2
- package/dist/render/body.js +2 -2
- package/dist/render/body.js.map +1 -1
- package/dist/render/cells.js +11 -3
- package/dist/render/cells.js.map +1 -1
- package/dist/render/content-directive.js +1 -1
- package/dist/render/content-directive.js.map +1 -1
- package/dist/render/content.js +15 -3
- package/dist/render/content.js.map +1 -1
- package/dist/render/header.js +82 -19
- package/dist/render/header.js.map +1 -1
- package/dist/styles/base.js +1 -1
- package/dist/styles/base.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-table.js","names":[],"sources":["../../../../../core/src/table/create-table.ts"],"sourcesContent":["import {\n columnSizingFeature,\n constructTable,\n rowSortingFeature,\n sortFn_alphanumeric,\n sortFn_basic,\n sortFn_datetime,\n sortFn_text,\n tableFeatures,\n type ColumnDef as TanStackColumnDef,\n type Row,\n type Table,\n type TableOptions,\n} from '@tanstack/table-core';\nimport { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings';\nimport { moveColumn, normalizeOrder } from '../columns/column-order.js';\nimport { resolveColumns, type ResolvedColumn } from '../columns/resolve-columns.js';\nimport { distinctValues, rowPredicate } from '../filters/filter.js';\nimport { filteredRowModel, setRowPredicate } from './filtered-row-model.js';\nimport { sortedRowModel, valuesChanged } from './sorted-row-model.js';\nimport type {\n CellContext,\n ColumnAlign,\n ColumnDef,\n ColumnFilter,\n ColumnFilterState,\n ColumnOrderState,\n ColumnPin,\n ColumnPinningState,\n ColumnSizingState,\n ColumnVisibilityState,\n FilterKind,\n FilterValue,\n PinnedRows,\n RowPin,\n SortState,\n} from '../types.js';\n\n// The TanStack adapter. Everything TanStack stays in this module: callers only see\n// the view types below, so TanStack can be upgraded or replaced without touching\n// `argus-table`'s public API.\n\nconst features = tableFeatures({\n // Vanilla (framework-free) reactivity; required by `constructTable`.\n coreReactivityFeature: storeReactivityBindings(),\n // No pinning, ordering or visibility feature: the model groups, orders and hides\n // columns itself (see `buildViews`), so they cost no bundle size.\n columnSizingFeature,\n rowSortingFeature,\n // Our own filtering, without TanStack's filtering feature (see filtered-row-model.ts).\n // TanStack's types tie this slot to that feature; at runtime the core row models read it.\n ...({ filteredRowModel: filteredRowModel() } as object),\n // Our own: TanStack's is very slow in Firefox at scale (see sorted-row-model.ts).\n sortedRowModel: sortedRowModel(),\n // Registered by name so `sortFn: 'auto'` can pick one by value type.\n sortFns: {\n alphanumeric: sortFn_alphanumeric,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n },\n});\ntype Features = typeof features;\ntype AnyRow = Record<string, unknown>;\n\n/** Sort direction of a column, or `false` when it isn't sorted. */\nexport type SortDirection = 'asc' | 'desc' | false;\n\n/**\n * Id of the selection column, the checkbox column the model adds first when\n * `selectionColumn` is set. Not a column of `columns`: it never appears in the\n * column order, sizing or events.\n */\nexport const SELECTION_COLUMN_ID = '--argus-selection';\n\n/** Width of the selection column in px. */\nexport const SELECTION_COLUMN_WIDTH = 40;\n\n/** A column as the renderer sees it, in visual order: start-pinned, scrolling, end-pinned. */\nexport interface ColumnView<TData, TContent> {\n id: string;\n /** `'data'` for a column of `columns`; `'selection'` for the checkbox column. */\n kind: 'data' | 'selection';\n /** 1-based position in visual order, for `aria-colindex`. `0` for a hidden column. */\n colIndex: number;\n /** The pin in effect: `columnPinning`'s, else the column's own. */\n pin: ColumnPin | undefined;\n /**\n * Sticky inset in px: from the start edge for `'start'` columns, from the end edge\n * for `'end'` columns. For scrolling columns, the start within the scrolling area.\n */\n offset: number;\n /** `true` on the pinned column next to the scrolling area (one per pinned side). */\n pinEdge: boolean;\n /**\n * `true` for a hidden column. Only `allColumns` lists hidden columns; `columns`\n * holds the ones the table shows.\n */\n hidden: boolean;\n /** Current width in px (a resized width wins over the column's own). */\n width: number;\n /** Share of free space, or `undefined` for a fixed width. A resized column stops flexing. */\n flex: number | undefined;\n /**\n * `true` for a `width: 'auto'` column that hasn't been resized: the table measures\n * its content and passes the width in as `autoWidths`.\n */\n auto: boolean;\n minWidth: number;\n maxWidth: number;\n sortable: boolean;\n resizable: boolean;\n reorderable: boolean;\n pinnable: boolean;\n hideable: boolean;\n /** The kind of filter users can set, or `undefined` when they can't filter the column. */\n filter: FilterKind | undefined;\n /** `true` when `columnFilters` has a filter for the column. */\n filtered: boolean;\n align: ColumnAlign;\n /** Whether the cell text wraps (`ColumnDef.wrap`). */\n wrap: boolean;\n sorted: SortDirection;\n header: ColumnDef<TData, TContent>['header'];\n cell: ColumnDef<TData, TContent>['cell'];\n hasAccessor: boolean;\n}\n\n/** A row of the current (filtered and sorted) row model. */\nexport interface RowView<TData> {\n id: string;\n /** Index in the current row model, 0-based. */\n index: number;\n original: TData;\n}\n\n/**\n * Rows that live outside the model, loaded page by page (`dataSource`). The\n * source sorts them, so the model reads them as they are. `PageCache` implements it.\n */\nexport interface RemoteRows<TData> {\n readonly rowCount: number;\n /** The loaded row at an index, with its id; `undefined` while it isn't loaded. */\n entryAt(index: number): { id: string; row: TData } | undefined;\n /** The index of a loaded row's id, or `undefined`. */\n indexOf(rowId: string): number | undefined;\n /** The ids of every loaded row, in row order. */\n loadedIds(): string[];\n}\n\nexport interface TableModelOptions<TData, TContent> {\n columns: readonly ColumnDef<TData, TContent>[];\n data: readonly TData[];\n /**\n * Remote rows. When set, rows come from here instead of `data`, and the model\n * doesn't sort them (the source does).\n */\n remote?: RemoteRows<TData> | undefined;\n /** Row id function. Default: the row's index in `data`, as a string. */\n getRowId: ((row: TData, index: number) => string) | undefined;\n /** Current sort state; its owner is the caller (see `controllable`). */\n sorting: SortState;\n /** Current resized widths; its owner is the caller. */\n columnSizing: ColumnSizingState;\n /**\n * Current column order; its owner is the caller. Each pin group follows it; an\n * empty array (the default) keeps the order of `columns`.\n */\n columnOrder?: ColumnOrderState | undefined;\n /** Pins set at runtime, over the columns' own `pin`; its owner is the caller. */\n columnPinning?: ColumnPinningState | undefined;\n /** Visibility set at runtime, over the columns' own `hidden`; its owner is the caller. */\n columnVisibility?: ColumnVisibilityState | undefined;\n /**\n * Column filters; its owner is the caller. Rows that fail one leave the row model.\n * Remote rows aren't filtered: the source does it.\n */\n columnFilters?: ColumnFilterState | undefined;\n /**\n * Words to find in the shown columns' values as text, ignoring case: a row stays\n * when each word is in one of its values. Remote rows aren't filtered.\n */\n quickFilter?: string | undefined;\n /**\n * Measured widths of `width: 'auto'` columns, in px by id. Clamped to the column's\n * bounds; a resized width wins. Ids of other columns are ignored.\n */\n autoWidths?: ColumnSizingState | undefined;\n /** Rows fixed above or below the body. They stay out of the row model: never sorted, not counted. */\n pinnedRows?: PinnedRows<TData> | undefined;\n /**\n * Adds the selection (checkbox) column first among the start-pinned columns. It\n * has the id `SELECTION_COLUMN_ID`, a fixed width, and no part in sorting,\n * sizing or the column order.\n */\n selectionColumn?: boolean | undefined;\n}\n\nexport interface TableModel<TData, TContent> {\n /** Updates any subset of the options. Unchanged references are ignored. */\n update(options: Partial<TableModelOptions<TData, TContent>>): void;\n /** The columns the table shows, in visual order. */\n readonly columns: readonly ColumnView<TData, TContent>[];\n /**\n * Every column of `columns`, hidden ones included (with `hidden: true` and\n * `colIndex: 0`), in the order of `orderOf()`. Not the selection column.\n */\n readonly allColumns: readonly ColumnView<TData, TContent>[];\n /** Number of rows in the current row model. */\n readonly rowCount: number;\n /**\n * Changes identity whenever the row at an index may have changed: new data, a\n * sort, a filter, a new remote source. Compare it by identity only.\n */\n readonly rowOrder: object;\n /** Sum of the shown columns' widths in px (flex columns count their minimum). */\n readonly totalWidth: number;\n /** The row at an index of the current row model; `undefined` for a remote row not loaded yet. */\n rowAt(index: number): RowView<TData> | undefined;\n /** The index of a row id in the current row model (after filtering and sorting), or `undefined`. */\n indexOf(rowId: string): number | undefined;\n /**\n * The ids of the rows that can be selected, in row order: every row of the row\n * model, or only the loaded ones for remote rows.\n */\n selectableIds(): string[];\n /** The value a column reads from the row at `index`. */\n valueAt(index: number, columnId: string): unknown;\n /** What a column's `cell` function receives for the row at `index`. */\n cellContext(index: number, columnId: string): CellContext<TData> | undefined;\n /**\n * The sort state that clicking this column's header would produce:\n * asc → desc → unsorted, one column at a time. `undefined` if it can't sort.\n */\n nextSorting(columnId: string): SortState | undefined;\n /**\n * The sizing state after setting a column to `width` px, clamped to its bounds.\n * `undefined` if the column can't be resized.\n */\n nextSizing(columnId: string, width: number): ColumnSizingState | undefined;\n /**\n * The full column order as the table shows it: start-pinned, scrolling and\n * end-pinned ids. `base` defaults to the current `columnOrder`.\n */\n orderOf(base?: readonly string[]): ColumnOrderState;\n /**\n * The order after moving a column to position `to` (0-based among the shown data\n * columns, in visual order, counted after the move; hidden columns keep their place),\n * starting from `base` (default: the current order). `undefined` if the column can't\n * move or is hidden, `to` is outside its pin group, or nothing changes.\n */\n nextOrder(columnId: string, to: number, base?: readonly string[]): ColumnOrderState | undefined;\n /**\n * The pinning state after pinning a column to a side, or unpinning it with `false`,\n * starting from `base` (default: the current `columnPinning`). `undefined` for an\n * unknown column, one with `pinnable: false`, or no change.\n */\n nextPinning(\n columnId: string,\n pin: ColumnPin | false,\n base?: ColumnPinningState,\n ): ColumnPinningState | undefined;\n /**\n * The visibility state after hiding or showing a column, starting from `base`\n * (default: the current `columnVisibility`). `undefined` for an unknown column,\n * hiding one with `hideable: false` or the last one shown, or no change.\n */\n nextVisibility(\n columnId: string,\n hidden: boolean,\n base?: ColumnVisibilityState,\n ): ColumnVisibilityState | undefined;\n /**\n * The filter state after setting a column's filter, or clearing it with `undefined`,\n * starting from `base` (default: the current `columnFilters`). `undefined` for an\n * unknown column, setting a filter on a column without `filter`, or no change.\n */\n nextFilters(\n columnId: string,\n filter: ColumnFilter | undefined,\n base?: ColumnFilterState,\n ): ColumnFilterState | undefined;\n /**\n * The values a `'set'` filter on the column offers: its `filterOptions`, else (not for\n * remote rows) the distinct values of the rows the other filters keep, sorted, at most\n * `limit` of them (`truncated` when there are more). `undefined` for an unknown column,\n * or remote rows without `filterOptions`.\n */\n filterValues(\n columnId: string,\n limit?: number,\n ): { values: FilterValue[]; truncated: boolean } | undefined;\n /** Number of rows pinned to a side. */\n pinnedCount(side: RowPin): number;\n /**\n * A pinned row, `index` counted within its side. Its id comes from `getRowId`,\n * else it is `'top-{index}'` or `'bottom-{index}'`, apart from the data rows' index ids.\n */\n pinnedRowAt(side: RowPin, index: number): RowView<TData> | undefined;\n /** The value a column reads from a pinned row. */\n pinnedValueAt(side: RowPin, index: number, columnId: string): unknown;\n /** What a column's `cell` function receives for a pinned row (with `pinned` set). */\n pinnedCellContext(side: RowPin, index: number, columnId: string): CellContext<TData> | undefined;\n}\n\nconst defaultRowId = (_row: unknown, index: number) => String(index);\n\n/**\n * Ids of the columns kept from `before` whose accessor changed: a new function,\n * or a different path. A new column has nothing cached and isn't listed.\n */\nfunction changedAccessors<TData, TContent>(\n before: readonly ColumnDef<TData, TContent>[],\n after: readonly ColumnDef<TData, TContent>[],\n): string[] {\n const old = new Map(before.map((c) => [c.id, c.accessor]));\n return after.filter((c) => old.has(c.id) && old.get(c.id) !== c.accessor).map((c) => c.id);\n}\n\n/** The selection column's view: first, pinned to the start, fixed, and inert to sorting, sizing and moves. */\nfunction selectionView<TData, TContent>(pinEdge: boolean): ColumnView<TData, TContent> {\n return {\n id: SELECTION_COLUMN_ID,\n kind: 'selection',\n colIndex: 1,\n pin: 'start',\n offset: 0,\n pinEdge,\n hidden: false,\n width: SELECTION_COLUMN_WIDTH,\n flex: undefined,\n auto: false,\n minWidth: SELECTION_COLUMN_WIDTH,\n maxWidth: SELECTION_COLUMN_WIDTH,\n sortable: false,\n resizable: false,\n reorderable: false,\n pinnable: false,\n hideable: false,\n filter: undefined,\n filtered: false,\n align: 'center',\n wrap: false,\n sorted: false,\n header: undefined,\n cell: undefined,\n hasAccessor: false,\n };\n}\n\nfunction toTanStack<TData, TContent>(\n column: ResolvedColumn<TData, TContent>,\n): TanStackColumnDef<Features, AnyRow> {\n return {\n id: column.id,\n accessorFn: column.getValue as (row: AnyRow, index: number) => unknown,\n size: column.width,\n minSize: column.minWidth,\n maxSize: column.maxWidth,\n enableSorting: column.sortable,\n sortUndefined: 'last',\n };\n}\n\n/**\n * Creates the table model over TanStack Table. It owns no state: sorting, sizing, order,\n * pinning and visibility come in through `update()`, and the `next*()` methods only propose\n * changes, so the caller decides (controlled or uncontrolled) whether to apply them.\n *\n * Hidden columns stay in TanStack, so their values still sort and read; only the\n * views leave them out. Pin groups, sticky offsets and the order are the model's own.\n */\nexport function createTableModel<TData, TContent>(\n initial: TableModelOptions<TData, TContent>,\n): TableModel<TData, TContent> {\n let options = initial;\n let resolved = resolveColumns(options.columns);\n let byId = new Map(resolved.map((c) => [c.id, c]));\n // TanStack column defs by id, kept between updates that don't change `columns`.\n let tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));\n let views: ColumnView<TData, TContent>[] | undefined;\n // The pin and visibility in effect: the state's, else the column's own.\n const pinOf = (\n column: ResolvedColumn<TData, TContent>,\n pinning = options.columnPinning,\n ): ColumnPin | undefined => {\n const state = pinning?.[column.id];\n if (state === 'start' || state === 'end') return state;\n return state === false ? undefined : column.pin;\n };\n const hiddenOf = (\n column: ResolvedColumn<TData, TContent>,\n visibility = options.columnVisibility,\n ): boolean => {\n const state = visibility?.[column.id];\n return typeof state === 'boolean' ? !state : column.hidden;\n };\n const shown = (id: string) => {\n const column = byId.get(id);\n return column !== undefined && !hiddenOf(column);\n };\n // TanStack's sizing state: measured auto widths and the widths of pinned flex columns\n // under the resized ones. Kept stable between updates that don't touch them.\n let sizing: ColumnSizingState | undefined;\n const sizingState = (): ColumnSizingState => {\n if (sizing) return sizing;\n const auto = options.autoWidths;\n const merged: ColumnSizingState = {};\n let any = false;\n for (const column of resolved) {\n // A pinned column can't flex: it takes a fixed width for its sticky offsets.\n if (column.flex !== undefined && pinOf(column) !== undefined) {\n merged[column.id] = column.pinnedWidth;\n any = true;\n }\n const px = auto?.[column.id];\n if (!column.auto || px === undefined || !Number.isFinite(px)) continue;\n merged[column.id] = Math.min(column.maxWidth, Math.max(column.minWidth, px));\n any = true;\n }\n return (sizing = any ? { ...merged, ...options.columnSizing } : options.columnSizing);\n };\n // What ordering needs, with the pin in effect.\n const orderable = () =>\n resolved.map((c) => ({ id: c.id, pin: pinOf(c), reorderable: c.reorderable }));\n // The normalized order, kept stable between updates that touch neither columns,\n // order nor pinning.\n let order: ColumnOrderState | undefined;\n const orderState = (): ColumnOrderState =>\n (order ??= normalizeOrder(options.columnOrder ?? [], orderable()));\n const rowViews = new WeakMap<Row<Features, AnyRow>, RowView<TData>>();\n // Built lazily per row model (sorting or new data gives a new array).\n let indexById: { rows: readonly Row<Features, AnyRow>[]; map: Map<string, number> } | undefined;\n\n // TanStack gets its column defs in the order, hidden ones included. Rebuilt only when\n // the order changes: a new columns array makes TanStack rebuild its columns, though\n // not its row models, which depend on data and sorting alone.\n let ordered:\n { order: ColumnOrderState; columns: TanStackColumnDef<Features, AnyRow>[] } | undefined;\n const orderedColumns = () => {\n const current = orderState();\n if (ordered?.order !== current) {\n ordered = { order: current, columns: current.flatMap((id) => tanStackById.get(id) ?? []) };\n }\n return ordered;\n };\n\n const tableOptions = (): TableOptions<Features, AnyRow> => ({\n features,\n columns: orderedColumns().columns,\n // Remote rows bypass TanStack's row models; it still handles columns and state.\n data: (options.remote ? [] : options.data) as AnyRow[],\n getRowId: (options.getRowId ?? defaultRowId) as (row: AnyRow, index: number) => string,\n state: {\n sorting: options.sorting,\n columnSizing: sizingState(),\n },\n // State is owned by the caller; TanStack's own setters must not change it.\n onSortingChange: () => undefined,\n onColumnSizingChange: () => undefined,\n });\n\n const table: Table<Features, AnyRow> = constructTable(tableOptions());\n\n // The row test of the filters, the quick filter and the shown columns (which the quick\n // filter reads). Remote rows are filtered by their source.\n const predicateFor = (except?: string) =>\n options.remote\n ? undefined\n : rowPredicate(\n byId,\n options.columnFilters,\n options.quickFilter,\n resolved.filter((c) => c.hasAccessor && !hiddenOf(c)),\n except,\n );\n setRowPredicate(table, predicateFor());\n\n const rows = () => table.getRowModel().rows;\n const pinned = (side: RowPin): readonly TData[] => options.pinnedRows?.[side] ?? [];\n\n const widthOf = (id: string) => table.getColumn(id)?.getSize() ?? 0;\n const view = (\n def: ResolvedColumn<TData, TContent>,\n colIndex: number,\n offset: number,\n pinEdge: boolean,\n width: number,\n ): ColumnView<TData, TContent> => {\n const sort = options.sorting.find((s) => s.id === def.id);\n const pin = pinOf(def);\n const resized = options.columnSizing[def.id] !== undefined;\n return {\n id: def.id,\n kind: 'data',\n colIndex,\n pin,\n offset,\n pinEdge,\n hidden: colIndex === 0,\n width,\n flex: pin === undefined && !resized ? def.flex : undefined,\n auto: def.auto && !resized,\n minWidth: def.minWidth,\n maxWidth: def.maxWidth,\n sortable: def.sortable,\n resizable: def.resizable,\n reorderable: def.reorderable,\n pinnable: def.pinnable,\n hideable: def.hideable,\n filter: def.filter,\n filtered: options.columnFilters?.[def.id] !== undefined,\n align: def.align,\n wrap: def.wrap,\n sorted: sort ? (sort.desc ? 'desc' : 'asc') : false,\n header: def.header,\n cell: def.cell,\n hasAccessor: def.hasAccessor,\n };\n };\n\n const buildViews = (): ColumnView<TData, TContent>[] => {\n const groups: Record<ColumnPin | 'center', ResolvedColumn<TData, TContent>[]> = {\n start: [],\n center: [],\n end: [],\n };\n for (const id of orderState()) {\n const def = byId.get(id);\n if (def && !hiddenOf(def)) groups[pinOf(def) ?? 'center'].push(def);\n }\n const { start, center, end } = groups;\n // The selection column comes first: it shifts every column one place on, and\n // the other start-pinned columns its width further from the start edge.\n const lead = options.selectionColumn ? 1 : 0;\n if (lead && byId.has(SELECTION_COLUMN_ID)) {\n throw new Error(`argus-table: the column id '${SELECTION_COLUMN_ID}' is reserved.`);\n }\n // Offsets: start columns from the start edge (after the selection column), the\n // scrolling ones within the scrolling area, end columns from the end edge.\n let x = lead * SELECTION_COLUMN_WIDTH;\n const list = start.map((def, i) => {\n const width = widthOf(def.id);\n const v = view(def, lead + i + 1, x, i === start.length - 1, width);\n x += width;\n return v;\n });\n x = 0;\n for (const [i, def] of center.entries()) {\n const width = widthOf(def.id);\n list.push(view(def, lead + start.length + i + 1, x, false, width));\n x += width;\n }\n const ends: ColumnView<TData, TContent>[] = [];\n x = 0;\n for (const [i, def] of [...end.entries()].reverse()) {\n const width = widthOf(def.id);\n ends.unshift(view(def, lead + start.length + center.length + i + 1, x, i === 0, width));\n x += width;\n }\n list.push(...ends);\n if (lead) list.unshift(selectionView(start.length === 0));\n return list;\n };\n\n let allViews: ColumnView<TData, TContent>[] | undefined;\n const buildAllViews = (shownViews: readonly ColumnView<TData, TContent>[]) => {\n const byShownId = new Map(shownViews.map((v) => [v.id, v]));\n return orderState().flatMap((id) => {\n const shownView = byShownId.get(id);\n if (shownView) return [shownView];\n const def = byId.get(id);\n return def ? [view(def, 0, 0, false, widthOf(id))] : [];\n });\n };\n\n return {\n update(next) {\n const merged = { ...options, ...next };\n const changed = (Object.keys(next) as (keyof typeof next)[]).some(\n (key) => next[key] !== options[key],\n );\n if (!changed) return;\n let reread: string[] = [];\n if (next.columns && next.columns !== options.columns) {\n reread = changedAccessors(options.columns, next.columns);\n resolved = resolveColumns(next.columns);\n byId = new Map(resolved.map((c) => [c.id, c]));\n tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));\n }\n const pinningChanged = merged.columnPinning !== options.columnPinning;\n if (\n merged.columns !== options.columns ||\n merged.columnSizing !== options.columnSizing ||\n merged.autoWidths !== options.autoWidths ||\n pinningChanged\n ) {\n sizing = undefined;\n }\n if (\n merged.columns !== options.columns ||\n merged.columnOrder !== options.columnOrder ||\n pinningChanged\n ) {\n order = undefined;\n }\n const refilter =\n merged.columns !== options.columns ||\n merged.columnFilters !== options.columnFilters ||\n merged.quickFilter !== options.quickFilter ||\n merged.columnVisibility !== options.columnVisibility ||\n merged.remote !== options.remote;\n options = merged;\n views = undefined;\n allViews = undefined;\n if (refilter) setRowPredicate(table, predicateFor());\n table.setOptions((prev) => ({ ...prev, ...tableOptions() }));\n if (reread.length && !options.remote) {\n // TanStack caches each value on its row by column id, and keeps rows\n // while the data is the same: drop the values of the columns that now\n // read differently, and sort again.\n for (const row of table.getCoreRowModel().rows) {\n for (const id of reread) Reflect.deleteProperty(row._valuesCache, id);\n }\n valuesChanged(table);\n }\n },\n\n get columns() {\n return (views ??= buildViews());\n },\n\n get allColumns() {\n return (allViews ??= buildAllViews(this.columns));\n },\n\n get rowCount() {\n return options.remote?.rowCount ?? rows().length;\n },\n get rowOrder() {\n return options.remote ?? rows();\n },\n\n get totalWidth() {\n return this.columns.reduce((sum, column) => sum + column.width, 0);\n },\n\n rowAt(index) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n return entry && { id: entry.id, index, original: entry.row };\n }\n const row = rows()[index];\n if (!row) return undefined;\n let view = rowViews.get(row);\n if (view?.index !== index) {\n view = { id: row.id, index, original: row.original as TData };\n rowViews.set(row, view);\n }\n return view;\n },\n\n indexOf(rowId) {\n if (options.remote) return options.remote.indexOf(rowId);\n const current = rows();\n if (indexById?.rows !== current) {\n indexById = { rows: current, map: new Map(current.map((r, i) => [r.id, i])) };\n }\n return indexById.map.get(rowId);\n },\n\n selectableIds() {\n if (options.remote) return options.remote.loadedIds();\n return rows().map((r) => r.id);\n },\n\n valueAt(index, columnId) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n return entry && byId.get(columnId)?.getValue(entry.row, index);\n }\n return rows()[index]?.getValue(columnId);\n },\n\n cellContext(index, columnId) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n const column = byId.get(columnId);\n if (!entry || !column) return undefined;\n return {\n row: entry.row,\n rowId: entry.id,\n index,\n columnId,\n value: column.getValue(entry.row, index),\n };\n }\n const row = rows()[index];\n if (!row || !byId.has(columnId)) return undefined;\n return {\n row: row.original as TData,\n rowId: row.id,\n index,\n columnId,\n value: row.getValue(columnId),\n };\n },\n\n nextSorting(columnId) {\n if (byId.get(columnId)?.sortable !== true) return undefined;\n const current = options.sorting.find((s) => s.id === columnId);\n if (!current) return [{ id: columnId, desc: false }];\n return current.desc ? [] : [{ id: columnId, desc: true }];\n },\n\n nextSizing(columnId, width) {\n const column = byId.get(columnId);\n if (!column?.resizable || !Number.isFinite(width)) return undefined;\n const clamped = Math.round(Math.min(column.maxWidth, Math.max(column.minWidth, width)));\n return { ...options.columnSizing, [columnId]: clamped };\n },\n\n orderOf(base) {\n return base === undefined ? orderState() : normalizeOrder(base, orderable());\n },\n\n nextOrder(columnId, to, base) {\n return moveColumn(base ?? orderState(), orderable(), columnId, to, shown);\n },\n\n nextPinning(columnId, pin, base = options.columnPinning) {\n const column = byId.get(columnId);\n if (!column?.pinnable || (pinOf(column, base) ?? false) === pin) return undefined;\n return { ...base, [columnId]: pin };\n },\n\n nextVisibility(columnId, hidden, base = options.columnVisibility) {\n const column = byId.get(columnId);\n if (!column || hiddenOf(column, base) === hidden) return undefined;\n const othersShown = resolved.some((c) => c !== column && !hiddenOf(c, base));\n if (hidden && (!column.hideable || !othersShown)) return undefined;\n return { ...base, [columnId]: !hidden };\n },\n\n nextFilters(columnId, filter, base = options.columnFilters ?? {}) {\n const column = byId.get(columnId);\n if (!column) return undefined;\n const current = base[columnId];\n if (filter === undefined) {\n if (current === undefined) return undefined;\n const next = { ...base };\n Reflect.deleteProperty(next, columnId);\n return next;\n }\n if (column.filter === undefined) return undefined;\n if (current && JSON.stringify(current) === JSON.stringify(filter)) return undefined;\n return { ...base, [columnId]: filter };\n },\n\n filterValues(columnId, limit = 1000) {\n const column = byId.get(columnId);\n if (!column) return undefined;\n if (column.filterOptions) return { values: [...column.filterOptions], truncated: false };\n if (options.remote) return undefined;\n const rows = table.getCoreRowModel().rows as unknown as Iterable<{\n original: TData;\n index: number;\n }>;\n return distinctValues(rows, column, predicateFor(columnId), limit);\n },\n\n pinnedCount(side) {\n return pinned(side).length;\n },\n\n pinnedRowAt(side, index) {\n if (index < 0 || index >= pinned(side).length) return undefined;\n const row = pinned(side)[index] as TData;\n const id = options.getRowId ? options.getRowId(row, index) : `${side}-${String(index)}`;\n return { id, index, original: row };\n },\n\n pinnedValueAt(side, index, columnId) {\n if (index < 0 || index >= pinned(side).length) return undefined;\n return byId.get(columnId)?.getValue(pinned(side)[index] as TData, index);\n },\n\n pinnedCellContext(side, index, columnId) {\n const row = this.pinnedRowAt(side, index);\n const column = byId.get(columnId);\n if (!row || !column) return undefined;\n return {\n row: row.original,\n rowId: row.id,\n index,\n columnId,\n value: column.getValue(row.original, index),\n pinned: side,\n };\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create-table.js","names":[],"sources":["../../../../../core/src/table/create-table.ts"],"sourcesContent":["import {\n columnSizingFeature,\n constructTable,\n rowSortingFeature,\n sortFn_alphanumeric,\n sortFn_basic,\n sortFn_datetime,\n sortFn_text,\n tableFeatures,\n type ColumnDef as TanStackColumnDef,\n type Row,\n type Table,\n type TableOptions,\n} from '@tanstack/table-core';\nimport { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings';\nimport {\n cellOver,\n headerGroupRows,\n resolveColumnGroups,\n type GroupTree,\n type HeaderGroupCell,\n} from '../columns/column-groups.js';\nimport {\n moveUnit,\n normalizeOrder,\n siblingUnits,\n type OrderUnit,\n type SiblingUnit,\n} from '../columns/column-order.js';\nimport { resolveColumns, type ResolvedColumn } from '../columns/resolve-columns.js';\nimport { distinctValues, rowPredicate } from '../filters/filter.js';\nimport { filteredRowModel, setRowPredicate } from './filtered-row-model.js';\nimport { sortedRowModel, valuesChanged } from './sorted-row-model.js';\nimport type {\n CellContext,\n ColumnAlign,\n ColumnDef,\n ColumnGroup,\n ColumnFilter,\n ColumnFilterState,\n ColumnOrderState,\n ColumnPin,\n ColumnPinningState,\n ColumnSizingState,\n ColumnVisibilityState,\n FilterKind,\n FilterValue,\n PinnedRows,\n RowPin,\n SortItem,\n SortState,\n} from '../types.js';\n\n// The TanStack adapter. Everything TanStack stays in this module: callers only see\n// the view types below, so TanStack can be upgraded or replaced without touching\n// `argus-table`'s public API.\n\nconst features = tableFeatures({\n // Vanilla (framework-free) reactivity; required by `constructTable`.\n coreReactivityFeature: storeReactivityBindings(),\n // No pinning, ordering or visibility feature: the model groups, orders and hides\n // columns itself (see `buildViews`), so they cost no bundle size.\n columnSizingFeature,\n rowSortingFeature,\n // Our own filtering, without TanStack's filtering feature (see filtered-row-model.ts).\n // TanStack's types tie this slot to that feature; at runtime the core row models read it.\n ...({ filteredRowModel: filteredRowModel() } as object),\n // Our own: TanStack's is very slow in Firefox at scale (see sorted-row-model.ts).\n sortedRowModel: sortedRowModel(),\n // Registered by name so `sortFn: 'auto'` can pick one by value type.\n sortFns: {\n alphanumeric: sortFn_alphanumeric,\n basic: sortFn_basic,\n datetime: sortFn_datetime,\n text: sortFn_text,\n },\n});\ntype Features = typeof features;\ntype AnyRow = Record<string, unknown>;\n\n/** Sort direction of a column, or `false` when it isn't sorted. */\nexport type SortDirection = 'asc' | 'desc' | false;\n\n/**\n * Id of the selection column, the checkbox column the model adds first when\n * `selectionColumn` is set. Not a column of `columns`: it never appears in the\n * column order, sizing or events.\n */\nexport const SELECTION_COLUMN_ID = '--argus-selection';\n\n/** Width of the selection column in px. */\nexport const SELECTION_COLUMN_WIDTH = 40;\n\n/** A column as the renderer sees it, in visual order: start-pinned, scrolling, end-pinned. */\nexport interface ColumnView<TData, TContent> {\n id: string;\n /** `'data'` for a column of `columns`; `'selection'` for the checkbox column. */\n kind: 'data' | 'selection';\n /** 1-based position in visual order, for `aria-colindex`. `0` for a hidden column. */\n colIndex: number;\n /** The pin in effect: `columnPinning`'s, else the column's own. */\n pin: ColumnPin | undefined;\n /**\n * Sticky inset in px: from the start edge for `'start'` columns, from the end edge\n * for `'end'` columns. For scrolling columns, the start within the scrolling area.\n */\n offset: number;\n /** `true` on the pinned column next to the scrolling area (one per pinned side). */\n pinEdge: boolean;\n /**\n * `true` for a hidden column. Only `allColumns` lists hidden columns; `columns`\n * holds the ones the table shows.\n */\n hidden: boolean;\n /** Current width in px (a resized width wins over the column's own). */\n width: number;\n /** Share of free space, or `undefined` for a fixed width. A resized column stops flexing. */\n flex: number | undefined;\n /**\n * `true` for a `width: 'auto'` column that hasn't been resized: the table measures\n * its content and passes the width in as `autoWidths`.\n */\n auto: boolean;\n minWidth: number;\n maxWidth: number;\n sortable: boolean;\n resizable: boolean;\n reorderable: boolean;\n pinnable: boolean;\n hideable: boolean;\n /** The kind of filter users can set, or `undefined` when they can't filter the column. */\n filter: FilterKind | undefined;\n /** `true` when `columnFilters` has a filter for the column. */\n filtered: boolean;\n align: ColumnAlign;\n /** Whether the cell text wraps (`ColumnDef.wrap`). */\n wrap: boolean;\n sorted: SortDirection;\n header: ColumnDef<TData, TContent>['header'];\n cell: ColumnDef<TData, TContent>['cell'];\n hasAccessor: boolean;\n}\n\n/** A row of the current (filtered and sorted) row model. */\nexport interface RowView<TData> {\n id: string;\n /** Index in the current row model, 0-based. */\n index: number;\n original: TData;\n}\n\n/**\n * Rows that live outside the model, loaded page by page (`dataSource`). The\n * source sorts them, so the model reads them as they are. `PageCache` implements it.\n */\nexport interface RemoteRows<TData> {\n readonly rowCount: number;\n /** The loaded row at an index, with its id; `undefined` while it isn't loaded. */\n entryAt(index: number): { id: string; row: TData } | undefined;\n /** The index of a loaded row's id, or `undefined`. */\n indexOf(rowId: string): number | undefined;\n /** The ids of every loaded row, in row order. */\n loadedIds(): string[];\n}\n\nexport interface TableModelOptions<TData, TContent> {\n columns: readonly ColumnDef<TData, TContent>[];\n /**\n * Headers over several columns, nested to any depth. Their columns stay next to\n * each other in the order, and each level adds a header row.\n */\n columnGroups?: readonly ColumnGroup<TContent>[] | undefined;\n data: readonly TData[];\n /**\n * Remote rows. When set, rows come from here instead of `data`, and the model\n * doesn't sort them (the source does).\n */\n remote?: RemoteRows<TData> | undefined;\n /** Row id function. Default: the row's index in `data`, as a string. */\n getRowId: ((row: TData, index: number) => string) | undefined;\n /** Current sort state; its owner is the caller (see `controllable`). */\n sorting: SortState;\n /** Current resized widths; its owner is the caller. */\n columnSizing: ColumnSizingState;\n /**\n * Current column order; its owner is the caller. Each pin group follows it; an\n * empty array (the default) keeps the order of `columns`.\n */\n columnOrder?: ColumnOrderState | undefined;\n /** Pins set at runtime, over the columns' own `pin`; its owner is the caller. */\n columnPinning?: ColumnPinningState | undefined;\n /** Visibility set at runtime, over the columns' own `hidden`; its owner is the caller. */\n columnVisibility?: ColumnVisibilityState | undefined;\n /**\n * Column filters; its owner is the caller. Rows that fail one leave the row model.\n * Remote rows aren't filtered: the source does it.\n */\n columnFilters?: ColumnFilterState | undefined;\n /**\n * Words to find in the shown columns' values as text, ignoring case: a row stays\n * when each word is in one of its values. Remote rows aren't filtered.\n */\n quickFilter?: string | undefined;\n /**\n * Measured widths of `width: 'auto'` columns, in px by id. Clamped to the column's\n * bounds; a resized width wins. Ids of other columns are ignored.\n */\n autoWidths?: ColumnSizingState | undefined;\n /** Rows fixed above or below the body. They stay out of the row model: never sorted, not counted. */\n pinnedRows?: PinnedRows<TData> | undefined;\n /**\n * Adds the selection (checkbox) column first among the start-pinned columns. It\n * has the id `SELECTION_COLUMN_ID`, a fixed width, and no part in sorting,\n * sizing or the column order.\n */\n selectionColumn?: boolean | undefined;\n}\n\nexport interface TableModel<TData, TContent> {\n /** Updates any subset of the options. Unchanged references are ignored. */\n update(options: Partial<TableModelOptions<TData, TContent>>): void;\n /** The columns the table shows, in visual order. */\n readonly columns: readonly ColumnView<TData, TContent>[];\n /**\n * Every column of `columns`, hidden ones included (with `hidden: true` and\n * `colIndex: 0`), in the order of `orderOf()`. Not the selection column.\n */\n readonly allColumns: readonly ColumnView<TData, TContent>[];\n /** Number of rows in the current row model. */\n readonly rowCount: number;\n /**\n * Changes identity whenever the row at an index may have changed: new data, a\n * sort, a filter, a new remote source. Compare it by identity only.\n */\n readonly rowOrder: object;\n /** Sum of the shown columns' widths in px (flex columns count their minimum). */\n readonly totalWidth: number;\n /**\n * The group header rows over `columns`, top row first; empty without column groups.\n * Keeps its identity while `columns` does.\n */\n readonly headerGroups: readonly (readonly HeaderGroupCell<TContent>[])[];\n /** Number of header rows: the group rows and the row of column headers. */\n readonly headerRows: number;\n /** The cell of group header row `level` over a column, or `undefined`. */\n headerCell(level: number, columnId: string): HeaderGroupCell<TContent> | undefined;\n /** The row at an index of the current row model; `undefined` for a remote row not loaded yet. */\n rowAt(index: number): RowView<TData> | undefined;\n /** The index of a row id in the current row model (after filtering and sorting), or `undefined`. */\n indexOf(rowId: string): number | undefined;\n /**\n * The ids of the rows that can be selected, in row order: every row of the row\n * model, or only the loaded ones for remote rows.\n */\n selectableIds(): string[];\n /** The value a column reads from the row at `index`. */\n valueAt(index: number, columnId: string): unknown;\n /** What a column's `cell` function receives for the row at `index`. */\n cellContext(index: number, columnId: string): CellContext<TData> | undefined;\n /**\n * The sort state that clicking this column's header would produce:\n * asc → desc → unsorted, one column at a time. `undefined` if it can't sort.\n */\n nextSorting(columnId: string): SortState | undefined;\n /**\n * The sizing state after setting a column to `width` px, clamped to its bounds.\n * `undefined` if the column can't be resized.\n */\n nextSizing(columnId: string, width: number): ColumnSizingState | undefined;\n /**\n * The full column order as the table shows it: start-pinned, scrolling and\n * end-pinned ids. `base` defaults to the current `columnOrder`.\n */\n orderOf(base?: readonly string[]): ColumnOrderState;\n /**\n * The units a column or group moves among: the shown columns and groups with the\n * same parent group on the same pin side, in visual order, starting from `base`\n * (default: the current order). Empty if the unit isn't shown.\n */\n siblingUnits(unit: OrderUnit, base?: readonly string[]): SiblingUnit[];\n /**\n * The order after moving a column or group to position `to` among its sibling\n * units (0-based, counted after the move; hidden columns keep their place),\n * starting from `base` (default: the current order). `undefined` if it can't\n * move or is hidden, `to` is out of range, or nothing changes.\n */\n nextMove(unit: OrderUnit, to: number, base?: readonly string[]): ColumnOrderState | undefined;\n /**\n * The pinning state after pinning a column to a side, or unpinning it with `false`,\n * starting from `base` (default: the current `columnPinning`). `undefined` for an\n * unknown column, one with `pinnable: false`, or no change.\n */\n nextPinning(\n columnId: string,\n pin: ColumnPin | false,\n base?: ColumnPinningState,\n ): ColumnPinningState | undefined;\n /**\n * The visibility state after hiding or showing a column, starting from `base`\n * (default: the current `columnVisibility`). `undefined` for an unknown column,\n * hiding one with `hideable: false` or the last one shown, or no change.\n */\n nextVisibility(\n columnId: string,\n hidden: boolean,\n base?: ColumnVisibilityState,\n ): ColumnVisibilityState | undefined;\n /**\n * The filter state after setting a column's filter, or clearing it with `undefined`,\n * starting from `base` (default: the current `columnFilters`). `undefined` for an\n * unknown column, setting a filter on a column without `filter`, or no change.\n */\n nextFilters(\n columnId: string,\n filter: ColumnFilter | undefined,\n base?: ColumnFilterState,\n ): ColumnFilterState | undefined;\n /**\n * The values a `'set'` filter on the column offers: its `filterOptions`, else (not for\n * remote rows) the distinct values of the rows the other filters keep, sorted, at most\n * `limit` of them (`truncated` when there are more). `undefined` for an unknown column,\n * or remote rows without `filterOptions`.\n */\n filterValues(\n columnId: string,\n limit?: number,\n ): { values: FilterValue[]; truncated: boolean } | undefined;\n /**\n * The indexes in `data` of the rows the column filters and the quick filter keep,\n * ascending (not sorted), leaving out the filters on the `except` columns and their\n * text in the quick filter. `undefined` for remote rows. Reads only the core rows\n * and the other columns' accessors, so an accessor of an `except` column can call it\n * while the model filters or sorts.\n */\n indexesPassing(except?: Iterable<string>): readonly number[] | undefined;\n /** Number of rows pinned to a side. */\n pinnedCount(side: RowPin): number;\n /**\n * A pinned row, `index` counted within its side. Its id comes from `getRowId`,\n * else it is `'top-{index}'` or `'bottom-{index}'`, apart from the data rows' index ids.\n */\n pinnedRowAt(side: RowPin, index: number): RowView<TData> | undefined;\n /** The value a column reads from a pinned row. */\n pinnedValueAt(side: RowPin, index: number, columnId: string): unknown;\n /** What a column's `cell` function receives for a pinned row (with `pinned` set). */\n pinnedCellContext(side: RowPin, index: number, columnId: string): CellContext<TData> | undefined;\n}\n\nconst defaultRowId = (_row: unknown, index: number) => String(index);\n\n/**\n * Ids of the columns kept from `before` whose accessor changed: a new function,\n * or a different path. A new column has nothing cached and isn't listed.\n */\nfunction changedAccessors<TData, TContent>(\n before: readonly ColumnDef<TData, TContent>[],\n after: readonly ColumnDef<TData, TContent>[],\n): string[] {\n const old = new Map(before.map((c) => [c.id, c.accessor]));\n return after.filter((c) => old.has(c.id) && old.get(c.id) !== c.accessor).map((c) => c.id);\n}\n\n/** The selection column's view: first, pinned to the start, fixed, and inert to sorting, sizing and moves. */\nfunction selectionView<TData, TContent>(pinEdge: boolean): ColumnView<TData, TContent> {\n return {\n id: SELECTION_COLUMN_ID,\n kind: 'selection',\n colIndex: 1,\n pin: 'start',\n offset: 0,\n pinEdge,\n hidden: false,\n width: SELECTION_COLUMN_WIDTH,\n flex: undefined,\n auto: false,\n minWidth: SELECTION_COLUMN_WIDTH,\n maxWidth: SELECTION_COLUMN_WIDTH,\n sortable: false,\n resizable: false,\n reorderable: false,\n pinnable: false,\n hideable: false,\n filter: undefined,\n filtered: false,\n align: 'center',\n wrap: false,\n sorted: false,\n header: undefined,\n cell: undefined,\n hasAccessor: false,\n };\n}\n\nfunction toTanStack<TData, TContent>(\n column: ResolvedColumn<TData, TContent>,\n): TanStackColumnDef<Features, AnyRow> {\n return {\n id: column.id,\n accessorFn: column.getValue as (row: AnyRow, index: number) => unknown,\n size: column.width,\n minSize: column.minWidth,\n maxSize: column.maxWidth,\n enableSorting: column.sortable,\n sortUndefined: 'last',\n };\n}\n\n/**\n * Creates the table model over TanStack Table. It owns no state: sorting, sizing, order,\n * pinning and visibility come in through `update()`, and the `next*()` methods only propose\n * changes, so the caller decides (controlled or uncontrolled) whether to apply them.\n *\n * Hidden columns stay in TanStack, so their values still sort and read; only the\n * views leave them out. Pin groups, sticky offsets and the order are the model's own.\n */\nexport function createTableModel<TData, TContent>(\n initial: TableModelOptions<TData, TContent>,\n): TableModel<TData, TContent> {\n let options = initial;\n let resolved = resolveColumns(options.columns);\n let byId = new Map(resolved.map((c) => [c.id, c]));\n // TanStack column defs by id, kept between updates that don't change `columns`.\n let tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));\n let views: ColumnView<TData, TContent>[] | undefined;\n const treeOf = () =>\n resolveColumnGroups(options.columnGroups, new Set(resolved.map((c) => c.id)));\n let tree: GroupTree<TContent> = treeOf();\n // The group header rows, kept while the tree and what they read of the views stay.\n let groupRows:\n | {\n views: readonly ColumnView<TData, TContent>[];\n tree: GroupTree<TContent>;\n key: string;\n rows: HeaderGroupCell<TContent>[][];\n }\n | undefined;\n // The pin and visibility in effect: the state's, else the column's own.\n const pinOf = (\n column: ResolvedColumn<TData, TContent>,\n pinning = options.columnPinning,\n ): ColumnPin | undefined => {\n const state = pinning?.[column.id];\n if (state === 'start' || state === 'end') return state;\n return state === false ? undefined : column.pin;\n };\n const hiddenOf = (\n column: ResolvedColumn<TData, TContent>,\n visibility = options.columnVisibility,\n ): boolean => {\n const state = visibility?.[column.id];\n return typeof state === 'boolean' ? !state : column.hidden;\n };\n const shown = (id: string) => {\n const column = byId.get(id);\n return column !== undefined && !hiddenOf(column);\n };\n // TanStack's sizing state: measured auto widths and the widths of pinned flex columns\n // under the resized ones. Kept stable between updates that don't touch them.\n let sizing: ColumnSizingState | undefined;\n const sizingState = (): ColumnSizingState => {\n if (sizing) return sizing;\n const auto = options.autoWidths;\n const merged: ColumnSizingState = {};\n let any = false;\n for (const column of resolved) {\n // A pinned column can't flex: it takes a fixed width for its sticky offsets.\n if (column.flex !== undefined && pinOf(column) !== undefined) {\n merged[column.id] = column.pinnedWidth;\n any = true;\n }\n const px = auto?.[column.id];\n if (!column.auto || px === undefined || !Number.isFinite(px)) continue;\n merged[column.id] = Math.min(column.maxWidth, Math.max(column.minWidth, px));\n any = true;\n }\n return (sizing = any ? { ...merged, ...options.columnSizing } : options.columnSizing);\n };\n // What ordering needs, with the pin in effect.\n const orderable = () =>\n resolved.map((c) => ({ id: c.id, pin: pinOf(c), reorderable: c.reorderable }));\n // The normalized order, kept stable between updates that touch neither columns,\n // order nor pinning.\n let order: ColumnOrderState | undefined;\n const orderState = (): ColumnOrderState =>\n (order ??= normalizeOrder(options.columnOrder ?? [], orderable(), tree));\n const rowViews = new WeakMap<Row<Features, AnyRow>, RowView<TData>>();\n // Built lazily per row model (sorting or new data gives a new array).\n let indexById: { rows: readonly Row<Features, AnyRow>[]; map: Map<string, number> } | undefined;\n\n // TanStack gets its column defs in the order, hidden ones included. Rebuilt only when\n // the order changes: a new columns array makes TanStack rebuild its columns, though\n // not its row models, which depend on data and sorting alone.\n let ordered:\n { order: ColumnOrderState; columns: TanStackColumnDef<Features, AnyRow>[] } | undefined;\n const orderedColumns = () => {\n const current = orderState();\n if (ordered?.order !== current) {\n ordered = { order: current, columns: current.flatMap((id) => tanStackById.get(id) ?? []) };\n }\n return ordered;\n };\n\n const tableOptions = (): TableOptions<Features, AnyRow> => ({\n features,\n columns: orderedColumns().columns,\n // Remote rows bypass TanStack's row models; it still handles columns and state.\n data: (options.remote ? [] : options.data) as AnyRow[],\n getRowId: (options.getRowId ?? defaultRowId) as (row: AnyRow, index: number) => string,\n state: {\n // TanStack's type is mutable; it never changes the array.\n sorting: options.sorting as SortItem[],\n columnSizing: sizingState(),\n },\n // State is owned by the caller; TanStack's own setters must not change it.\n onSortingChange: () => undefined,\n onColumnSizingChange: () => undefined,\n });\n\n const table: Table<Features, AnyRow> = constructTable(tableOptions());\n\n // The row test of the filters, the quick filter and the shown columns (which the quick\n // filter reads). Remote rows are filtered by their source.\n // `except`: columns whose filter is left out; with `quick`, their text is left out\n // of the quick filter too.\n const predicateFor = (except?: ReadonlySet<string>, quick = false) =>\n options.remote\n ? undefined\n : rowPredicate(\n byId,\n options.columnFilters,\n options.quickFilter,\n resolved.filter((c) => c.hasAccessor && !hiddenOf(c) && !(quick && except?.has(c.id))),\n except,\n );\n setRowPredicate(table, predicateFor());\n\n const rows = () => table.getRowModel().rows;\n const pinned = (side: RowPin): readonly TData[] => options.pinnedRows?.[side] ?? [];\n\n const widthOf = (id: string) => table.getColumn(id)?.getSize() ?? 0;\n const view = (\n def: ResolvedColumn<TData, TContent>,\n colIndex: number,\n offset: number,\n pinEdge: boolean,\n ): ColumnView<TData, TContent> => {\n const sort = options.sorting.find((s) => s.id === def.id);\n const pin = pinOf(def);\n const resized = options.columnSizing[def.id] !== undefined;\n return {\n id: def.id,\n kind: 'data',\n colIndex,\n pin,\n offset,\n pinEdge,\n hidden: colIndex === 0,\n width: widthOf(def.id),\n flex: pin === undefined && !resized ? def.flex : undefined,\n auto: def.auto && !resized,\n minWidth: def.minWidth,\n maxWidth: def.maxWidth,\n sortable: def.sortable,\n resizable: def.resizable,\n reorderable: def.reorderable,\n pinnable: def.pinnable,\n hideable: def.hideable,\n filter: def.filter,\n filtered: options.columnFilters?.[def.id] !== undefined,\n align: def.align,\n wrap: def.wrap,\n sorted: sort ? (sort.desc ? 'desc' : 'asc') : false,\n header: def.header,\n cell: def.cell,\n hasAccessor: def.hasAccessor,\n };\n };\n\n const buildViews = (): ColumnView<TData, TContent>[] => {\n const groups: Record<ColumnPin | 'center', ResolvedColumn<TData, TContent>[]> = {\n start: [],\n center: [],\n end: [],\n };\n for (const id of orderState()) {\n const def = byId.get(id);\n if (def && !hiddenOf(def)) groups[pinOf(def) ?? 'center'].push(def);\n }\n const { start, center, end } = groups;\n // The selection column comes first: it shifts every column one place on, and\n // the other start-pinned columns its width further from the start edge.\n const lead = options.selectionColumn ? 1 : 0;\n if (lead && byId.has(SELECTION_COLUMN_ID)) {\n throw new Error(`argus-table: the column id '${SELECTION_COLUMN_ID}' is reserved.`);\n }\n // Offsets: start columns from the start edge (after the selection column), the\n // scrolling ones within the scrolling area, end columns from the end edge.\n let x = lead * SELECTION_COLUMN_WIDTH;\n const list = start.map((def, i) => {\n const v = view(def, lead + i + 1, x, i === start.length - 1);\n x += v.width;\n return v;\n });\n x = 0;\n for (const [i, def] of center.entries()) {\n const v = view(def, lead + start.length + i + 1, x, false);\n list.push(v);\n x += v.width;\n }\n const ends: ColumnView<TData, TContent>[] = [];\n x = 0;\n for (const [i, def] of [...end.entries()].reverse()) {\n const v = view(def, lead + start.length + center.length + i + 1, x, i === 0);\n ends.unshift(v);\n x += v.width;\n }\n list.push(...ends);\n if (lead) list.unshift(selectionView(start.length === 0));\n return list;\n };\n\n let allViews: ColumnView<TData, TContent>[] | undefined;\n const buildAllViews = (shownViews: readonly ColumnView<TData, TContent>[]) => {\n const byShownId = new Map(shownViews.map((v) => [v.id, v]));\n return orderState().flatMap((id) => {\n const shownView = byShownId.get(id);\n if (shownView) return [shownView];\n const def = byId.get(id);\n return def ? [view(def, 0, 0, false)] : [];\n });\n };\n\n return {\n update(next) {\n const merged = { ...options, ...next };\n const changed = (Object.keys(next) as (keyof typeof next)[]).some(\n (key) => next[key] !== options[key],\n );\n if (!changed) return;\n let reread: string[] = [];\n if (next.columns && next.columns !== options.columns) {\n reread = changedAccessors(options.columns, next.columns);\n resolved = resolveColumns(next.columns);\n byId = new Map(resolved.map((c) => [c.id, c]));\n tanStackById = new Map(resolved.map((c) => [c.id, toTanStack(c)]));\n }\n const columnsChanged = merged.columns !== options.columns;\n const pinningChanged = merged.columnPinning !== options.columnPinning;\n const groupsChanged = merged.columnGroups !== options.columnGroups;\n if (\n columnsChanged ||\n merged.columnSizing !== options.columnSizing ||\n merged.autoWidths !== options.autoWidths ||\n pinningChanged\n ) {\n sizing = undefined;\n }\n if (\n columnsChanged ||\n groupsChanged ||\n merged.columnOrder !== options.columnOrder ||\n pinningChanged\n ) {\n order = undefined;\n }\n const refilter =\n columnsChanged ||\n merged.columnFilters !== options.columnFilters ||\n merged.quickFilter !== options.quickFilter ||\n merged.columnVisibility !== options.columnVisibility ||\n merged.remote !== options.remote;\n options = merged;\n if (columnsChanged || groupsChanged) tree = treeOf();\n views = undefined;\n allViews = undefined;\n if (refilter) setRowPredicate(table, predicateFor());\n table.setOptions((prev) => ({ ...prev, ...tableOptions() }));\n if (reread.length && !options.remote) {\n // TanStack caches each value on its row by column id, and keeps rows\n // while the data is the same: drop the values of the columns that now\n // read differently, and sort again.\n for (const row of table.getCoreRowModel().rows) {\n for (const id of reread) Reflect.deleteProperty(row._valuesCache, id);\n }\n valuesChanged(table);\n }\n },\n\n get columns() {\n return (views ??= buildViews());\n },\n\n get allColumns() {\n return (allViews ??= buildAllViews(this.columns));\n },\n\n get rowCount() {\n return options.remote?.rowCount ?? rows().length;\n },\n get rowOrder() {\n return options.remote ?? rows();\n },\n\n get totalWidth() {\n return this.columns.reduce((sum, column) => sum + column.width, 0);\n },\n\n get headerGroups() {\n const current = this.columns;\n if (groupRows?.views === current && groupRows.tree === tree) return groupRows.rows;\n // Views are rebuilt on every update; the rows only change with what they read.\n const key = tree.groups.size\n ? current\n .map(\n (c) =>\n `${c.id}\\u0000${String(c.pin)}\\u0000${String(c.offset)}\\u0000${String(c.pinEdge)}\\u0000${String(c.reorderable)}\\u0000${String(c.resizable)}`,\n )\n .join('\\u0001')\n : '';\n if (groupRows?.tree !== tree || groupRows.key !== key) {\n groupRows = { views: current, tree, key, rows: headerGroupRows(tree, current) };\n } else {\n groupRows.views = current;\n }\n return groupRows.rows;\n },\n\n get headerRows() {\n return this.headerGroups.length + 1;\n },\n\n headerCell(level, columnId) {\n return cellOver(this.headerGroups, level, columnId);\n },\n\n rowAt(index) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n return entry && { id: entry.id, index, original: entry.row };\n }\n const row = rows()[index];\n if (!row) return undefined;\n let view = rowViews.get(row);\n if (view?.index !== index) {\n view = { id: row.id, index, original: row.original as TData };\n rowViews.set(row, view);\n }\n return view;\n },\n\n indexOf(rowId) {\n if (options.remote) return options.remote.indexOf(rowId);\n const current = rows();\n if (indexById?.rows !== current) {\n indexById = { rows: current, map: new Map(current.map((r, i) => [r.id, i])) };\n }\n return indexById.map.get(rowId);\n },\n\n selectableIds() {\n if (options.remote) return options.remote.loadedIds();\n return rows().map((r) => r.id);\n },\n\n valueAt(index, columnId) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n return entry && byId.get(columnId)?.getValue(entry.row, index);\n }\n return rows()[index]?.getValue(columnId);\n },\n\n cellContext(index, columnId) {\n if (options.remote) {\n const entry = options.remote.entryAt(index);\n const column = byId.get(columnId);\n if (!entry || !column) return undefined;\n return {\n row: entry.row,\n rowId: entry.id,\n index,\n columnId,\n value: column.getValue(entry.row, index),\n };\n }\n const row = rows()[index];\n if (!row || !byId.has(columnId)) return undefined;\n return {\n row: row.original as TData,\n rowId: row.id,\n index,\n columnId,\n value: row.getValue(columnId),\n };\n },\n\n nextSorting(columnId) {\n if (byId.get(columnId)?.sortable !== true) return undefined;\n const current = options.sorting.find((s) => s.id === columnId);\n if (!current) return [{ id: columnId, desc: false }];\n return current.desc ? [] : [{ id: columnId, desc: true }];\n },\n\n nextSizing(columnId, width) {\n const column = byId.get(columnId);\n if (!column?.resizable || !Number.isFinite(width)) return undefined;\n const clamped = Math.round(Math.min(column.maxWidth, Math.max(column.minWidth, width)));\n return { ...options.columnSizing, [columnId]: clamped };\n },\n\n orderOf(base) {\n return base === undefined ? orderState() : normalizeOrder(base, orderable(), tree);\n },\n\n siblingUnits(unit, base) {\n return siblingUnits(base ?? orderState(), orderable(), tree, unit, shown);\n },\n\n nextMove(unit, to, base) {\n return moveUnit(base ?? orderState(), orderable(), tree, unit, to, shown);\n },\n\n nextPinning(columnId, pin, base = options.columnPinning) {\n const column = byId.get(columnId);\n if (!column?.pinnable || (pinOf(column, base) ?? false) === pin) return undefined;\n return { ...base, [columnId]: pin };\n },\n\n nextVisibility(columnId, hidden, base = options.columnVisibility) {\n const column = byId.get(columnId);\n if (!column || hiddenOf(column, base) === hidden) return undefined;\n const othersShown = resolved.some((c) => c !== column && !hiddenOf(c, base));\n if (hidden && (!column.hideable || !othersShown)) return undefined;\n return { ...base, [columnId]: !hidden };\n },\n\n nextFilters(columnId, filter, base = options.columnFilters ?? {}) {\n const column = byId.get(columnId);\n if (!column) return undefined;\n const current = base[columnId];\n if (filter === undefined) {\n if (current === undefined) return undefined;\n const next = { ...base };\n Reflect.deleteProperty(next, columnId);\n return next;\n }\n if (column.filter === undefined) return undefined;\n if (current && JSON.stringify(current) === JSON.stringify(filter)) return undefined;\n return { ...base, [columnId]: filter };\n },\n\n filterValues(columnId, limit = 1000) {\n const column = byId.get(columnId);\n if (!column) return undefined;\n if (column.filterOptions) return { values: [...column.filterOptions], truncated: false };\n if (options.remote) return undefined;\n const rows = table.getCoreRowModel().rows as unknown as Iterable<{\n original: TData;\n index: number;\n }>;\n return distinctValues(rows, column, predicateFor(new Set([columnId])), limit);\n },\n\n indexesPassing(except) {\n if (options.remote) return undefined;\n const keep = predicateFor(new Set(except), true);\n const kept: number[] = [];\n for (const row of table.getCoreRowModel().rows) {\n if (!keep || keep(row.original as TData, row.index)) kept.push(row.index);\n }\n return kept;\n },\n\n pinnedCount(side) {\n return pinned(side).length;\n },\n\n pinnedRowAt(side, index) {\n if (index < 0 || index >= pinned(side).length) return undefined;\n const row = pinned(side)[index] as TData;\n const id = options.getRowId ? options.getRowId(row, index) : `${side}-${String(index)}`;\n return { id, index, original: row };\n },\n\n pinnedValueAt(side, index, columnId) {\n if (index < 0 || index >= pinned(side).length) return undefined;\n return byId.get(columnId)?.getValue(pinned(side)[index] as TData, index);\n },\n\n pinnedCellContext(side, index, columnId) {\n const row = this.pinnedRowAt(side, index);\n const column = byId.get(columnId);\n if (!row || !column) return undefined;\n return {\n row: row.original,\n rowId: row.id,\n index,\n columnId,\n value: column.getValue(row.original, index),\n pinned: side,\n };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sorted-row-model.js","names":[],"sources":["../../../../../core/src/table/sorted-row-model.ts"],"sourcesContent":["import type {\n ColumnDef_RowSorting,\n RowData,\n RowModel,\n SortFnDef,\n Table,\n TableFeatures,\n} from '@tanstack/table-core';\nimport { column_getCanSort, column_getSortFn } from '@tanstack/table-core/static-functions';\n\ntype Sorting = readonly { id: string; desc: boolean }[];\n\n// Bumped per table when a column reads its values differently (same id, new\n// accessor): the rows and the sorting are the same,
|
|
1
|
+
{"version":3,"file":"sorted-row-model.js","names":[],"sources":["../../../../../core/src/table/sorted-row-model.ts"],"sourcesContent":["import type {\n ColumnDef_RowSorting,\n RowData,\n RowModel,\n SortFnDef,\n Table,\n TableFeatures,\n} from '@tanstack/table-core';\nimport { column_getCanSort, column_getSortFn } from '@tanstack/table-core/static-functions';\n\ntype Sorting = readonly { id: string; desc: boolean }[];\n\n// Bumped per table when a column reads its values differently (same id, new\n// accessor): the rows, the filters and the sorting are the same, but which rows\n// pass and their order may not be.\nconst valueVersions = new WeakMap<object, number>();\n\n/** Makes the filtered and sorted row models of `table` filter and sort again on their next read. */\nexport function valuesChanged(table: object): void {\n valueVersions.set(table, (valueVersions.get(table) ?? 0) + 1);\n}\n\n/** The values version of `table`, bumped by `valuesChanged()`. */\nexport function valueVersion(table: object): number | undefined {\n return valueVersions.get(table);\n}\n\ninterface SortKey {\n /** Each row's value by its position in the unsorted rows, resolved for `compare`. */\n keys: unknown[];\n compare: (a: unknown, b: unknown) => number;\n /** -1 flips `compare` (descending, inverted). */\n sign: number;\n sortUndefined: false | -1 | 1 | 'first' | 'last' | undefined;\n}\n\n/**\n * The sorted row model, in place of TanStack's `createSortedRowModel()`, giving the\n * same order: the same sort functions (`auto` included), `sortUndefined`,\n * `invertSorting`, ties by row index.\n *\n * It reads each row's value once, through the column's accessor, and sorts the row\n * positions by those values. TanStack's model calls `row.getValue()` four times per\n * comparison, and its row methods take rest arguments (`function (...args)`): in\n * Firefox that slows a large sort down by orders of magnitude (750k rows: 176 s\n * against 0.9 s for the same comparator without rest arguments). Reading values\n * once is also faster everywhere, most of all for text, which is lowercased once\n * per row instead of twice per comparison.\n *\n * The registered sort functions come from `constructSortFn`: each carries a value\n * comparator (`sort`, which compares values only) and a normalizer\n * (`resolveDataValue`). The rows are flat (no sub-rows), so there is nothing to\n * sort below them.\n */\nexport function sortedRowModel<TFeatures extends TableFeatures, TData extends RowData>() {\n return (table: Table<TFeatures, TData>) => {\n let last:\n | {\n sorting: unknown;\n source: RowModel<TFeatures, TData>;\n version: number | undefined;\n model: RowModel<TFeatures, TData>;\n }\n | undefined;\n return (): RowModel<TFeatures, TData> => {\n const source = table.getPreSortedRowModel();\n const sorting = (table.options.state as { sorting?: Sorting } | undefined)?.sorting;\n const version = valueVersion(table);\n const prev = last;\n if (prev && prev.sorting === sorting && prev.source === source && prev.version === version) {\n return prev.model;\n }\n const model = sortRows(table, source, sorting ?? []);\n last = { sorting, source, version, model };\n return model;\n };\n };\n}\n\nfunction sortRows<TFeatures extends TableFeatures, TData extends RowData>(\n table: Table<TFeatures, TData>,\n source: RowModel<TFeatures, TData>,\n sorting: Sorting,\n): RowModel<TFeatures, TData> {\n const rows = source.rows;\n const sortKeys: SortKey[] = [];\n for (const { id, desc } of sorting) {\n const column = table.getColumn(id);\n if (!column || !column_getCanSort(column)) continue;\n const fn = column_getSortFn(column) as unknown as SortFnDef<TFeatures, TData>;\n const def = column.columnDef as ColumnDef_RowSorting<TFeatures, TData>;\n const read = column.accessorFn;\n const resolve = fn.resolveDataValue;\n const sortUndefined = def.sortUndefined;\n sortKeys.push({\n keys: rows.map((row) => {\n const value = read?.(row.original, row.index);\n // Undefined stays undefined where `sortUndefined` places it.\n return resolve && !(value === undefined && sortUndefined)\n ? (resolve(value) as unknown)\n : value;\n }),\n compare: fn.sort as (a: unknown, b: unknown) => number,\n sign: (desc ? -1 : 1) * (def.invertSorting ? -1 : 1),\n sortUndefined,\n });\n }\n if (!sortKeys.length || !rows.length) return source;\n\n const compare = (i: number, j: number): number => {\n for (const { keys, compare, sign, sortUndefined } of sortKeys) {\n const a = keys[i];\n const b = keys[j];\n let result = 0;\n if (sortUndefined && (a === undefined || b === undefined)) {\n if (a === undefined && b === undefined) continue;\n if (sortUndefined === 'first') return a === undefined ? -1 : 1;\n if (sortUndefined === 'last') return a === undefined ? 1 : -1;\n result = a === undefined ? sortUndefined : -sortUndefined;\n }\n if (result === 0) result = compare(a, b);\n if (result !== 0) return result * sign;\n }\n return (rows[i]?.index ?? i) - (rows[j]?.index ?? j);\n };\n\n const sorted = rows\n .map((_, i) => i)\n .sort(compare)\n .map((i) => rows[i])\n .filter((row) => row !== undefined);\n return { rows: sorted, flatRows: sorted, rowsById: source.rowsById };\n}\n"],"mappings":";;AAeA,IAAM,gCAAgB,IAAI,QAAwB;;AAGlD,SAAgB,cAAc,OAAqB;CACjD,cAAc,IAAI,QAAQ,cAAc,IAAI,KAAK,KAAK,KAAK,CAAC;AAC9D;;AAGA,SAAgB,aAAa,OAAmC;CAC9D,OAAO,cAAc,IAAI,KAAK;AAChC;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,iBAAyE;CACvF,QAAQ,UAAmC;EACzC,IAAI;EAQJ,aAAyC;GACvC,MAAM,SAAS,MAAM,qBAAqB;GAC1C,MAAM,UAAW,MAAM,QAAQ,OAA6C;GAC5E,MAAM,UAAU,aAAa,KAAK;GAClC,MAAM,OAAO;GACb,IAAI,QAAQ,KAAK,YAAY,WAAW,KAAK,WAAW,UAAU,KAAK,YAAY,SACjF,OAAO,KAAK;GAEd,MAAM,QAAQ,SAAS,OAAO,QAAQ,WAAW,CAAC,CAAC;GACnD,OAAO;IAAE;IAAS;IAAQ;IAAS;GAAM;GACzC,OAAO;EACT;CACF;AACF;AAEA,SAAS,SACP,OACA,QACA,SAC4B;CAC5B,MAAM,OAAO,OAAO;CACpB,MAAM,WAAsB,CAAC;CAC7B,KAAK,MAAM,EAAE,IAAI,UAAU,SAAS;EAClC,MAAM,SAAS,MAAM,UAAU,EAAE;EACjC,IAAI,CAAC,UAAU,CAAC,kBAAkB,MAAM,GAAG;EAC3C,MAAM,KAAK,iBAAiB,MAAM;EAClC,MAAM,MAAM,OAAO;EACnB,MAAM,OAAO,OAAO;EACpB,MAAM,UAAU,GAAG;EACnB,MAAM,gBAAgB,IAAI;EAC1B,SAAS,KAAK;GACZ,MAAM,KAAK,KAAK,QAAQ;IACtB,MAAM,QAAQ,OAAO,IAAI,UAAU,IAAI,KAAK;IAE5C,OAAO,WAAW,EAAE,UAAU,KAAA,KAAa,iBACtC,QAAQ,KAAK,IACd;GACN,CAAC;GACD,SAAS,GAAG;GACZ,OAAO,OAAO,KAAK,MAAM,IAAI,gBAAgB,KAAK;GAClD;EACF,CAAC;CACH;CACA,IAAI,CAAC,SAAS,UAAU,CAAC,KAAK,QAAQ,OAAO;CAE7C,MAAM,WAAW,GAAW,MAAsB;EAChD,KAAK,MAAM,EAAE,MAAM,SAAS,MAAM,mBAAmB,UAAU;GAC7D,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK;GACf,IAAI,SAAS;GACb,IAAI,kBAAkB,MAAM,KAAA,KAAa,MAAM,KAAA,IAAY;IACzD,IAAI,MAAM,KAAA,KAAa,MAAM,KAAA,GAAW;IACxC,IAAI,kBAAkB,SAAS,OAAO,MAAM,KAAA,IAAY,KAAK;IAC7D,IAAI,kBAAkB,QAAQ,OAAO,MAAM,KAAA,IAAY,IAAI;IAC3D,SAAS,MAAM,KAAA,IAAY,gBAAgB,CAAC;GAC9C;GACA,IAAI,WAAW,GAAG,SAAS,QAAQ,GAAG,CAAC;GACvC,IAAI,WAAW,GAAG,OAAO,SAAS;EACpC;EACA,QAAQ,KAAK,EAAE,EAAE,SAAS,MAAM,KAAK,EAAE,EAAE,SAAS;CACpD;CAEA,MAAM,SAAS,KACZ,KAAK,GAAG,MAAM,CAAC,CAAC,CAChB,KAAK,OAAO,CAAC,CACb,KAAK,MAAM,KAAK,EAAE,CAAC,CACnB,QAAQ,QAAQ,QAAQ,KAAA,CAAS;CACpC,OAAO;EAAE,MAAM;EAAQ,UAAU;EAAQ,UAAU,OAAO;CAAS;AACrE"}
|
|
@@ -23,10 +23,6 @@ var RowSizes = class {
|
|
|
23
23
|
get count() {
|
|
24
24
|
return this.#count;
|
|
25
25
|
}
|
|
26
|
-
/** The height of a row not measured, in px. */
|
|
27
|
-
get estimate() {
|
|
28
|
-
return this.#estimate;
|
|
29
|
-
}
|
|
30
26
|
/** The height of all rows. */
|
|
31
27
|
get total() {
|
|
32
28
|
return this.#count * this.#estimate + this.#sum;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"row-sizes.js","names":[],"sources":["../../../../../core/src/virtual/row-sizes.ts"],"sourcesContent":["/**\n * Row heights for rows that aren't all the same height (`rowHeight: 'auto'`):\n * every row is `estimate` px until it is measured. Offsets, the row at an\n * offset and the total take O(log n), so measuring a row near the top of a\n * million rows doesn't recompute every row below it.\n *\n * A Fenwick tree over each row's difference from the estimate. Nothing is\n * allocated until a row differs from the estimate: one-line rows cost nothing.\n */\nexport class RowSizes {\n #count = 0;\n #estimate = 1;\n /** Each row's difference from the estimate; `undefined` while every row is the estimate. */\n #delta: Float64Array | undefined;\n /** Fenwick tree over `#delta`, 1-based. */\n #tree: Float64Array | undefined;\n /** The highest power of two at most `#count`, for `indexAt`. */\n #step = 0;\n /** The sum of all differences. */\n #sum = 0;\n\n /** Number of rows. */\n get count(): number {\n return this.#count;\n }\n\n /** The height of
|
|
1
|
+
{"version":3,"file":"row-sizes.js","names":[],"sources":["../../../../../core/src/virtual/row-sizes.ts"],"sourcesContent":["/**\n * Row heights for rows that aren't all the same height (`rowHeight: 'auto'`):\n * every row is `estimate` px until it is measured. Offsets, the row at an\n * offset and the total take O(log n), so measuring a row near the top of a\n * million rows doesn't recompute every row below it.\n *\n * A Fenwick tree over each row's difference from the estimate. Nothing is\n * allocated until a row differs from the estimate: one-line rows cost nothing.\n */\nexport class RowSizes {\n #count = 0;\n #estimate = 1;\n /** Each row's difference from the estimate; `undefined` while every row is the estimate. */\n #delta: Float64Array | undefined;\n /** Fenwick tree over `#delta`, 1-based. */\n #tree: Float64Array | undefined;\n /** The highest power of two at most `#count`, for `indexAt`. */\n #step = 0;\n /** The sum of all differences. */\n #sum = 0;\n\n /** Number of rows. */\n get count(): number {\n return this.#count;\n }\n\n /** The height of all rows. */\n get total(): number {\n return this.#count * this.#estimate + this.#sum;\n }\n\n /**\n * Starts over: `count` rows of `estimate` px, then the heights in `sizes`\n * (`[index, px]`; indexes out of range are ignored). O(count).\n */\n reset(count: number, estimate: number, sizes: Iterable<readonly [number, number]> = []): void {\n this.#count = Math.max(0, Math.floor(count));\n this.#estimate = estimate > 0 ? estimate : 1;\n this.#step = highestPowerOfTwo(this.#count);\n this.#sum = 0;\n let delta: Float64Array | undefined;\n for (const [index, px] of sizes) {\n if (index < 0 || index >= this.#count || !Number.isFinite(px)) continue;\n const d = px - this.#estimate;\n if (d === 0) continue;\n delta ??= this.#buffer(this.#count);\n this.#sum += d - (delta[index] ?? 0);\n delta[index] = d;\n }\n if (delta) this.#build(delta);\n else this.#clear();\n }\n\n /**\n * Changes the number of rows (a data source counting more), keeping the\n * heights of the rows that stay. O(count) when any row was measured.\n */\n resize(count: number): void {\n count = Math.max(0, Math.floor(count));\n if (count === this.#count) return;\n const old = this.#delta;\n this.#count = count;\n this.#step = highestPowerOfTwo(count);\n if (!old) return;\n const delta = new Float64Array(count);\n delta.set(old.subarray(0, Math.min(count, old.length)));\n this.#sum = 0;\n for (const d of delta) this.#sum += d;\n this.#build(delta);\n }\n\n /** The height of the row at `index`. */\n sizeOf(index: number): number {\n return this.#estimate + (this.#delta?.[index] ?? 0);\n }\n\n /** Sets the height of the row at `index`. Returns how much it changed by. */\n set(index: number, px: number): number {\n if (index < 0 || index >= this.#count || !Number.isFinite(px)) return 0;\n const d = px - this.sizeOf(index);\n if (Math.abs(d) < 1e-6) return 0;\n if (!this.#delta || !this.#tree) this.#build(this.#buffer(this.#count));\n const delta = this.#delta;\n const tree = this.#tree;\n if (!delta || !tree) return 0;\n delta[index] = (delta[index] ?? 0) + d;\n for (let i = index + 1; i <= this.#count; i += i & -i) tree[i] = (tree[i] ?? 0) + d;\n this.#sum += d;\n return d;\n }\n\n /** The offset of the row at `index` from the first row's top: the heights of the rows before it. */\n startOf(index: number): number {\n const i = Math.min(Math.max(Math.floor(index), 0), this.#count);\n let start = i * this.#estimate;\n const tree = this.#tree;\n if (tree) for (let j = i; j > 0; j -= j & -j) start += tree[j] ?? 0;\n return start;\n }\n\n /** The row at `offset` px from the first row's top, clamped to the rows. 0 when there are none. */\n indexAt(offset: number): number {\n const count = this.#count;\n if (count === 0 || !(offset > 0)) return 0;\n const estimate = this.#estimate;\n const tree = this.#tree;\n let index: number;\n if (!tree) {\n index = Math.floor(offset / estimate);\n } else {\n // The most rows whose heights add up to at most `offset`: that many rows\n // end at or above it, so the row at it is the next one.\n index = 0;\n let rest = offset;\n for (let step = this.#step; step > 0; step >>= 1) {\n const next = index + step;\n if (next > count) continue;\n const size = step * estimate + (tree[next] ?? 0);\n if (size <= rest) {\n index = next;\n rest -= size;\n }\n }\n }\n return Math.min(index, count - 1);\n }\n\n /** A zeroed buffer for `count` differences, reusing the current one when it fits. */\n #buffer(count: number): Float64Array {\n const delta = this.#delta;\n if (delta?.length === count) {\n delta.fill(0);\n return delta;\n }\n return new Float64Array(count);\n }\n\n /** Builds the tree over `delta` in O(count). */\n #build(delta: Float64Array): void {\n const count = this.#count;\n let tree = this.#tree;\n if (tree?.length !== count + 1) tree = new Float64Array(count + 1);\n tree.set(delta, 1);\n tree[0] = 0;\n for (let i = 1; i <= count; i++) {\n const parent = i + (i & -i);\n if (parent <= count) tree[parent] = (tree[parent] ?? 0) + (tree[i] ?? 0);\n }\n this.#delta = delta;\n this.#tree = tree;\n }\n\n #clear(): void {\n this.#delta = undefined;\n this.#tree = undefined;\n }\n}\n\nfunction highestPowerOfTwo(n: number): number {\n let step = 1;\n while (step * 2 <= n) step *= 2;\n return n > 0 ? step : 0;\n}\n"],"mappings":"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"}
|