Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
39ff928
feat: addGroupBy
bryanmylee May 17, 2022
8efacfd
fix: don't apply aggregate label on group cell
bryanmylee May 17, 2022
2990ccd
use `:` separator for rowColId
bryanmylee May 21, 2022
d2c2d43
feat: track aggregate and group cells
bryanmylee May 21, 2022
b725918
feat: track repeat cells
bryanmylee May 21, 2022
125534b
chore: remove id from DisplayBodyCell
bryanmylee May 21, 2022
49671ca
feat: store sets
bryanmylee May 21, 2022
59587e2
feat: clearOthers when toggling
bryanmylee May 21, 2022
6faa5e9
feat: toggle groupBy ids
bryanmylee May 21, 2022
5ec59db
fix: warn instead of throwing error if missing getGroupOn
bryanmylee May 21, 2022
0c7f9ba
fix: AnyPlugin as supertype of all Plugin
bryanmylee May 21, 2022
cb023fa
fix: find value with key.id in case cellForId missing
bryanmylee May 21, 2022
74c968f
feat: Clonable for all TableComponent
bryanmylee May 21, 2022
5d928f6
feat: clone rows for subRows
bryanmylee May 21, 2022
bc5f55f
doc: group / ungroup button
bryanmylee May 21, 2022
d882c1e
fix: cellForId for groupRows
bryanmylee May 21, 2022
308daad
feat: nested grouping
bryanmylee May 21, 2022
6405e82
fix: repeated cell props for nested grouped
bryanmylee May 21, 2022
399ae2e
doc: filter should come before groupBy
bryanmylee May 21, 2022
ed657e4
fix: test components
bryanmylee May 21, 2022
ccfbb93
feat: invariant metadata for plugins to keep track
bryanmylee May 22, 2022
514ddf3
refactor: use clone() method
bryanmylee May 22, 2022
c784451
bump version
bryanmylee May 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svelte-headless-table",
"version": "0.6.1",
"version": "0.7.0",
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build",
Expand Down
12 changes: 11 additions & 1 deletion src/lib/bodyCells.HeaderCell.render.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,17 @@ interface User {
status: string;
}

class TestHeaderCell<Item> extends HeaderCell<Item> {}
class TestHeaderCell<Item> extends HeaderCell<Item> {
clone(): TestHeaderCell<Item> {
return new TestHeaderCell({
id: this.id,
colspan: this.colspan,
label: this.label,
isData: this.isData,
isFlat: this.isFlat,
});
}
}

it('renders string label', () => {
const actual = new TestHeaderCell({
Expand Down
25 changes: 24 additions & 1 deletion src/lib/bodyCells.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ export abstract class BodyCell<

abstract attrs(): Readable<BodyCellAttributes<Item, Plugins>>;

abstract clone(): BodyCell<Item, Plugins>;

rowColId(): string {
return `${this.row.id}-${this.column.id}`;
return `${this.row.id}:${this.column.id}`;
}
}

Expand Down Expand Up @@ -81,6 +83,17 @@ export class DataBodyCell<
return {};
});
}

clone(): DataBodyCell<Item, Plugins> {
const clonedCell = new DataBodyCell({
row: this.row,
column: this.column,
label: this.label,
value: this.value,
});
clonedCell.metadataForName = this.metadataForName;
return clonedCell;
}
}

export type DisplayBodyCellInit<Item, Plugins extends AnyPlugins = AnyPlugins> = Omit<
Expand Down Expand Up @@ -115,4 +128,14 @@ export class DisplayBodyCell<Item, Plugins extends AnyPlugins = AnyPlugins> exte
return {};
});
}

