compote-ui 0.42.7 → 0.43.1
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/components/data-table/column-helper.ts.md +96 -0
- package/dist/components/data-table/create-table.ts.md +386 -0
- package/dist/components/data-table/data-table-column-filter.svelte.md +249 -0
- package/dist/components/data-table/data-table-column-visibility.svelte.md +74 -0
- package/dist/components/data-table/{data-table-head.svelte → data-table-head.svelte.md} +1 -1
- package/dist/components/data-table/data-table-new.svelte.md +245 -0
- package/dist/components/data-table/data-table-title.svelte.md +16 -0
- package/dist/components/data-table/data-table-toolbar.svelte.md +40 -0
- package/dist/components/data-table/data-table-utils.ts.md +179 -0
- package/dist/components/data-table/{data-table-virtual-rows.svelte → data-table-virtual-rows.svelte.md} +1 -1
- package/dist/components/data-table/data-table-virtualized.svelte.md +108 -0
- package/dist/components/data-table/data-table.svelte.md +214 -0
- package/dist/components/data-table/index.ts.md +22 -0
- package/dist/components/data-table/types.ts.md +101 -0
- package/dist/components/data-table/virtual/index.ts.md +26 -0
- package/dist/components/{data-table → data-table-v8}/column-helper.d.ts +1 -1
- package/dist/components/data-table-v8/create-svelte-table.svelte.d.ts +8 -0
- package/dist/components/data-table-v8/create-svelte-table.svelte.js +85 -0
- package/dist/components/data-table-v8/create-table.svelte.d.ts +35 -0
- package/dist/components/{data-table/create-table.js → data-table-v8/create-table.svelte.js} +25 -55
- package/dist/components/{data-table → data-table-v8}/data-table-column-filter.svelte +16 -19
- package/dist/components/{data-table → data-table-v8}/data-table-column-filter.svelte.d.ts +2 -2
- package/dist/components/{data-table → data-table-v8}/data-table-column-visibility.svelte +15 -14
- package/dist/components/{data-table → data-table-v8}/data-table-column-visibility.svelte.d.ts +2 -2
- package/dist/components/data-table-v8/data-table-head.svelte +196 -0
- package/dist/components/{data-table → data-table-v8}/data-table-head.svelte.d.ts +3 -3
- package/dist/components/{data-table → data-table-v8}/data-table-utils.d.ts +10 -15
- package/dist/components/{data-table → data-table-v8}/data-table-utils.js +18 -12
- package/dist/components/data-table-v8/data-table-virtual-rows.svelte +166 -0
- package/dist/components/{data-table → data-table-v8}/data-table-virtual-rows.svelte.d.ts +3 -3
- package/dist/components/{data-table → data-table-v8}/data-table-virtualized.svelte +15 -14
- package/dist/components/{data-table → data-table-v8}/data-table-virtualized.svelte.d.ts +2 -2
- package/dist/components/{data-table → data-table-v8}/data-table.svelte +37 -26
- package/dist/components/{data-table → data-table-v8}/data-table.svelte.d.ts +2 -2
- package/dist/components/data-table-v8/flex-render.svelte +35 -0
- package/dist/components/data-table-v8/flex-render.svelte.d.ts +28 -0
- package/dist/components/{data-table → data-table-v8}/index.d.ts +4 -2
- package/dist/components/{data-table → data-table-v8}/index.js +3 -1
- package/dist/components/data-table-v8/render-helpers.d.ts +13 -0
- package/dist/components/data-table-v8/render-helpers.js +23 -0
- package/dist/components/{data-table → data-table-v8}/types.d.ts +12 -2
- package/dist/components/data-table-v8/virtual/index.d.ts +3 -0
- package/dist/components/data-table-v8/virtual/index.js +2 -0
- package/dist/theme.css +45 -0
- package/package.json +9 -9
- package/dist/components/data-table/create-table.d.ts +0 -41
- package/dist/components/data-table/virtual/index.d.ts +0 -3
- package/dist/components/data-table/virtual/index.js +0 -2
- /package/dist/components/{data-table → data-table-v8}/column-helper.js +0 -0
- /package/dist/components/{data-table → data-table-v8}/data-table-title.svelte +0 -0
- /package/dist/components/{data-table → data-table-v8}/data-table-title.svelte.d.ts +0 -0
- /package/dist/components/{data-table → data-table-v8}/data-table-toolbar.svelte +0 -0
- /package/dist/components/{data-table → data-table-v8}/data-table-toolbar.svelte.d.ts +0 -0
- /package/dist/components/{data-table → data-table-v8}/types.js +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { createTable } from '@tanstack/table-core';
|
|
2
|
+
export function createSvelteTable(options) {
|
|
3
|
+
const resolvedOptions = mergeObjects({
|
|
4
|
+
state: {},
|
|
5
|
+
onStateChange() { },
|
|
6
|
+
renderFallbackValue: null,
|
|
7
|
+
mergeOptions: (defaultOptions, options) => {
|
|
8
|
+
return mergeObjects(defaultOptions, options);
|
|
9
|
+
}
|
|
10
|
+
}, options);
|
|
11
|
+
const table = createTable(resolvedOptions);
|
|
12
|
+
let state = $state(table.initialState);
|
|
13
|
+
function updateOptions() {
|
|
14
|
+
table.setOptions(() => {
|
|
15
|
+
return mergeObjects(resolvedOptions, options, {
|
|
16
|
+
state: mergeObjects(state, options.state || {}),
|
|
17
|
+
onStateChange: (updater) => {
|
|
18
|
+
if (updater instanceof Function)
|
|
19
|
+
state = updater(state);
|
|
20
|
+
else
|
|
21
|
+
state = mergeObjects(state, updater);
|
|
22
|
+
options.onStateChange?.(updater);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
updateOptions();
|
|
28
|
+
$effect.pre(() => {
|
|
29
|
+
updateOptions();
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(table, '_svelteState', {
|
|
32
|
+
get() {
|
|
33
|
+
return state;
|
|
34
|
+
},
|
|
35
|
+
enumerable: false,
|
|
36
|
+
configurable: true
|
|
37
|
+
});
|
|
38
|
+
return table;
|
|
39
|
+
}
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
|
+
export function mergeObjects(...sources) {
|
|
42
|
+
const resolve = (src) => typeof src === 'function' ? (src() ?? undefined) : src;
|
|
43
|
+
const findSourceWithKey = (key) => {
|
|
44
|
+
for (let i = sources.length - 1; i >= 0; i--) {
|
|
45
|
+
const obj = resolve(sources[i]);
|
|
46
|
+
if (obj && key in obj)
|
|
47
|
+
return obj;
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
};
|
|
51
|
+
return new Proxy(Object.create(null), {
|
|
52
|
+
get(_, key) {
|
|
53
|
+
const src = findSourceWithKey(key);
|
|
54
|
+
return src?.[key];
|
|
55
|
+
},
|
|
56
|
+
has(_, key) {
|
|
57
|
+
return !!findSourceWithKey(key);
|
|
58
|
+
},
|
|
59
|
+
ownKeys() {
|
|
60
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity
|
|
61
|
+
const all = new Set();
|
|
62
|
+
for (const s of sources) {
|
|
63
|
+
const obj = resolve(s);
|
|
64
|
+
if (obj) {
|
|
65
|
+
for (const k of Reflect.ownKeys(obj)) {
|
|
66
|
+
all.add(k);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return [...all];
|
|
71
|
+
},
|
|
72
|
+
getOwnPropertyDescriptor(_, key) {
|
|
73
|
+
const src = findSourceWithKey(key);
|
|
74
|
+
if (!src)
|
|
75
|
+
return undefined;
|
|
76
|
+
return {
|
|
77
|
+
configurable: true,
|
|
78
|
+
enumerable: true,
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
80
|
+
value: src[key],
|
|
81
|
+
writable: true
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ColumnPinningState, type ColumnResizeMode, type ColumnSizingState, type VisibilityState, type FilterFn, type Row, type RowData, type Table } from '@tanstack/table-core';
|
|
2
|
+
import type { DataTableColumn, DataTableLeafColumn } from './types';
|
|
3
|
+
declare module '@tanstack/table-core' {
|
|
4
|
+
interface FilterFns {
|
|
5
|
+
oneOf: FilterFn<unknown>;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export type DataTableInstance<T extends RowData> = Table<T>;
|
|
9
|
+
export type CreateDataTableOptions<T extends RowData> = {
|
|
10
|
+
data: T[];
|
|
11
|
+
columns: DataTableColumn<T>[];
|
|
12
|
+
columnResizeMode?: ColumnResizeMode;
|
|
13
|
+
initialState?: {
|
|
14
|
+
columnVisibility?: VisibilityState;
|
|
15
|
+
columnSizing?: ColumnSizingState;
|
|
16
|
+
columnPinning?: ColumnPinningState;
|
|
17
|
+
rowSelection?: Record<string, boolean>;
|
|
18
|
+
sorting?: {
|
|
19
|
+
id: string;
|
|
20
|
+
desc: boolean;
|
|
21
|
+
}[];
|
|
22
|
+
columnFilters?: {
|
|
23
|
+
id: string;
|
|
24
|
+
value: unknown;
|
|
25
|
+
}[];
|
|
26
|
+
};
|
|
27
|
+
getRowId?: (row: T, index: number, parent?: Row<T>) => string;
|
|
28
|
+
enableRowSelection?: boolean | ((row: Row<T>) => boolean);
|
|
29
|
+
enableMultiRowSelection?: boolean | ((row: Row<T>) => boolean);
|
|
30
|
+
enableSorting?: boolean;
|
|
31
|
+
debugTable?: boolean;
|
|
32
|
+
onColumnVisibilityChange?: (visibility: VisibilityState) => void;
|
|
33
|
+
};
|
|
34
|
+
export declare function createTable<T extends RowData>(options: CreateDataTableOptions<T>): Table<T>;
|
|
35
|
+
export declare function getColumnId<T extends RowData>(column: DataTableLeafColumn<T>): string;
|
|
@@ -1,21 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
// createFacetedRowModel,
|
|
3
|
-
// createFacetedMinMaxValues,
|
|
4
|
-
// createFacetedUniqueValues,
|
|
5
|
-
createTable as createTanStackTable, filterFns, renderComponent, renderSnippet, rowSelectionFeature, rowSortingFeature, sortFns, tableFeatures } from '@tanstack/svelte-table';
|
|
6
|
-
import { createAtom } from '@tanstack/svelte-store';
|
|
1
|
+
import { getCoreRowModel, getSortedRowModel, getFilteredRowModel, getFacetedRowModel, getFacetedUniqueValues, getFacetedMinMaxValues } from '@tanstack/table-core';
|
|
7
2
|
import { useLocaleContext } from '@ark-ui/svelte/locale';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
columnSizingFeature,
|
|
11
|
-
columnResizingFeature,
|
|
12
|
-
columnFilteringFeature,
|
|
13
|
-
columnFacetingFeature,
|
|
14
|
-
columnPinningFeature,
|
|
15
|
-
columnOrderingFeature,
|
|
16
|
-
rowSelectionFeature,
|
|
17
|
-
rowSortingFeature
|
|
18
|
-
});
|
|
3
|
+
import { createSvelteTable } from './create-svelte-table.svelte';
|
|
4
|
+
import { renderComponent, renderSnippet } from './render-helpers';
|
|
19
5
|
function oneOfFilterFn(row, columnId, filterValue) {
|
|
20
6
|
return filterValue.includes(String(row.getValue(columnId)));
|
|
21
7
|
}
|
|
@@ -26,33 +12,35 @@ export function createTable(options) {
|
|
|
26
12
|
...createColumnVisibility(options.columns),
|
|
27
13
|
...options.initialState?.columnVisibility
|
|
28
14
|
};
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const table = createTanStackTable({
|
|
33
|
-
_features: dataTableFeatures,
|
|
34
|
-
_rowModels: {
|
|
35
|
-
sortedRowModel: createSortedRowModel(sortFns),
|
|
36
|
-
filteredRowModel: createFilteredRowModel({ ...filterFns, oneOf: oneOfFilterFn })
|
|
37
|
-
// facetedRowModel: createFacetedRowModel(),
|
|
38
|
-
// facetedMinMaxValues: createFacetedMinMaxValues(),
|
|
39
|
-
// facetedUniqueValues: createFacetedUniqueValues()
|
|
15
|
+
const table = createSvelteTable({
|
|
16
|
+
get data() {
|
|
17
|
+
return options.data;
|
|
40
18
|
},
|
|
19
|
+
columns: createColumns(options.columns, localeCtx),
|
|
20
|
+
getCoreRowModel: getCoreRowModel(),
|
|
21
|
+
getSortedRowModel: getSortedRowModel(),
|
|
22
|
+
getFilteredRowModel: getFilteredRowModel(),
|
|
23
|
+
getFacetedRowModel: getFacetedRowModel(),
|
|
24
|
+
getFacetedUniqueValues: getFacetedUniqueValues(),
|
|
25
|
+
getFacetedMinMaxValues: getFacetedMinMaxValues(),
|
|
41
26
|
columnResizeMode: options.columnResizeMode,
|
|
42
27
|
getRowId: options.getRowId,
|
|
43
28
|
enableRowSelection: options.enableRowSelection ?? false,
|
|
44
29
|
enableMultiRowSelection: options.enableMultiRowSelection,
|
|
45
30
|
enableSorting: options.enableSorting,
|
|
46
31
|
debugTable: options.debugTable,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
get columns() {
|
|
51
|
-
return createColumns(options.columns, localeCtx);
|
|
32
|
+
filterFns: {
|
|
33
|
+
oneOf: oneOfFilterFn
|
|
52
34
|
},
|
|
53
|
-
...(
|
|
35
|
+
...(options.onColumnVisibilityChange
|
|
36
|
+
? {
|
|
37
|
+
onColumnVisibilityChange: (updater) => {
|
|
38
|
+
const newVis = typeof updater === 'function' ? updater(table.getState().columnVisibility) : updater;
|
|
39
|
+
options.onColumnVisibilityChange(newVis);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
: {}),
|
|
54
43
|
initialState: {
|
|
55
|
-
...options.initialState,
|
|
56
44
|
columnVisibility: initialColumnVisibility,
|
|
57
45
|
columnSizing: {
|
|
58
46
|
...createColumnSizing(options.columns),
|
|
@@ -63,25 +51,7 @@ export function createTable(options) {
|
|
|
63
51
|
sorting: options.initialState?.sorting ?? [],
|
|
64
52
|
columnFilters: options.initialState?.columnFilters ?? []
|
|
65
53
|
}
|
|
66
|
-
}
|
|
67
|
-
columnVisibility: state.columnVisibility,
|
|
68
|
-
columnSizing: state.columnSizing,
|
|
69
|
-
columnResizing: state.columnResizing,
|
|
70
|
-
rowSelection: state.rowSelection,
|
|
71
|
-
sorting: state.sorting,
|
|
72
|
-
columnFilters: state.columnFilters
|
|
73
|
-
}));
|
|
74
|
-
if (columnVisibilityAtom && options.onColumnVisibilityChange) {
|
|
75
|
-
const { onColumnVisibilityChange } = options;
|
|
76
|
-
let initialized = false;
|
|
77
|
-
columnVisibilityAtom.subscribe((value) => {
|
|
78
|
-
if (!initialized) {
|
|
79
|
-
initialized = true;
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
onColumnVisibilityChange(value);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
54
|
+
});
|
|
85
55
|
return table;
|
|
86
56
|
}
|
|
87
57
|
function createColumnVisibility(columns) {
|
|
@@ -128,8 +98,8 @@ function createColumns(columns, localeCtx) {
|
|
|
128
98
|
enableResizing: column.enableResizing,
|
|
129
99
|
enableHiding: getColumnEnableHiding(column, columnId),
|
|
130
100
|
enableSorting: column.enableSorting,
|
|
131
|
-
enableColumnFilter: column.enableColumnFilter,
|
|
132
101
|
sortDescFirst: column.sortDescFirst,
|
|
102
|
+
enableColumnFilter: column.enableColumnFilter,
|
|
133
103
|
...(derivedFilterFn !== undefined ? { filterFn: derivedFilterFn } : {}),
|
|
134
104
|
meta: {
|
|
135
105
|
align: column.align,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends RowData">
|
|
2
2
|
import { onDestroy } from 'svelte';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Column, RowData } from '@tanstack/table-core';
|
|
4
4
|
import * as Popover from '../popover';
|
|
5
5
|
import * as ScrollArea from '../scroll-area';
|
|
6
6
|
import Checkbox from '../checkbox/checkbox.svelte';
|
|
7
7
|
import { cn } from 'tailwind-variants';
|
|
8
|
-
import
|
|
8
|
+
import { getReactiveTableState, type DataTableInstance } from './data-table-utils';
|
|
9
9
|
import NumberInput from '../number-input/number-input.svelte';
|
|
10
10
|
import * as Field from '../field';
|
|
11
11
|
|
|
@@ -21,21 +21,24 @@
|
|
|
21
21
|
let localNumMax: Record<string, number> = $state({});
|
|
22
22
|
const timers: Record<string, ReturnType<typeof setTimeout>> = {};
|
|
23
23
|
|
|
24
|
-
const columnFilters = $derived(table.
|
|
24
|
+
const columnFilters = $derived(getReactiveTableState(table).columnFilters);
|
|
25
25
|
const activeCount = $derived(columnFilters.length);
|
|
26
|
-
const filterableColumns = $derived
|
|
26
|
+
const filterableColumns = $derived.by(() => {
|
|
27
|
+
getReactiveTableState(table);
|
|
28
|
+
return table.getAllLeafColumns().filter((col) => col.getCanFilter());
|
|
29
|
+
});
|
|
27
30
|
|
|
28
31
|
onDestroy(() => {
|
|
29
32
|
Object.values(timers).forEach(clearTimeout);
|
|
30
33
|
});
|
|
31
34
|
|
|
32
|
-
function getColumnType(column: Column<
|
|
35
|
+
function getColumnType(column: Column<T, unknown>): string | undefined {
|
|
33
36
|
return (column.columnDef.meta as Record<string, unknown> | undefined)?.type as
|
|
34
37
|
| string
|
|
35
38
|
| undefined;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
function getColumnLabel(column: Column<
|
|
41
|
+
function getColumnLabel(column: Column<T, unknown>): string {
|
|
39
42
|
return typeof column.columnDef.header === 'string' ? column.columnDef.header : column.id;
|
|
40
43
|
}
|
|
41
44
|
|
|
@@ -48,7 +51,7 @@
|
|
|
48
51
|
table.resetColumnFilters();
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
function handleTextInput(column: Column<
|
|
54
|
+
function handleTextInput(column: Column<T, unknown>, value: string) {
|
|
52
55
|
localText[column.id] = value;
|
|
53
56
|
clearTimeout(timers[column.id]);
|
|
54
57
|
timers[column.id] = setTimeout(() => {
|
|
@@ -57,7 +60,7 @@
|
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
function handleNumericInput(
|
|
60
|
-
column: Column<
|
|
63
|
+
column: Column<T, unknown>,
|
|
61
64
|
which: 'min' | 'max',
|
|
62
65
|
value: number | null
|
|
63
66
|
) {
|
|
@@ -76,33 +79,27 @@
|
|
|
76
79
|
}, 300);
|
|
77
80
|
}
|
|
78
81
|
|
|
79
|
-
function getSelectValues(column: Column<
|
|
82
|
+
function getSelectValues(column: Column<T, unknown>): string[] {
|
|
80
83
|
return (column.getFilterValue() as string[] | undefined) ?? [];
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
function handleSelectChange(
|
|
84
|
-
column: Column<DataTableFeatures, T, CellData>,
|
|
85
|
-
value: string,
|
|
86
|
-
checked: boolean
|
|
87
|
-
) {
|
|
86
|
+
function handleSelectChange(column: Column<T, unknown>, value: string, checked: boolean) {
|
|
88
87
|
const current = getSelectValues(column);
|
|
89
88
|
const next = checked ? [...current, value] : current.filter((v) => v !== value);
|
|
90
89
|
column.setFilterValue(next.length ? next : undefined);
|
|
91
90
|
}
|
|
92
91
|
|
|
93
|
-
function getFacetedValues(column: Column<
|
|
92
|
+
function getFacetedValues(column: Column<T, unknown>): string[] {
|
|
94
93
|
return Array.from(column.getFacetedUniqueValues().keys()).map(String).sort();
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
function getFacetedMinMax(
|
|
98
|
-
column: Column<DataTableFeatures, T, CellData>
|
|
99
|
-
): [number | undefined, number | undefined] {
|
|
96
|
+
function getFacetedMinMax(column: Column<T, unknown>): [number | undefined, number | undefined] {
|
|
100
97
|
const vals = column.getFacetedMinMaxValues();
|
|
101
98
|
return vals ? [vals[0] as number, vals[1] as number] : [undefined, undefined];
|
|
102
99
|
}
|
|
103
100
|
|
|
104
101
|
function getColumnFormatOptions(
|
|
105
|
-
column: Column<
|
|
102
|
+
column: Column<T, unknown>
|
|
106
103
|
): Intl.NumberFormatOptions | undefined {
|
|
107
104
|
return (column.columnDef.meta as Record<string, unknown> | undefined)?.formatOptions as
|
|
108
105
|
| Intl.NumberFormatOptions
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RowData } from '@tanstack/
|
|
2
|
-
import type
|
|
1
|
+
import type { RowData } from '@tanstack/table-core';
|
|
2
|
+
import { type DataTableInstance } from './data-table-utils';
|
|
3
3
|
declare function $$render<T extends RowData>(): {
|
|
4
4
|
props: {
|
|
5
5
|
table: DataTableInstance<T>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends RowData">
|
|
2
|
-
import type {
|
|
2
|
+
import type { RowData } from '@tanstack/table-core';
|
|
3
3
|
import * as Popover from '../popover';
|
|
4
4
|
import * as ScrollArea from '../scroll-area';
|
|
5
5
|
import Checkbox from '../checkbox/checkbox.svelte';
|
|
6
|
-
import
|
|
6
|
+
import { getReactiveTableState, type DataTableInstance } from './data-table-utils';
|
|
7
7
|
|
|
8
8
|
type Props = {
|
|
9
9
|
table: DataTableInstance<T>;
|
|
@@ -12,23 +12,24 @@
|
|
|
12
12
|
|
|
13
13
|
let { table, triggerLabel = 'Columns' }: Props = $props();
|
|
14
14
|
|
|
15
|
-
const columnVisibility = $derived(table.
|
|
16
|
-
const
|
|
15
|
+
const columnVisibility = $derived(getReactiveTableState(table).columnVisibility);
|
|
16
|
+
const allLeafColumns = $derived.by(() => {
|
|
17
|
+
getReactiveTableState(table);
|
|
18
|
+
return table.getAllLeafColumns();
|
|
19
|
+
});
|
|
20
|
+
const allColumnsVisible = $derived(
|
|
21
|
+
allLeafColumns.every((c) => !c.getCanHide() || columnVisibility[c.id] !== false)
|
|
22
|
+
);
|
|
17
23
|
const someColumnsVisible = $derived(
|
|
18
|
-
|
|
24
|
+
allLeafColumns.some((c) => c.getCanHide() && columnVisibility[c.id] !== false)
|
|
19
25
|
);
|
|
20
26
|
const allColumnsVisibilityState = $derived(
|
|
21
|
-
allColumnsVisible ? true : someColumnsVisible ? 'indeterminate' : false
|
|
27
|
+
allColumnsVisible ? true : someColumnsVisible ? ('indeterminate' as const) : false
|
|
22
28
|
);
|
|
23
29
|
|
|
24
|
-
function getColumnLabel(column:
|
|
30
|
+
function getColumnLabel(column: { columnDef: { header?: unknown }; id: string }) {
|
|
25
31
|
return typeof column.columnDef.header === 'string' ? column.columnDef.header : column.id;
|
|
26
32
|
}
|
|
27
|
-
|
|
28
|
-
function getColumnIsVisible(column: Column<DataTableFeatures, T, CellData>, state: unknown) {
|
|
29
|
-
void state;
|
|
30
|
-
return column.getIsVisible();
|
|
31
|
-
}
|
|
32
33
|
</script>
|
|
33
34
|
|
|
34
35
|
<Popover.Root positioning={{ placement: 'bottom-end' }}>
|
|
@@ -52,12 +53,12 @@
|
|
|
52
53
|
<ScrollArea.Viewport>
|
|
53
54
|
<ScrollArea.Content class="py-1 pe-3">
|
|
54
55
|
<div class="flex flex-col">
|
|
55
|
-
{#each
|
|
56
|
+
{#each allLeafColumns as column (column.id)}
|
|
56
57
|
<Checkbox
|
|
57
58
|
size="md"
|
|
58
59
|
label={getColumnLabel(column)}
|
|
59
60
|
class="min-h-8 rounded-sm px-2 hover:bg-surface-2"
|
|
60
|
-
checked={
|
|
61
|
+
checked={columnVisibility[column.id] !== false}
|
|
61
62
|
disabled={!column.getCanHide()}
|
|
62
63
|
onCheckedChange={({ checked }) => column.toggleVisibility(checked === true)}
|
|
63
64
|
/>
|
package/dist/components/{data-table → data-table-v8}/data-table-column-visibility.svelte.d.ts
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RowData } from '@tanstack/
|
|
2
|
-
import type
|
|
1
|
+
import type { RowData } from '@tanstack/table-core';
|
|
2
|
+
import { type DataTableInstance } from './data-table-utils';
|
|
3
3
|
declare function $$render<T extends RowData>(): {
|
|
4
4
|
props: {
|
|
5
5
|
table: DataTableInstance<T>;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends RowData">
|
|
2
|
+
import type { HeaderGroup, RowData } from '@tanstack/table-core';
|
|
3
|
+
import { cn } from 'tailwind-variants';
|
|
4
|
+
import { PhCaretDown, PhCaretUp } from '../../icons';
|
|
5
|
+
import type { DataTableInstance } from './data-table-utils';
|
|
6
|
+
import FlexRender from './flex-render.svelte';
|
|
7
|
+
import {
|
|
8
|
+
alignClass,
|
|
9
|
+
getColumnMeta,
|
|
10
|
+
getHeaderAriaSort,
|
|
11
|
+
getHeaderSortDirection,
|
|
12
|
+
getHeaderSortLabel,
|
|
13
|
+
getPinningStyle,
|
|
14
|
+
joinStyles,
|
|
15
|
+
justifyClass,
|
|
16
|
+
resizeHandleClass,
|
|
17
|
+
resizeHandleStyle,
|
|
18
|
+
sortButtonDirectionClass,
|
|
19
|
+
virtualColumnSizeStyle,
|
|
20
|
+
virtualGroupWithGrowSizeStyle,
|
|
21
|
+
virtualGrowColumnSizeStyle,
|
|
22
|
+
virtualSelectionColumnSizeStyle
|
|
23
|
+
} from './data-table-utils';
|
|
24
|
+
|
|
25
|
+
type Props = {
|
|
26
|
+
table: DataTableInstance<T>;
|
|
27
|
+
headerGroups: HeaderGroup<T>[];
|
|
28
|
+
headerGroupCount: number;
|
|
29
|
+
isRowSelectionEnabled: boolean;
|
|
30
|
+
isMultiRowSelectionEnabled: boolean;
|
|
31
|
+
allRowsSelectionState: boolean | 'indeterminate';
|
|
32
|
+
isVirtual?: boolean;
|
|
33
|
+
hasGrowColumn?: boolean;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
let {
|
|
37
|
+
table,
|
|
38
|
+
headerGroups,
|
|
39
|
+
headerGroupCount,
|
|
40
|
+
isRowSelectionEnabled,
|
|
41
|
+
isMultiRowSelectionEnabled,
|
|
42
|
+
allRowsSelectionState,
|
|
43
|
+
isVirtual = false,
|
|
44
|
+
hasGrowColumn = false
|
|
45
|
+
}: Props = $props();
|
|
46
|
+
|
|
47
|
+
type Header = HeaderGroup<T>['headers'][number];
|
|
48
|
+
|
|
49
|
+
function findGrowLeafHeader(header: Header): Header | undefined {
|
|
50
|
+
if (header.subHeaders.length === 0) {
|
|
51
|
+
return getColumnMeta(header.column.columnDef)?.grow ? header : undefined;
|
|
52
|
+
}
|
|
53
|
+
for (const sub of header.subHeaders) {
|
|
54
|
+
const found = findGrowLeafHeader(sub);
|
|
55
|
+
if (found) return found;
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function headerCellStyle(header: Header) {
|
|
61
|
+
const canPinHeader = header.subHeaders.length === 0;
|
|
62
|
+
|
|
63
|
+
let virtualSizeStyle: string | undefined;
|
|
64
|
+
if (isVirtual) {
|
|
65
|
+
const isGrowLeaf = canPinHeader && getColumnMeta(header.column.columnDef)?.grow;
|
|
66
|
+
if (isGrowLeaf) {
|
|
67
|
+
virtualSizeStyle = virtualGrowColumnSizeStyle();
|
|
68
|
+
} else {
|
|
69
|
+
const growLeaf = findGrowLeafHeader(header);
|
|
70
|
+
virtualSizeStyle = growLeaf
|
|
71
|
+
? virtualGroupWithGrowSizeStyle(header.getSize() - growLeaf.getSize())
|
|
72
|
+
: virtualColumnSizeStyle(header.getSize());
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return joinStyles(
|
|
77
|
+
virtualSizeStyle,
|
|
78
|
+
canPinHeader ? getPinningStyle(header.column, table, true, isRowSelectionEnabled) : undefined
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function selectionHeaderStyle() {
|
|
83
|
+
return isVirtual
|
|
84
|
+
? joinStyles(
|
|
85
|
+
virtualSelectionColumnSizeStyle(),
|
|
86
|
+
'min-width: 40px',
|
|
87
|
+
'max-width: 40px',
|
|
88
|
+
'position: sticky',
|
|
89
|
+
'left: 0',
|
|
90
|
+
'z-index: 30'
|
|
91
|
+
)
|
|
92
|
+
: 'width: 40px; min-width: 40px; max-width: 40px; position: sticky; left: 0; z-index: 15';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function headerRowStyle() {
|
|
96
|
+
if (!isVirtual) return undefined;
|
|
97
|
+
return joinStyles('display: flex', 'width: 100%');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function shouldRenderSelectionCheckbox(headerGroupIndex: number) {
|
|
101
|
+
if (!isMultiRowSelectionEnabled) return false;
|
|
102
|
+
return headerGroupIndex === headerGroupCount - 1;
|
|
103
|
+
}
|
|
104
|
+
</script>
|
|
105
|
+
|
|
106
|
+
<thead
|
|
107
|
+
class="sticky top-0 z-20 bg-surface-2 text-left text-ink-dim"
|
|
108
|
+
style={isVirtual ? 'display: grid; position: sticky; top: 0; z-index: 20' : undefined}
|
|
109
|
+
>
|
|
110
|
+
{#each headerGroups as headerGroup, headerGroupIndex (headerGroup.id)}
|
|
111
|
+
{@const visibleHeaders = headerGroup.headers.filter((header) => header.colSpan > 0)}
|
|
112
|
+
<tr class="h-9" style={headerRowStyle()}>
|
|
113
|
+
{#if isRowSelectionEnabled}
|
|
114
|
+
<th
|
|
115
|
+
class={cn(
|
|
116
|
+
'h-9 border-b border-surface-3 bg-surface-2 px-3 py-0 text-center align-middle leading-5 font-medium',
|
|
117
|
+
isVirtual && 'items-center justify-center'
|
|
118
|
+
)}
|
|
119
|
+
style={selectionHeaderStyle()}
|
|
120
|
+
>
|
|
121
|
+
{#if shouldRenderSelectionCheckbox(headerGroupIndex)}
|
|
122
|
+
<input
|
|
123
|
+
type="checkbox"
|
|
124
|
+
aria-label="Select all rows"
|
|
125
|
+
class="table-checkbox mx-auto block size-4"
|
|
126
|
+
checked={allRowsSelectionState === true}
|
|
127
|
+
indeterminate={allRowsSelectionState === 'indeterminate'}
|
|
128
|
+
onchange={(e) => table.toggleAllRowsSelected(e.currentTarget.checked)}
|
|
129
|
+
/>
|
|
130
|
+
{/if}
|
|
131
|
+
</th>
|
|
132
|
+
{/if}
|
|
133
|
+
{#each visibleHeaders as header, headerIndex (header.id)}
|
|
134
|
+
{@const columnDef = getColumnMeta(header.column.columnDef)}
|
|
135
|
+
{@const sortDirection = getHeaderSortDirection(header)}
|
|
136
|
+
<th
|
|
137
|
+
class={cn(
|
|
138
|
+
'relative h-9 border-b border-surface-3 bg-surface-2 px-3 py-0 align-middle leading-5 font-medium',
|
|
139
|
+
isVirtual && 'items-center',
|
|
140
|
+
isVirtual && justifyClass(columnDef?.align),
|
|
141
|
+
alignClass(columnDef?.align)
|
|
142
|
+
)}
|
|
143
|
+
colspan={header.colSpan}
|
|
144
|
+
aria-sort={header.column.getCanSort() ? getHeaderAriaSort(sortDirection) : undefined}
|
|
145
|
+
style={headerCellStyle(header)}
|
|
146
|
+
>
|
|
147
|
+
{#if !header.isPlaceholder}
|
|
148
|
+
{#if header.column.getCanSort()}
|
|
149
|
+
<button
|
|
150
|
+
type="button"
|
|
151
|
+
class={cn(
|
|
152
|
+
'inline-flex max-w-full appearance-none items-center gap-1 rounded-sm border-0 bg-transparent p-0 align-middle text-sm leading-5 text-inherit outline-none hover:text-ink data-focus-visible:outline-2 data-focus-visible:outline-offset-2 data-focus-visible:outline-ring',
|
|
153
|
+
justifyClass(columnDef?.align),
|
|
154
|
+
sortButtonDirectionClass(columnDef?.align)
|
|
155
|
+
)}
|
|
156
|
+
aria-label={`${getHeaderSortLabel(sortDirection)}. Toggle sorting.`}
|
|
157
|
+
onclick={header.column.getToggleSortingHandler()}
|
|
158
|
+
>
|
|
159
|
+
<span class="min-w-0 truncate">
|
|
160
|
+
<FlexRender
|
|
161
|
+
content={header.column.columnDef.header}
|
|
162
|
+
context={header.getContext()}
|
|
163
|
+
/>
|
|
164
|
+
</span>
|
|
165
|
+
<span
|
|
166
|
+
class="inline-flex size-3.5 shrink-0 items-center justify-center text-ink-dim"
|
|
167
|
+
>
|
|
168
|
+
{#if sortDirection === 'asc'}
|
|
169
|
+
<PhCaretUp class="size-3.5" />
|
|
170
|
+
{:else if sortDirection === 'desc'}
|
|
171
|
+
<PhCaretDown class="size-3.5" />
|
|
172
|
+
{/if}
|
|
173
|
+
</span>
|
|
174
|
+
</button>
|
|
175
|
+
{:else}
|
|
176
|
+
<FlexRender content={header.column.columnDef.header} context={header.getContext()} />
|
|
177
|
+
{/if}
|
|
178
|
+
{/if}
|
|
179
|
+
{#if header.column.getCanResize()}
|
|
180
|
+
<div
|
|
181
|
+
aria-hidden="true"
|
|
182
|
+
class={resizeHandleClass(headerIndex, visibleHeaders.length)}
|
|
183
|
+
style={resizeHandleStyle(table, header)}
|
|
184
|
+
ondblclick={() => header.column.resetSize()}
|
|
185
|
+
onmousedown={header.getResizeHandler()}
|
|
186
|
+
ontouchstart={header.getResizeHandler()}
|
|
187
|
+
></div>
|
|
188
|
+
{/if}
|
|
189
|
+
</th>
|
|
190
|
+
{/each}
|
|
191
|
+
{#if !isVirtual && !hasGrowColumn}
|
|
192
|
+
<th aria-hidden="true" class="h-9 border-b border-surface-3 bg-surface-2 p-0"></th>
|
|
193
|
+
{/if}
|
|
194
|
+
</tr>
|
|
195
|
+
{/each}
|
|
196
|
+
</thead>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { HeaderGroup, RowData } from '@tanstack/
|
|
2
|
-
import type {
|
|
1
|
+
import type { HeaderGroup, RowData } from '@tanstack/table-core';
|
|
2
|
+
import type { DataTableInstance } from './data-table-utils';
|
|
3
3
|
declare function $$render<T extends RowData>(): {
|
|
4
4
|
props: {
|
|
5
5
|
table: DataTableInstance<T>;
|
|
6
|
-
headerGroups: HeaderGroup<
|
|
6
|
+
headerGroups: HeaderGroup<T>[];
|
|
7
7
|
headerGroupCount: number;
|
|
8
8
|
isRowSelectionEnabled: boolean;
|
|
9
9
|
isMultiRowSelectionEnabled: boolean;
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { DataTableFeatures, DataTableInstance } from './create-table';
|
|
1
|
+
import type { Column, Header, Row, RowData, Table, TableState, VisibilityState } from '@tanstack/table-core';
|
|
3
2
|
import type { DataTableColumnMeta } from './types';
|
|
4
|
-
export type
|
|
5
|
-
|
|
6
|
-
getStart(position?: ColumnPinningPosition): number;
|
|
7
|
-
getAfter(position?: ColumnPinningPosition): number;
|
|
8
|
-
getIsLastColumn(position?: ColumnPinningPosition): boolean;
|
|
9
|
-
getIsFirstColumn(position?: ColumnPinningPosition): boolean;
|
|
10
|
-
};
|
|
3
|
+
export type DataTableInstance<T extends RowData> = Table<T>;
|
|
4
|
+
export declare function getReactiveTableState<T extends RowData>(table: DataTableInstance<T>): TableState;
|
|
11
5
|
export declare function alignClass(align: DataTableColumnMeta['align']): "text-right" | "text-center" | "text-left";
|
|
12
6
|
export declare function justifyClass(align: DataTableColumnMeta['align']): "justify-end" | "justify-center" | "justify-start";
|
|
13
7
|
export declare function sortButtonDirectionClass(align: DataTableColumnMeta['align']): "flex-row-reverse" | "flex-row";
|
|
@@ -18,16 +12,17 @@ export declare function virtualSelectionColumnSizeStyle(): string;
|
|
|
18
12
|
export declare function tableSizeStyle<T extends RowData>(table: DataTableInstance<T>, isRowSelectionEnabled: boolean): string;
|
|
19
13
|
export declare function virtualGrowColumnSizeStyle(): string;
|
|
20
14
|
export declare function virtualGroupWithGrowSizeStyle(fixedPortion: number): string;
|
|
21
|
-
export declare function resizeHandleStyle<T extends RowData>(table: DataTableInstance<T>, header: Header<
|
|
15
|
+
export declare function resizeHandleStyle<T extends RowData>(table: DataTableInstance<T>, header: Header<T, unknown>): string | undefined;
|
|
22
16
|
export declare function resizeHandleClass(headerIndex: number, headerCount: number): import("tailwind-variants").CnReturn;
|
|
23
|
-
export declare function getHeaderSortDirection<T extends RowData>(header: Header<
|
|
17
|
+
export declare function getHeaderSortDirection<T extends RowData>(header: Header<T, unknown>): false | import("@tanstack/table-core").SortDirection;
|
|
24
18
|
export declare function getHeaderSortLabel(sortDirection: false | 'asc' | 'desc'): "Sorted ascending" | "Sorted descending" | "Not sorted";
|
|
25
19
|
export declare function getHeaderAriaSort(sortDirection: false | 'asc' | 'desc'): "none" | "ascending" | "descending";
|
|
26
|
-
export declare function getAllRowsSelectionState<T extends RowData>(table: DataTableInstance<T
|
|
27
|
-
export declare function getRowSelectionState<T extends RowData>(table: DataTableInstance<T>,
|
|
28
|
-
export declare function
|
|
20
|
+
export declare function getAllRowsSelectionState<T extends RowData>(table: DataTableInstance<T>): boolean | 'indeterminate';
|
|
21
|
+
export declare function getRowSelectionState<T extends RowData>(table: DataTableInstance<T>, rowId: string): boolean;
|
|
22
|
+
export declare function getReactiveCells<T extends RowData>(row: Row<T>, columnVisibility: VisibilityState): import("@tanstack/table-core").Cell<T, unknown>[];
|
|
23
|
+
export declare function getSelectedRowCount<T extends RowData>(table: DataTableInstance<T>): number;
|
|
29
24
|
export declare function getBooleanCellValue(value: unknown): boolean | undefined;
|
|
30
|
-
export declare function getPinningStyle(column:
|
|
25
|
+
export declare function getPinningStyle<T extends RowData>(column: Column<T, unknown>, table: DataTableInstance<T>, isHeader?: boolean, isRowSelectionEnabled?: boolean): string | undefined;
|
|
31
26
|
export declare function getUrlCellValue(value: unknown): string | undefined;
|
|
32
27
|
export declare function openUrlCell(value: string): void;
|
|
33
28
|
export declare function getColumnMeta(columnDef: {
|