Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce re-derivation of body rows and columns #4

Merged
merged 10 commits into from
May 12, 2022
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.3.0",
"version": "0.4.0",
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build",
Expand Down
16 changes: 8 additions & 8 deletions src/lib/plugins/useColumnFilters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { keyed } from 'svelte-keyed';
import type { BodyRow } from '$lib/bodyRows';
import type { TablePlugin, NewTablePropSet } from '$lib/types/TablePlugin';
import type { TablePlugin, NewTablePropSet, DeriveRowsFn } from '$lib/types/TablePlugin';
import { derived, writable, type Readable, type Writable } from 'svelte/store';
import type { RenderConfig } from '$lib/render';
import type { TableState } from '$lib/useTable';
Expand Down Expand Up @@ -60,10 +60,10 @@ export const useColumnFilters =

const pluginState: ColumnFiltersState<Item> = { filterValues, preFilteredRows };

const transformRowsFn = derived(filterValues, ($filterValues) => {
return (rows: BodyRow<Item>[]) => {
preFilteredRows.set(rows);
const _filteredRows = rows.filter((row) => {
const deriveRows: DeriveRowsFn<Item> = (rows) => {
return derived([rows, filterValues], ([$rows, $filterValues]) => {
preFilteredRows.set($rows);
const _filteredRows = $rows.filter((row) => {
for (const [columnId, columnOption] of Object.entries(columnOptions)) {
const { value } = row.cellForId[columnId];
const filterValue = $filterValues[columnId];
Expand All @@ -79,12 +79,12 @@ export const useColumnFilters =
});
filteredRows.set(_filteredRows);
return _filteredRows;
};
});
});
};

return {
pluginState,
transformRowsFn,
deriveRows,
hooks: {
'thead.tr.th': (cell) => {
const filterValue = keyed(filterValues, cell.id);
Expand Down
23 changes: 11 additions & 12 deletions src/lib/plugins/useColumnOrder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { DataColumn } from '$lib/columns';
import type { NewTablePropSet, TablePlugin } from '$lib/types/TablePlugin';
import type { DeriveFlatColumnsFn, NewTablePropSet, TablePlugin } from '$lib/types/TablePlugin';
import { derived, writable, type Writable } from 'svelte/store';

export interface ColumnOrderConfig {
Expand All @@ -26,24 +25,24 @@ export const useColumnOrder =

const pluginState: ColumnOrderState = { columnIdOrder };

const transformFlatColumnsFn = derived(columnIdOrder, ($columnIdOrder) => {
return (flatColumns: DataColumn<Item>[]) => {
const flatColumnsCopy = [...flatColumns];
const orderedFlatColumns: DataColumn<Item>[] = [];
const deriveFlatColumns: DeriveFlatColumnsFn<Item> = (flatColumns) => {
return derived([flatColumns, columnIdOrder], ([$flatColumns, $columnIdOrder]) => {
const _flatColumns = [...$flatColumns];
const orderedFlatColumns: typeof $flatColumns = [];
$columnIdOrder.forEach((id) => {
const colIdx = flatColumnsCopy.findIndex((c) => c.id === id);
orderedFlatColumns.push(...flatColumnsCopy.splice(colIdx, 1));
const colIdx = _flatColumns.findIndex((c) => c.id === id);
orderedFlatColumns.push(..._flatColumns.splice(colIdx, 1));
});
if (!hideUnspecifiedColumns) {
// Push the remaining unspecified columns.
orderedFlatColumns.push(...flatColumnsCopy);
orderedFlatColumns.push(..._flatColumns);
}
return orderedFlatColumns;
};
});
});
};

return {
pluginState,
transformFlatColumnsFn,
deriveFlatColumns,
};
};
17 changes: 8 additions & 9 deletions src/lib/plugins/useHiddenColumns.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { DataColumn } from '$lib/columns';
import type { NewTablePropSet, TablePlugin } from '$lib/types/TablePlugin';
import type { DeriveFlatColumnsFn, NewTablePropSet, TablePlugin } from '$lib/types/TablePlugin';
import { derived, writable, type Writable } from 'svelte/store';

export interface HiddenColumnsConfig {
Expand All @@ -22,17 +21,17 @@ export const useHiddenColumns =

const pluginState: HiddenColumnsState = { hiddenColumnIds };

const transformFlatColumnsFn = derived(hiddenColumnIds, ($hiddenColumnIds) => {
return (flatColumns: DataColumn<Item>[]) => {
const deriveFlatColumns: DeriveFlatColumnsFn<Item> = (flatColumns) => {
return derived([flatColumns, hiddenColumnIds], ([$flatColumns, $hiddenColumnIds]) => {
if ($hiddenColumnIds.length === 0) {
return flatColumns;
return $flatColumns;
}
return flatColumns.filter((c) => !$hiddenColumnIds.includes(c.id));
};
});
return $flatColumns.filter((c) => !$hiddenColumnIds.includes(c.id));
});
};

return {
pluginState,
transformFlatColumnsFn,
deriveFlatColumns,
};
};
16 changes: 8 additions & 8 deletions src/lib/plugins/usePagination.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { BodyRow } from '$lib/bodyRows';
import type { NewTablePropSet, TablePlugin } from '$lib/types/TablePlugin';
import type { DeriveRowsFn, NewTablePropSet, TablePlugin } from '$lib/types/TablePlugin';
import { derived, writable, type Readable, type Updater, type Writable } from 'svelte/store';

export interface PaginationConfig {
Expand Down Expand Up @@ -91,18 +91,18 @@ export const usePagination =
hasNextPage,
};

const transformRowsFn = derived([pageSize, pageIndex], ([$pageSize, $pageIndex]) => {
return (rows: BodyRow<Item>[]) => {
prePaginatedRows.set(rows);
const deriveRows: DeriveRowsFn<Item> = (rows) => {
return derived([rows, pageSize, pageIndex], ([$rows, $pageSize, $pageIndex]) => {
prePaginatedRows.set($rows);
const startIdx = $pageIndex * $pageSize;
const _paginatedRows = rows.slice(startIdx, startIdx + $pageSize);
const _paginatedRows = $rows.slice(startIdx, startIdx + $pageSize);
paginatedRows.set(_paginatedRows);
return _paginatedRows;
};
});
});
};

return {
pluginState,
transformRowsFn,
deriveRows,
};
};
16 changes: 8 additions & 8 deletions src/lib/plugins/useSortBy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { BodyRow } from '$lib/bodyRows';
import type { TablePlugin, NewTablePropSet } from '$lib/types/TablePlugin';
import type { TablePlugin, NewTablePropSet, DeriveRowsFn } from '$lib/types/TablePlugin';
import { compare } from '$lib/utils/compare';
import { derived, writable, type Readable, type Writable } from 'svelte/store';

Expand Down Expand Up @@ -114,10 +114,10 @@ export const useSortBy =
const preSortedRows = writable<BodyRow<Item>[]>([]);
const sortedRows = writable<BodyRow<Item>[]>([]);

const transformRowsFn = derived(sortKeys, ($sortKeys) => {
return (rows: BodyRow<Item>[]) => {
preSortedRows.set(rows);
const _sortedRows = [...rows];
const deriveRows: DeriveRowsFn<Item> = (rows) => {
return derived([rows, sortKeys], ([$rows, $sortKeys]) => {
preSortedRows.set($rows);
const _sortedRows = [...$rows];
_sortedRows.sort((a, b) => {
for (const key of $sortKeys) {
const invert = columnOptions[key.id]?.invert ?? false;
Expand Down Expand Up @@ -153,14 +153,14 @@ export const useSortBy =
});
sortedRows.set(_sortedRows);
return _sortedRows;
};
});
});
};

const pluginState: SortByState<Item> = { sortKeys, preSortedRows };

return {
pluginState,
transformRowsFn,
deriveRows,
hooks: {
'thead.tr.th': (cell) => {
const disabled = disabledSortIds.includes(cell.id);
Expand Down
16 changes: 8 additions & 8 deletions src/lib/plugins/useTableFilter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { BodyRow } from '$lib/bodyRows';
import type { TablePlugin, NewTablePropSet } from '$lib/types/TablePlugin';
import type { TablePlugin, NewTablePropSet, DeriveRowsFn } from '$lib/types/TablePlugin';
import { derived, writable, type Readable, type Writable } from 'svelte/store';

export interface TableFilterConfig {
Expand Down Expand Up @@ -53,11 +53,11 @@ export const useTableFilter =

const pluginState: TableFilterState<Item> = { filterValue, preFilteredRows };

const transformRowsFn = derived(filterValue, ($filterValue) => {
return (rows: BodyRow<Item>[]) => {
preFilteredRows.set(rows);
const deriveRows: DeriveRowsFn<Item> = (rows) => {
return derived([rows, filterValue], ([$rows, $filterValue]) => {
preFilteredRows.set($rows);
tableCellMatches.set({});
const _filteredRows = rows.filter((row) => {
const _filteredRows = $rows.filter((row) => {
// An array of booleans, true if the cell matches the filter.
const rowCellMatches = Object.values(row.cellForId).map((cell) => {
const options = columnOptions[cell.id] as TableFilterColumnOptions | undefined;
Expand Down Expand Up @@ -85,12 +85,12 @@ export const useTableFilter =
});
filteredRows.set(_filteredRows);
return _filteredRows;
};
});
});
};

return {
pluginState,
transformRowsFn,
deriveRows,
hooks: {
'tbody.tr.td': (cell) => {
const props = derived(
Expand Down
12 changes: 10 additions & 2 deletions src/lib/types/TablePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export type TablePluginInstance<
> = {
pluginState: PluginState;
transformFlatColumnsFn?: Readable<TransformFlatColumnsFn<Item>>;
transformRowsFn?: Readable<TransformRowsFn<Item>>;
deriveFlatColumns?: DeriveFlatColumnsFn<Item>;
deriveRows?: DeriveRowsFn<Item>;
columnOptions?: ColumnOptions;
hooks?: TableHooks<Item, TablePropSet>;
};
Expand All @@ -43,7 +44,14 @@ export type AnyPluginInstances = Record<
>;

export type TransformFlatColumnsFn<Item> = (flatColumns: DataColumn<Item>[]) => DataColumn<Item>[];
export type TransformRowsFn<Item> = (rows: BodyRow<Item>[]) => BodyRow<Item>[];

export type DeriveFlatColumnsFn<Item> = <Col extends DataColumn<Item>>(
flatColumns: Readable<Col[]>
) => Readable<Col[]>;

export type DeriveRowsFn<Item> = <Row extends BodyRow<Item>>(
rows: Readable<Row[]>
) => Readable<Row[]>;

export type Components<Item, Plugins extends AnyPlugins = AnyPlugins> = {
'thead.tr': HeaderRow<Item, Plugins>;
Expand Down
Loading