clone(): DisplayBodyCell<Item, Plugins> {
const clonedCell = new DisplayBodyCell({
row: this.row,
column: this.column,
label: this.label,
});
clonedCell.metadataForName = this.metadataForName;
return clonedCell;
}
}
36 changes: 32 additions & 4 deletions src/lib/bodyRows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { BodyCell, DataBodyCell, DisplayBodyCell } from './bodyCells';
import { DataColumn, DisplayColumn, type FlatColumn } from './columns';
import { TableComponent } from './tableComponent';
import type { AnyPlugins } from './types/TablePlugin';
import { getCloned } from './utils/clone';
import { nonUndefined } from './utils/filter';

export interface BodyRowInit<Item, Plugins extends AnyPlugins = AnyPlugins> {
Expand All @@ -17,6 +16,10 @@ export interface BodyRowInit<Item, Plugins extends AnyPlugins = AnyPlugins> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface
export interface BodyRowAttributes<Item, Plugins extends AnyPlugins = AnyPlugins> {}

interface BodyRowCloneProps {
includeCells?: boolean;
}

export class BodyRow<Item, Plugins extends AnyPlugins = AnyPlugins> extends TableComponent<
Item,
Plugins,
Expand Down Expand Up @@ -45,6 +48,31 @@ export class BodyRow<Item, Plugins extends AnyPlugins = AnyPlugins> extends Tabl
return {};
});
}

clone({ includeCells = false }: BodyRowCloneProps = {}): BodyRow<Item, Plugins> {
const clonedRow = new BodyRow({
id: this.id,
cellForId: this.cellForId,
cells: this.cells,
original: this.original,
depth: this.depth,
});
clonedRow.metadataForName = this.metadataForName;
if (!includeCells) {
return clonedRow;
}
const clonedCellsForId = Object.fromEntries(
Object.entries(clonedRow.cellForId).map(([id, cell]) => {
const clonedCell = cell.clone();
clonedCell.row = clonedRow;
return [id, clonedCell];
})
);
const clonedCells = clonedRow.cells.map(({ id }) => clonedCellsForId[id]);
clonedRow.cellForId = clonedCellsForId;
clonedRow.cells = clonedCells;
return clonedRow;
}
}

