@humanspeak/svelte-headless-table 5.0.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/LICENSE +22 -0
- package/README.md +122 -0
- package/dist/bodyCells.d.ts +53 -0
- package/dist/bodyCells.js +90 -0
- package/dist/bodyRows.d.ts +82 -0
- package/dist/bodyRows.js +256 -0
- package/dist/columns.d.ts +76 -0
- package/dist/columns.js +96 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/createTable.d.ts +17 -0
- package/dist/createTable.js +36 -0
- package/dist/createViewModel.d.ts +38 -0
- package/dist/createViewModel.js +230 -0
- package/dist/headerCells.d.ts +80 -0
- package/dist/headerCells.js +147 -0
- package/dist/headerRows.d.ts +35 -0
- package/dist/headerRows.js +185 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +12 -0
- package/dist/plugins/addColumnFilters.d.ts +39 -0
- package/dist/plugins/addColumnFilters.js +117 -0
- package/dist/plugins/addColumnOrder.d.ts +10 -0
- package/dist/plugins/addColumnOrder.js +24 -0
- package/dist/plugins/addDataExport.d.ts +21 -0
- package/dist/plugins/addDataExport.js +68 -0
- package/dist/plugins/addExpandedRows.d.ts +17 -0
- package/dist/plugins/addExpandedRows.js +51 -0
- package/dist/plugins/addFlatten.d.ts +19 -0
- package/dist/plugins/addFlatten.js +38 -0
- package/dist/plugins/addGridLayout.d.ts +2 -0
- package/dist/plugins/addGridLayout.js +73 -0
- package/dist/plugins/addGroupBy.d.ts +40 -0
- package/dist/plugins/addGroupBy.js +192 -0
- package/dist/plugins/addHiddenColumns.d.ts +9 -0
- package/dist/plugins/addHiddenColumns.js +17 -0
- package/dist/plugins/addPagination.d.ts +39 -0
- package/dist/plugins/addPagination.js +84 -0
- package/dist/plugins/addResizedColumns.d.ts +41 -0
- package/dist/plugins/addResizedColumns.js +252 -0
- package/dist/plugins/addSelectedRows.d.ts +29 -0
- package/dist/plugins/addSelectedRows.js +190 -0
- package/dist/plugins/addSortBy.d.ts +46 -0
- package/dist/plugins/addSortBy.js +176 -0
- package/dist/plugins/addSubRows.d.ts +9 -0
- package/dist/plugins/addSubRows.js +28 -0
- package/dist/plugins/addTableFilter.d.ts +28 -0
- package/dist/plugins/addTableFilter.js +95 -0
- package/dist/plugins/index.d.ts +15 -0
- package/dist/plugins/index.js +16 -0
- package/dist/plugins/package.json +5 -0
- package/dist/tableComponent.d.ts +19 -0
- package/dist/tableComponent.js +35 -0
- package/dist/types/Action.d.ts +5 -0
- package/dist/types/Action.js +1 -0
- package/dist/types/Entries.d.ts +3 -0
- package/dist/types/Entries.js +1 -0
- package/dist/types/KeyPath.d.ts +6 -0
- package/dist/types/KeyPath.js +1 -0
- package/dist/types/Label.d.ts +8 -0
- package/dist/types/Label.js +1 -0
- package/dist/types/Matrix.d.ts +1 -0
- package/dist/types/Matrix.js +1 -0
- package/dist/types/TablePlugin.d.ts +88 -0
- package/dist/types/TablePlugin.js +1 -0
- package/dist/utils/array.d.ts +2 -0
- package/dist/utils/array.js +9 -0
- package/dist/utils/attributes.d.ts +2 -0
- package/dist/utils/attributes.js +23 -0
- package/dist/utils/clone.d.ts +13 -0
- package/dist/utils/clone.js +18 -0
- package/dist/utils/compare.d.ts +2 -0
- package/dist/utils/compare.js +17 -0
- package/dist/utils/counter.d.ts +1 -0
- package/dist/utils/counter.js +7 -0
- package/dist/utils/css.d.ts +1 -0
- package/dist/utils/css.js +5 -0
- package/dist/utils/event.d.ts +1 -0
- package/dist/utils/event.js +5 -0
- package/dist/utils/filter.d.ts +4 -0
- package/dist/utils/filter.js +4 -0
- package/dist/utils/math.d.ts +2 -0
- package/dist/utils/math.js +2 -0
- package/dist/utils/matrix.d.ts +3 -0
- package/dist/utils/matrix.js +23 -0
- package/dist/utils/store.d.ts +37 -0
- package/dist/utils/store.js +123 -0
- package/package.json +98 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NewTablePropSet, TablePlugin } from '../types/TablePlugin.js';
|
|
2
|
+
export type ValidChildrenKey<Item> = {
|
|
3
|
+
[Key in keyof Item]: Item[Key] extends Item[] ? Key : never;
|
|
4
|
+
}[keyof Item];
|
|
5
|
+
export type ValidChildrenFn<Item> = (item: Item) => Item[] | undefined;
|
|
6
|
+
export interface SubRowsConfig<Item> {
|
|
7
|
+
children: ValidChildrenKey<Item> | ValidChildrenFn<Item>;
|
|
8
|
+
}
|
|
9
|
+
export declare const addSubRows: <Item>({ children }: SubRowsConfig<Item>) => TablePlugin<Item, Record<string, never>, Record<string, never>, NewTablePropSet<never>>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { DataBodyRow, getSubRows } from '../bodyRows.js';
|
|
2
|
+
import { derived } from 'svelte/store';
|
|
3
|
+
const withSubRows = (row, getChildren) => {
|
|
4
|
+
const subItems = getChildren(row.original);
|
|
5
|
+
if (subItems === undefined) {
|
|
6
|
+
return row;
|
|
7
|
+
}
|
|
8
|
+
const subRows = getSubRows(subItems, row);
|
|
9
|
+
row.subRows = subRows.map((row) => withSubRows(row, getChildren));
|
|
10
|
+
return row;
|
|
11
|
+
};
|
|
12
|
+
export const addSubRows = ({ children }) => () => {
|
|
13
|
+
const getChildren = children instanceof Function ? children : (item) => item[children];
|
|
14
|
+
const deriveRows = (rows) => {
|
|
15
|
+
return derived(rows, ($rows) => {
|
|
16
|
+
return $rows.map((row) => {
|
|
17
|
+
if (row.isData()) {
|
|
18
|
+
return withSubRows(row, getChildren);
|
|
19
|
+
}
|
|
20
|
+
return row;
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
pluginState: {},
|
|
26
|
+
deriveRows
|
|
27
|
+
};
|
|
28
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BodyRow } from '../bodyRows.js';
|
|
2
|
+
import type { TablePlugin, NewTablePropSet } from '../types/TablePlugin.js';
|
|
3
|
+
import { type Readable, type Writable } from 'svelte/store';
|
|
4
|
+
export interface TableFilterConfig {
|
|
5
|
+
fn?: TableFilterFn;
|
|
6
|
+
initialFilterValue?: string;
|
|
7
|
+
includeHiddenColumns?: boolean;
|
|
8
|
+
serverSide?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface TableFilterState<Item> {
|
|
11
|
+
filterValue: Writable<string>;
|
|
12
|
+
preFilteredRows: Readable<BodyRow<Item>[]>;
|
|
13
|
+
}
|
|
14
|
+
export interface TableFilterColumnOptions<Item> {
|
|
15
|
+
exclude?: boolean;
|
|
16
|
+
getFilterValue?: (value: any) => string;
|
|
17
|
+
}
|
|
18
|
+
export type TableFilterFn = (props: TableFilterFnProps) => boolean;
|
|
19
|
+
export type TableFilterFnProps = {
|
|
20
|
+
filterValue: string;
|
|
21
|
+
value: string;
|
|
22
|
+
};
|
|
23
|
+
export type TableFilterPropSet = NewTablePropSet<{
|
|
24
|
+
'tbody.tr.td': {
|
|
25
|
+
matches: boolean;
|
|
26
|
+
};
|
|
27
|
+
}>;
|
|
28
|
+
export declare const addTableFilter: <Item>({ fn, initialFilterValue, includeHiddenColumns, serverSide }?: TableFilterConfig) => TablePlugin<Item, TableFilterState<Item>, TableFilterColumnOptions<Item>, TableFilterPropSet>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { recordSetStore } from '../utils/store.js';
|
|
2
|
+
import { derived, writable } from 'svelte/store';
|
|
3
|
+
import { textPrefixFilter } from './addColumnFilters.js';
|
|
4
|
+
const getFilteredRows = (rows, filterValue, columnOptions, { tableCellMatches, fn, includeHiddenColumns }) => {
|
|
5
|
+
const $filteredRows = rows
|
|
6
|
+
// Filter `subRows`
|
|
7
|
+
.map((row) => {
|
|
8
|
+
const { subRows } = row;
|
|
9
|
+
if (subRows === undefined) {
|
|
10
|
+
return row;
|
|
11
|
+
}
|
|
12
|
+
const filteredSubRows = getFilteredRows(subRows, filterValue, columnOptions, {
|
|
13
|
+
tableCellMatches,
|
|
14
|
+
fn,
|
|
15
|
+
includeHiddenColumns
|
|
16
|
+
});
|
|
17
|
+
const clonedRow = row.clone();
|
|
18
|
+
clonedRow.subRows = filteredSubRows;
|
|
19
|
+
return clonedRow;
|
|
20
|
+
})
|
|
21
|
+
.filter((row) => {
|
|
22
|
+
if ((row.subRows?.length ?? 0) !== 0) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
// An array of booleans, true if the cell matches the filter.
|
|
26
|
+
const rowCellMatches = Object.values(row.cellForId).map((cell) => {
|
|
27
|
+
const options = columnOptions[cell.id];
|
|
28
|
+
if (options?.exclude === true) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const isHidden = row.cells.find((c) => c.id === cell.id) === undefined;
|
|
32
|
+
if (isHidden && !includeHiddenColumns) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (!cell.isData()) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
let value = cell.value;
|
|
39
|
+
if (options?.getFilterValue !== undefined) {
|
|
40
|
+
value = options?.getFilterValue(value);
|
|
41
|
+
}
|
|
42
|
+
const matches = fn({ value: String(value), filterValue });
|
|
43
|
+
if (matches) {
|
|
44
|
+
const dataRowColId = cell.dataRowColId();
|
|
45
|
+
if (dataRowColId !== undefined) {
|
|
46
|
+
tableCellMatches[dataRowColId] = matches;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return matches;
|
|
50
|
+
});
|
|
51
|
+
// If any cell matches, include in the filtered results.
|
|
52
|
+
return rowCellMatches.includes(true);
|
|
53
|
+
});
|
|
54
|
+
return $filteredRows;
|
|
55
|
+
};
|
|
56
|
+
export const addTableFilter = ({ fn = textPrefixFilter, initialFilterValue = '', includeHiddenColumns = false, serverSide = false } = {}) => ({ columnOptions }) => {
|
|
57
|
+
const filterValue = writable(initialFilterValue);
|
|
58
|
+
const preFilteredRows = writable([]);
|
|
59
|
+
const tableCellMatches = recordSetStore();
|
|
60
|
+
const pluginState = { filterValue, preFilteredRows };
|
|
61
|
+
const deriveRows = (rows) => {
|
|
62
|
+
return derived([rows, filterValue], ([$rows, $filterValue]) => {
|
|
63
|
+
preFilteredRows.set($rows);
|
|
64
|
+
tableCellMatches.clear();
|
|
65
|
+
const $tableCellMatches = {};
|
|
66
|
+
const $filteredRows = getFilteredRows($rows, $filterValue, columnOptions, {
|
|
67
|
+
tableCellMatches: $tableCellMatches,
|
|
68
|
+
fn,
|
|
69
|
+
includeHiddenColumns
|
|
70
|
+
});
|
|
71
|
+
tableCellMatches.set($tableCellMatches);
|
|
72
|
+
if (serverSide) {
|
|
73
|
+
return $rows;
|
|
74
|
+
}
|
|
75
|
+
return $filteredRows;
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
pluginState,
|
|
80
|
+
deriveRows,
|
|
81
|
+
hooks: {
|
|
82
|
+
'tbody.tr.td': (cell) => {
|
|
83
|
+
const props = derived([filterValue, tableCellMatches], ([$filterValue, $tableCellMatches]) => {
|
|
84
|
+
const dataRowColId = cell.dataRowColId();
|
|
85
|
+
return {
|
|
86
|
+
matches: $filterValue !== '' &&
|
|
87
|
+
dataRowColId !== undefined &&
|
|
88
|
+
($tableCellMatches[dataRowColId] ?? false)
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
return { props };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from './addColumnFilters.js';
|
|
2
|
+
export * from './addColumnOrder.js';
|
|
3
|
+
export * from './addDataExport.js';
|
|
4
|
+
export * from './addExpandedRows.js';
|
|
5
|
+
export * from './addFlatten.js';
|
|
6
|
+
export * from './addGridLayout.js';
|
|
7
|
+
export * from './addGroupBy.js';
|
|
8
|
+
export * from './addHiddenColumns.js';
|
|
9
|
+
export * from './addPagination.js';
|
|
10
|
+
export * from './addResizedColumns.js';
|
|
11
|
+
export * from './addSelectedRows.js';
|
|
12
|
+
export * from './addSortBy.js';
|
|
13
|
+
export * from './addSubRows.js';
|
|
14
|
+
export * from './addTableFilter.js';
|
|
15
|
+
export * from '../types/TablePlugin.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from './addColumnFilters.js';
|
|
2
|
+
export * from './addColumnOrder.js';
|
|
3
|
+
export * from './addDataExport.js';
|
|
4
|
+
export * from './addExpandedRows.js';
|
|
5
|
+
export * from './addFlatten.js';
|
|
6
|
+
export * from './addGridLayout.js';
|
|
7
|
+
export * from './addGroupBy.js';
|
|
8
|
+
export * from './addHiddenColumns.js';
|
|
9
|
+
export * from './addPagination.js';
|
|
10
|
+
export * from './addResizedColumns.js';
|
|
11
|
+
export * from './addSelectedRows.js';
|
|
12
|
+
export * from './addSortBy.js';
|
|
13
|
+
export * from './addSubRows.js';
|
|
14
|
+
export * from './addTableFilter.js';
|
|
15
|
+
// plugin helper types
|
|
16
|
+
export * from '../types/TablePlugin.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Readable } from 'svelte/store';
|
|
2
|
+
import type { AnyPlugins, ComponentKeys, ElementHook, PluginTablePropSet } from './types/TablePlugin.js';
|
|
3
|
+
import type { TableState } from './createViewModel.js';
|
|
4
|
+
import type { Clonable } from './utils/clone.js';
|
|
5
|
+
export interface TableComponentInit {
|
|
6
|
+
id: string;
|
|
7
|
+
}
|
|
8
|
+
export declare abstract class TableComponent<Item, Plugins extends AnyPlugins, Key extends ComponentKeys> implements Clonable<TableComponent<Item, Plugins, Key>> {
|
|
9
|
+
id: string;
|
|
10
|
+
constructor({ id }: TableComponentInit);
|
|
11
|
+
private attrsForName;
|
|
12
|
+
attrs(): Readable<Record<string, unknown>>;
|
|
13
|
+
private propsForName;
|
|
14
|
+
props(): Readable<PluginTablePropSet<Plugins>[Key]>;
|
|
15
|
+
state?: TableState<Item, Plugins>;
|
|
16
|
+
injectState(state: TableState<Item, Plugins>): void;
|
|
17
|
+
applyHook(pluginName: string, hook: ElementHook<Record<string, unknown>, Record<string, unknown>>): void;
|
|
18
|
+
abstract clone(): TableComponent<Item, Plugins, Key>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { derived } from 'svelte/store';
|
|
2
|
+
import { derivedKeys } from '@humanspeak/svelte-subscribe';
|
|
3
|
+
import { finalizeAttributes, mergeAttributes } from './utils/attributes.js';
|
|
4
|
+
export class TableComponent {
|
|
5
|
+
id;
|
|
6
|
+
constructor({ id }) {
|
|
7
|
+
this.id = id;
|
|
8
|
+
}
|
|
9
|
+
attrsForName = {};
|
|
10
|
+
attrs() {
|
|
11
|
+
return derived(Object.values(this.attrsForName), ($attrsArray) => {
|
|
12
|
+
let $mergedAttrs = {};
|
|
13
|
+
$attrsArray.forEach(($attrs) => {
|
|
14
|
+
$mergedAttrs = mergeAttributes($mergedAttrs, $attrs);
|
|
15
|
+
});
|
|
16
|
+
return finalizeAttributes($mergedAttrs);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
propsForName = {};
|
|
20
|
+
props() {
|
|
21
|
+
return derivedKeys(this.propsForName);
|
|
22
|
+
}
|
|
23
|
+
state;
|
|
24
|
+
injectState(state) {
|
|
25
|
+
this.state = state;
|
|
26
|
+
}
|
|
27
|
+
applyHook(pluginName, hook) {
|
|
28
|
+
if (hook.props !== undefined) {
|
|
29
|
+
this.propsForName[pluginName] = hook.props;
|
|
30
|
+
}
|
|
31
|
+
if (hook.attrs !== undefined) {
|
|
32
|
+
this.attrsForName[pluginName] = hook.attrs;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type KeyPath<T, D extends number = 3> = KeyPath_<T, D, []>;
|
|
2
|
+
type KeyPath_<T, D extends number, S extends unknown[]> = D extends S['length'] ? never : T extends object ? {
|
|
3
|
+
[K in keyof T]-?: K extends string ? `${K}` | Join<K, KeyPath_<T[K], D, [never, ...S]>> : K extends number ? `[${K}]` | Join<`[${K}]`, KeyPath_<T[K], D, [never, ...S]>> : never;
|
|
4
|
+
}[keyof T] : '';
|
|
5
|
+
type Join<K, P> = K extends string | number ? P extends string | number ? P extends `[${string}` ? `${K}${P}` : `${K}${'' extends P ? '' : '.'}${P}` : never : never;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RenderConfig } from '@humanspeak/svelte-subscribe';
|
|
2
|
+
import type { DataBodyCell, DisplayBodyCell } from '../bodyCells.js';
|
|
3
|
+
import type { TableState } from '../createViewModel.js';
|
|
4
|
+
import type { HeaderCell } from '../headerCells.js';
|
|
5
|
+
import type { AnyPlugins } from './TablePlugin.js';
|
|
6
|
+
export type DataLabel<Item, Plugins extends AnyPlugins = AnyPlugins, Value = any> = (cell: DataBodyCell<Item, AnyPlugins, Value>, state: TableState<Item, Plugins>) => RenderConfig;
|
|
7
|
+
export type DisplayLabel<Item, Plugins extends AnyPlugins = AnyPlugins> = (cell: DisplayBodyCell<Item>, state: TableState<Item, Plugins>) => RenderConfig;
|
|
8
|
+
export type HeaderLabel<Item, Plugins extends AnyPlugins = AnyPlugins> = RenderConfig | ((cell: HeaderCell<Item, Plugins>, state: TableState<Item, Plugins>) => RenderConfig);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Matrix<T> = T[][];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { BodyCell, BodyCellAttributes } from '../bodyCells.js';
|
|
2
|
+
import type { BodyRow, BodyRowAttributes } from '../bodyRows.js';
|
|
3
|
+
import type { DataColumn, FlatColumn } from '../columns.js';
|
|
4
|
+
import type { HeaderCell, HeaderCellAttributes } from '../headerCells.js';
|
|
5
|
+
import type { HeaderRow, HeaderRowAttributes } from '../headerRows.js';
|
|
6
|
+
import type { PluginInitTableState, TableAttributes, TableBodyAttributes, TableHeadAttributes } from '../createViewModel.js';
|
|
7
|
+
import type { Readable } from 'svelte/store';
|
|
8
|
+
export type TablePlugin<Item, PluginState, ColumnOptions, TablePropSet extends AnyTablePropSet = AnyTablePropSet, TableAttributeSet extends AnyTableAttributeSet = AnyTableAttributeSet> = (init: TablePluginInit<Item, ColumnOptions>) => TablePluginInstance<Item, PluginState, ColumnOptions, TablePropSet, TableAttributeSet>;
|
|
9
|
+
export type TablePluginInit<Item, ColumnOptions> = {
|
|
10
|
+
pluginName: string;
|
|
11
|
+
tableState: PluginInitTableState<Item>;
|
|
12
|
+
columnOptions: Record<string, ColumnOptions>;
|
|
13
|
+
};
|
|
14
|
+
export type TablePluginInstance<Item, PluginState, ColumnOptions, TablePropSet extends AnyTablePropSet = AnyTablePropSet, TableAttributeSet extends AnyTableAttributeSet = AnyTableAttributeSet> = {
|
|
15
|
+
pluginState: PluginState;
|
|
16
|
+
transformFlatColumnsFn?: Readable<TransformFlatColumnsFn<Item>>;
|
|
17
|
+
deriveFlatColumns?: DeriveFlatColumnsFn<Item>;
|
|
18
|
+
deriveRows?: DeriveRowsFn<Item>;
|
|
19
|
+
derivePageRows?: DeriveRowsFn<Item>;
|
|
20
|
+
deriveTableAttrs?: DeriveFn<TableAttributes<Item>>;
|
|
21
|
+
deriveTableHeadAttrs?: DeriveFn<TableHeadAttributes<Item>>;
|
|
22
|
+
deriveTableBodyAttrs?: DeriveFn<TableBodyAttributes<Item>>;
|
|
23
|
+
columnOptions?: ColumnOptions;
|
|
24
|
+
hooks?: TableHooks<Item, TablePropSet, TableAttributeSet>;
|
|
25
|
+
};
|
|
26
|
+
export type AnyPlugins = Record<any, TablePlugin<any, any, any, any, any>>;
|
|
27
|
+
export type AnyPluginInstances = Record<any, TablePluginInstance<any, any, any, any, any>>;
|
|
28
|
+
export type TransformFlatColumnsFn<Item> = (flatColumns: DataColumn<Item>[]) => DataColumn<Item>[];
|
|
29
|
+
export type DeriveFlatColumnsFn<Item> = <Col extends FlatColumn<Item>>(flatColumns: Readable<Col[]>) => Readable<Col[]>;
|
|
30
|
+
export type DeriveRowsFn<Item> = <Row extends BodyRow<Item>>(rows: Readable<Row[]>) => Readable<Row[]>;
|
|
31
|
+
export type DeriveFn<T> = (obj: Readable<T>) => Readable<T>;
|
|
32
|
+
export type Components<Item, Plugins extends AnyPlugins = AnyPlugins> = {
|
|
33
|
+
'thead.tr': HeaderRow<Item, Plugins>;
|
|
34
|
+
'thead.tr.th': HeaderCell<Item, Plugins>;
|
|
35
|
+
'tbody.tr': BodyRow<Item, Plugins>;
|
|
36
|
+
'tbody.tr.td': BodyCell<Item, Plugins>;
|
|
37
|
+
};
|
|
38
|
+
export type AttributesForKey<Item, Plugins extends AnyPlugins = AnyPlugins> = {
|
|
39
|
+
'thead.tr': HeaderRowAttributes<Item, Plugins>;
|
|
40
|
+
'thead.tr.th': HeaderCellAttributes<Item, Plugins>;
|
|
41
|
+
'tbody.tr': BodyRowAttributes<Item, Plugins>;
|
|
42
|
+
'tbody.tr.td': BodyCellAttributes<Item, Plugins>;
|
|
43
|
+
};
|
|
44
|
+
export type ComponentKeys = keyof Components<unknown>;
|
|
45
|
+
type TablePropSet<PropSet extends {
|
|
46
|
+
[K in ComponentKeys]?: unknown;
|
|
47
|
+
}> = {
|
|
48
|
+
[K in ComponentKeys]: PropSet[K];
|
|
49
|
+
};
|
|
50
|
+
export type NewTablePropSet<PropSet extends {
|
|
51
|
+
[K in ComponentKeys]?: unknown;
|
|
52
|
+
}> = {
|
|
53
|
+
[K in ComponentKeys]: unknown extends PropSet[K] ? never : PropSet[K];
|
|
54
|
+
};
|
|
55
|
+
export type AnyTablePropSet = TablePropSet<any>;
|
|
56
|
+
type TableAttributeSet<AttributeSet extends {
|
|
57
|
+
[K in ComponentKeys]?: unknown;
|
|
58
|
+
}> = {
|
|
59
|
+
[K in ComponentKeys]: AttributeSet[K];
|
|
60
|
+
};
|
|
61
|
+
export type NewTableAttributeSet<AttributeSet extends {
|
|
62
|
+
[K in ComponentKeys]?: unknown;
|
|
63
|
+
}> = {
|
|
64
|
+
[K in ComponentKeys]: unknown extends AttributeSet[K] ? never : AttributeSet[K];
|
|
65
|
+
};
|
|
66
|
+
export type AnyTableAttributeSet = TableAttributeSet<any>;
|
|
67
|
+
export type TableHooks<Item, PropSet extends AnyTablePropSet = AnyTablePropSet, AttributeSet extends AnyTableAttributeSet = AnyTableAttributeSet> = {
|
|
68
|
+
[ComponentKey in keyof Components<Item>]?: (component: Components<Item>[ComponentKey]) => ElementHook<PropSet[ComponentKey], AttributeSet[ComponentKey]>;
|
|
69
|
+
};
|
|
70
|
+
export type ElementHook<Props, Attributes> = {
|
|
71
|
+
props?: Readable<Props>;
|
|
72
|
+
attrs?: Readable<Attributes>;
|
|
73
|
+
};
|
|
74
|
+
export type PluginStates<Plugins extends AnyPlugins> = {
|
|
75
|
+
[K in keyof Plugins]: ReturnType<Plugins[K]>['pluginState'];
|
|
76
|
+
};
|
|
77
|
+
type TablePropSetForPluginKey<Plugins extends AnyPlugins> = {
|
|
78
|
+
[K in keyof Plugins]: Plugins[K] extends TablePlugin<any, any, any, infer TablePropSet> ? TablePropSet : never;
|
|
79
|
+
};
|
|
80
|
+
export type PluginTablePropSet<Plugins extends AnyPlugins> = {
|
|
81
|
+
[ComponentKey in ComponentKeys]: {
|
|
82
|
+
[PluginKey in keyof Plugins]: TablePropSetForPluginKey<Plugins>[PluginKey][ComponentKey];
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
export type PluginColumnConfigs<Plugins extends AnyPlugins> = Partial<{
|
|
86
|
+
[K in keyof Plugins]: ReturnType<Plugins[K]>['columnOptions'];
|
|
87
|
+
}>;
|
|
88
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getCounter } from './counter.js';
|
|
2
|
+
export const getDistinct = (items) => {
|
|
3
|
+
return Array.from(getCounter(items).keys());
|
|
4
|
+
};
|
|
5
|
+
export const getDuplicates = (items) => {
|
|
6
|
+
return Array.from(getCounter(items).entries())
|
|
7
|
+
.filter(([, count]) => count !== 1)
|
|
8
|
+
.map(([key]) => key);
|
|
9
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { stringifyCss } from './css.js';
|
|
2
|
+
export const mergeAttributes = (a, b) => {
|
|
3
|
+
if (a.style === undefined && b.style === undefined) {
|
|
4
|
+
return { ...a, ...b };
|
|
5
|
+
}
|
|
6
|
+
return {
|
|
7
|
+
...a,
|
|
8
|
+
...b,
|
|
9
|
+
style: {
|
|
10
|
+
...(typeof a.style === 'object' ? a.style : {}),
|
|
11
|
+
...(typeof b.style === 'object' ? b.style : {})
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export const finalizeAttributes = (attrs) => {
|
|
16
|
+
if (attrs.style === undefined || typeof attrs.style !== 'object') {
|
|
17
|
+
return attrs;
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
...attrs,
|
|
21
|
+
style: stringifyCss(attrs.style)
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface Clonable<T> {
|
|
2
|
+
clone(): T;
|
|
3
|
+
}
|
|
4
|
+
export declare const isClonable: <T>(obj: unknown) => obj is Clonable<T>;
|
|
5
|
+
/**
|
|
6
|
+
* Create a new instance of a class instance with all properties shallow
|
|
7
|
+
* copied. This is unsafe as it does not re-run the constructor. Therefore,
|
|
8
|
+
* cloned instances will share a reference to the same property instances.
|
|
9
|
+
* @param source The original instance object.
|
|
10
|
+
* @param props Any additional properties to override.
|
|
11
|
+
* @returns A new instance object with all properties shallow copied.
|
|
12
|
+
*/
|
|
13
|
+
export declare const unsafeClone: <T extends object>(source: T, props?: Partial<T>) => T;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const isClonable = (obj) => {
|
|
2
|
+
return typeof obj.clone === 'function';
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* Create a new instance of a class instance with all properties shallow
|
|
6
|
+
* copied. This is unsafe as it does not re-run the constructor. Therefore,
|
|
7
|
+
* cloned instances will share a reference to the same property instances.
|
|
8
|
+
* @param source The original instance object.
|
|
9
|
+
* @param props Any additional properties to override.
|
|
10
|
+
* @returns A new instance object with all properties shallow copied.
|
|
11
|
+
*/
|
|
12
|
+
export const unsafeClone = (source, props) => {
|
|
13
|
+
const clone = Object.assign(Object.create(Object.getPrototypeOf(source)), source);
|
|
14
|
+
if (props !== undefined) {
|
|
15
|
+
Object.assign(clone, props);
|
|
16
|
+
}
|
|
17
|
+
return clone;
|
|
18
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const compare = (a, b) => {
|
|
2
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
3
|
+
return compareArray(a, b);
|
|
4
|
+
}
|
|
5
|
+
if (typeof a === 'number' && typeof b === 'number')
|
|
6
|
+
return a - b;
|
|
7
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
8
|
+
};
|
|
9
|
+
export const compareArray = (a, b) => {
|
|
10
|
+
const minLength = Math.min(a.length, b.length);
|
|
11
|
+
for (let i = 0; i < minLength; i++) {
|
|
12
|
+
const order = compare(a[i], b[i]);
|
|
13
|
+
if (order !== 0)
|
|
14
|
+
return order;
|
|
15
|
+
}
|
|
16
|
+
return 0;
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getCounter: <T>(items: T[]) => Map<T, number>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const stringifyCss: (style: Record<string, unknown>) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isShiftClick: (event: Event) => boolean;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const nonNull: <T>(value: T | null) => value is T;
|
|
2
|
+
export declare const nonUndefined: <T>(value: T | undefined) => value is T;
|
|
3
|
+
export declare const nonNullish: <T>(value: T | null | undefined) => value is T;
|
|
4
|
+
export declare const isNumber: (value: unknown) => value is number;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const getNullMatrix = (width, height) => {
|
|
2
|
+
const result = [];
|
|
3
|
+
// Use a loop to create a new array instance per row.
|
|
4
|
+
for (let i = 0; i < height; i++) {
|
|
5
|
+
result.push(Array(width).fill(null));
|
|
6
|
+
}
|
|
7
|
+
return result;
|
|
8
|
+
};
|
|
9
|
+
export const getTransposed = (matrix) => {
|
|
10
|
+
const height = matrix.length;
|
|
11
|
+
if (height === 0) {
|
|
12
|
+
return matrix;
|
|
13
|
+
}
|
|
14
|
+
const width = matrix[0].length;
|
|
15
|
+
const result = getNullMatrix(height, width);
|
|
16
|
+
for (let i = 0; i < width; i++) {
|
|
17
|
+
for (let j = 0; j < height; j++) {
|
|
18
|
+
result[i][j] = matrix[j][i];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// We guarantee that all elements are filled.
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Readable, type Writable } from 'svelte/store';
|
|
2
|
+
export type ReadOrWritable<T> = Readable<T> | Writable<T>;
|
|
3
|
+
export declare const isReadable: <T>(value: any) => value is Readable<T>;
|
|
4
|
+
export declare const isWritable: <T>(store: any) => store is Writable<T>;
|
|
5
|
+
export type WritableKeys<T> = {
|
|
6
|
+
[K in keyof T]: T[K] extends undefined ? Writable<T[K] | undefined> : Writable<T[K]>;
|
|
7
|
+
};
|
|
8
|
+
export type ReadableKeys<T> = {
|
|
9
|
+
[K in keyof T]: T[K] extends undefined ? Readable<T[K] | undefined> : Readable<T[K]>;
|
|
10
|
+
};
|
|
11
|
+
export type ReadOrWritableKeys<T> = {
|
|
12
|
+
[K in keyof T]: T[K] extends undefined ? ReadOrWritable<T[K] | undefined> : ReadOrWritable<T[K]>;
|
|
13
|
+
};
|
|
14
|
+
export declare const Undefined: Readable<undefined>;
|
|
15
|
+
export declare const UndefinedAs: <T>() => Readable<T>;
|
|
16
|
+
export interface ToggleOptions {
|
|
17
|
+
clearOthers?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface ArraySetStoreOptions<T> {
|
|
20
|
+
isEqual?: (a: T, b: T) => boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ArraySetStore<T> extends Writable<T[]> {
|
|
23
|
+
toggle: (item: T, options?: ToggleOptions) => void;
|
|
24
|
+
add: (item: T) => void;
|
|
25
|
+
remove: (item: T) => void;
|
|
26
|
+
clear: () => void;
|
|
27
|
+
}
|
|
28
|
+
export declare const arraySetStore: <T>(initial?: T[], { isEqual }?: ArraySetStoreOptions<T>) => ArraySetStore<T>;
|
|
29
|
+
export interface RecordSetStore<T extends string | number> extends Writable<Record<T, boolean>> {
|
|
30
|
+
toggle: (item: T) => void;
|
|
31
|
+
add: (item: T) => void;
|
|
32
|
+
addAll: (items: T[]) => void;
|
|
33
|
+
remove: (item: T) => void;
|
|
34
|
+
removeAll: (items: T[]) => void;
|
|
35
|
+
clear: () => void;
|
|
36
|
+
}
|
|
37
|
+
export declare const recordSetStore: <T extends string | number>(initial?: Record<T, boolean>) => RecordSetStore<T>;
|