/**
Expand Down Expand Up @@ -120,9 +148,9 @@ export const getColumnedBodyRows = <Item, Plugins extends AnyPlugins = AnyPlugin
// Create a shallow copy of `row.cells` to reassign each `cell`'s `row`
// reference.
const cells = row.cells.map((cell) => {
return getCloned(cell, {
row: columnedRows[rowIdx],
});
const clonedCell = cell.clone();
clonedCell.row = columnedRows[rowIdx];
return clonedCell;
});
const visibleCells = columnIdOrder
.map((cid) => {
Expand Down
37 changes: 37 additions & 0 deletions src/lib/headerCells.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export abstract class HeaderCell<
};
});
}

abstract clone(): HeaderCell<Item, Plugins>;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand All @@ -72,6 +74,14 @@ export class FlatHeaderCell<Item, Plugins extends AnyPlugins = AnyPlugins> exten
constructor({ id, label, isData }: FlatHeaderCellInit<Item, Plugins>) {
super({ id, label, isData, colspan: 1, isFlat: true });
}

clone(): FlatHeaderCell<Item, Plugins> {
return new FlatHeaderCell({
id: this.id,
label: this.label,
isData: this.isData,
});
}
}

export type DataHeaderCellInit<Item, Plugins extends AnyPlugins = AnyPlugins> = Omit<
Expand All @@ -93,6 +103,15 @@ export class DataHeaderCell<Item, Plugins extends AnyPlugins = AnyPlugins> exten
this.accessorKey = accessorKey;
this.accessorFn = accessorFn;
}

clone(): DataHeaderCell<Item, Plugins> {
return new DataHeaderCell({
id: this.id,
label: this.label,
accessorFn: this.accessorFn,
accessorKey: this.accessorKey,
});
}
}

export type DisplayHeaderCellInit<Item, Plugins extends AnyPlugins = AnyPlugins> = Omit<
Expand All @@ -109,6 +128,13 @@ export class DisplayHeaderCell<
constructor({ id, label = NBSP }: DisplayHeaderCellInit<Item, Plugins>) {
super({ id, label });
}

clone(): DisplayHeaderCell<Item, Plugins> {
return new DisplayHeaderCell({
id: this.id,
label: this.label,
});
}
}

export type GroupHeaderCellInit<Item, Plugins extends AnyPlugins = AnyPlugins> = Omit<
Expand All @@ -132,12 +158,23 @@ export class GroupHeaderCell<Item, Plugins extends AnyPlugins = AnyPlugins> exte
this.allId = `[${allIds.join(',')}]`;
this.allIds = allIds;
}

setIds(ids: string[]) {
this.ids = ids;
this.id = `[${this.ids.join(',')}]`;
}

pushId(id: string) {
this.ids = [...this.ids, id];
this.id = `[${this.ids.join(',')}]`;
}

clone(): GroupHeaderCell<Item, Plugins> {
return new GroupHeaderCell({
label: this.label,
colspan: this.colspan,
ids: this.ids,
allIds: this.allIds,
});
}
}
10 changes: 8 additions & 2 deletions src/lib/headerRows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
import { TableComponent } from './tableComponent';
import type { Matrix } from './types/Matrix';
import type { AnyPlugins } from './types/TablePlugin';
import { getCloned } from './utils/clone';
import { sum } from './utils/math';
import { getNullMatrix, getTransposed } from './utils/matrix';

Expand All @@ -31,6 +30,13 @@ export class HeaderRow<Item, Plugins extends AnyPlugins = AnyPlugins> extends Ta
super({ id });
this.cells = cells;
}

clone(): HeaderRow<Item, Plugins> {
return new HeaderRow({
id: this.id,
cells: this.cells,
});
}
}

export const getHeaderRows = <Item, Plugins extends AnyPlugins = AnyPlugins>(
Expand Down Expand Up @@ -173,7 +179,7 @@ export const getMergedRow = <Item, Plugins extends AnyPlugins = AnyPlugins>(
let startIdx = 0;
let endIdx = 1;
while (startIdx < cells.length) {
const cell = getCloned(cells[startIdx]);
const cell = cells[startIdx].clone();
if (!(cell instanceof GroupHeaderCell)) {
mergedCells.push(cell);
startIdx++;
Expand Down
11 changes: 5 additions & 6 deletions src/lib/plugins/addColumnFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import type { RenderConfig } from '$lib/render';
import type { PluginInitTableState } from '$lib/createViewModel';
import { DataBodyCell } from '$lib/bodyCells';
import { DataHeaderCell } from '$lib/headerCells';
import { getCloned } from '$lib/utils/clone';

export interface ColumnFiltersState<Item> {
filterValues: Writable<Record<string, unknown>>;
Expand Down Expand Up @@ -54,17 +53,17 @@ const getFilteredRows = <Item, Row extends BodyRow<Item>>(
filterValues: Record<string, unknown>,
columnOptions: Record<string, ColumnFiltersColumnOptions<Item>>
): Row[] => {
const _filteredRows = rows
const $filteredRows = rows
// Filter `subRows`
.map((row) => {
const { subRows } = row;
if (subRows === undefined) {
return row;
}
const filteredSubRows = getFilteredRows(subRows, filterValues, columnOptions);
return getCloned(row, {
subRows: filteredSubRows,
} as unknown as Row);
const clonedRow = row.clone() as Row;
clonedRow.subRows = filteredSubRows;
return clonedRow;
})
.filter((row) => {
if ((row.subRows?.length ?? 0) !== 0) {
Expand All @@ -87,7 +86,7 @@ const getFilteredRows = <Item, Row extends BodyRow<Item>>(
}
return true;
});
return _filteredRows;
return $filteredRows;
};

export const addColumnFilters =
Expand Down
Loading