@spectric/ui 0.0.20 → 0.0.21
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/Banner.d.ts +1 -1
- package/dist/components/dialog/dialog.d.ts +1 -1
- package/dist/components/query_bar/QueryBar.d.ts +1 -1
- package/dist/components/table/cell.d.ts +1 -1
- package/dist/components/table/header.d.ts +2 -1
- package/dist/components/table/table.d.ts +10 -7
- package/dist/custom-elements.json +4 -4
- package/dist/index.es.js +876 -741
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +213 -138
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Banner.ts +46 -31
- package/src/components/dialog/dialog.ts +163 -135
- package/src/components/query_bar/QueryBar.ts +7 -2
- package/src/components/table/__tests__/table.spec.ts +143 -55
- package/src/components/table/cell.ts +185 -146
- package/src/components/table/header.ts +162 -152
- package/src/components/table/table.ts +362 -265
- package/src/components/table/virtualBody.ts +165 -115
|
@@ -1,315 +1,412 @@
|
|
|
1
|
-
import { html, LitElement, PropertyValues,
|
|
1
|
+
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
|
2
2
|
import "../pagination";
|
|
3
|
-
import "./header"
|
|
4
|
-
import "./body"
|
|
5
|
-
import { customElement, property, state
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
import {
|
|
3
|
+
import "./header";
|
|
4
|
+
import "./body";
|
|
5
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
6
|
+
import {
|
|
7
|
+
HTMLElementTagWithEvents,
|
|
8
|
+
ReactElementWithPropsAndEvents,
|
|
9
|
+
} from "../types";
|
|
10
|
+
import "./virtualBody";
|
|
11
|
+
import "./table.css";
|
|
12
|
+
export const TableElementTag = "spectric-table";
|
|
13
|
+
import { spreadProps } from "../../utils/spread";
|
|
14
|
+
import { PaginationChangeProps, PaginationProps } from "../pagination";
|
|
15
|
+
import { FilterEvent } from "./cell";
|
|
16
|
+
import { createSortChain } from "./sorting";
|
|
14
17
|
|
|
15
|
-
export type { TableProps, TableEvents }
|
|
18
|
+
export type { TableProps, TableEvents };
|
|
16
19
|
|
|
17
|
-
export type DomRenderable =
|
|
20
|
+
export type DomRenderable =
|
|
21
|
+
| HTMLElement
|
|
22
|
+
| TemplateResult
|
|
23
|
+
| string
|
|
24
|
+
| number
|
|
25
|
+
| null
|
|
26
|
+
| undefined;
|
|
18
27
|
export enum TableSelectOptions {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
multi = "multi",
|
|
29
|
+
single = "single",
|
|
30
|
+
none = "none",
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
export enum TableSortOption {
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
multi = "multi",
|
|
35
|
+
single = "single",
|
|
27
36
|
}
|
|
28
|
-
export type TableSortOptionTypes = `${TableSortOption}
|
|
37
|
+
export type TableSortOptionTypes = `${TableSortOption}`;
|
|
29
38
|
export enum TableSortDirection {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
ascending = "ascending",
|
|
40
|
+
descending = "descending",
|
|
41
|
+
none = "none",
|
|
33
42
|
}
|
|
34
|
-
export type TableSortDirectionTypes = `${TableSortDirection}
|
|
43
|
+
export type TableSortDirectionTypes = `${TableSortDirection}`;
|
|
35
44
|
export type ColumnSettings<T> = {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
[TABLE_CREATED_SELECTION_COLUMN]?: boolean;
|
|
46
|
+
width?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Enabled/disables resizing by dragging column header Default true
|
|
49
|
+
*/
|
|
50
|
+
allowResize?: boolean;
|
|
51
|
+
whiteSpace?: "nowrap";
|
|
52
|
+
hidden?: boolean;
|
|
53
|
+
sortable?: boolean;
|
|
54
|
+
sortDirection?: TableSortDirectionTypes;
|
|
55
|
+
filterable?: boolean;
|
|
56
|
+
title?: DomRenderable | ((table: SpectricTableElement<T>) => DomRenderable);
|
|
57
|
+
/**
|
|
58
|
+
* Key to used for getting data from an object for a cell
|
|
59
|
+
*/
|
|
60
|
+
key?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Render function to render a table cell for displaying custom html
|
|
63
|
+
*/
|
|
64
|
+
render?: (
|
|
65
|
+
row: T,
|
|
66
|
+
index: number,
|
|
67
|
+
table: SpectricTableElement<T>
|
|
68
|
+
) => DomRenderable;
|
|
69
|
+
/**
|
|
70
|
+
* Custom comparator function for sorting
|
|
71
|
+
*/
|
|
72
|
+
compareFn?: ((a: T, b: T) => number) | undefined;
|
|
73
|
+
};
|
|
74
|
+
export type TableSelectOptionsTypes = `${TableSelectOptions}`;
|
|
62
75
|
export interface TableDataOptions<T> {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
76
|
+
pagination?: PaginationProps;
|
|
77
|
+
columns: ColumnSettings<T>[];
|
|
78
|
+
sortOrder?: string[];
|
|
66
79
|
}
|
|
67
80
|
interface TableProps<T> extends TableDataOptions<T> {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
81
|
+
data: T[];
|
|
82
|
+
select: TableSelectOptionsTypes;
|
|
83
|
+
sort?: TableSortOptionTypes;
|
|
84
|
+
rowHeight?: number;
|
|
72
85
|
}
|
|
73
86
|
|
|
74
87
|
export type DomEvent<T> = Event & {
|
|
75
|
-
|
|
76
|
-
}
|
|
88
|
+
target: T;
|
|
89
|
+
};
|
|
77
90
|
|
|
78
91
|
export const TD_BorderAndPadding = 4;
|
|
79
|
-
const TABLE_CREATED_SELECTION_COLUMN = Symbol(
|
|
92
|
+
const TABLE_CREATED_SELECTION_COLUMN = Symbol(
|
|
93
|
+
"spectric-table-selection-column"
|
|
94
|
+
);
|
|
80
95
|
/**
|
|
81
96
|
* React example
|
|
82
97
|
* <iframe width="100%" height="400px" src="https://stackblitz.com/edit/react-ts-2ue7azag?ctl=1&embed=1&file=App.tsx&hideExplorer=1&hideNavigation=1"/>
|
|
83
98
|
*
|
|
84
99
|
*/
|
|
85
100
|
@customElement(TableElementTag)
|
|
86
|
-
export class SpectricTableElement<T = any>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Needed for virtualization
|
|
102
|
-
*/
|
|
103
|
-
@property({ type: Number, reflect: true })
|
|
104
|
-
rowHeight: number = 25;
|
|
105
|
-
/**
|
|
106
|
-
* Needed for virtualization
|
|
107
|
-
*/
|
|
108
|
-
@property({ type: Number, reflect: true })
|
|
109
|
-
fontSize: number = 16;
|
|
110
|
-
|
|
111
|
-
static getDefaultDataSorterAndPaginatior<T>(data: T[]) {
|
|
112
|
-
return (props: TableDataOptions<T>) => {
|
|
113
|
-
//let sorts = props.columns.filter(column => column.sortable && column.sortDirection && column.sortDirection !== TableSortDirection.none)
|
|
114
|
-
let sorts = (props.sortOrder || []).map(key => props.columns.find(col => col.key === key) as ColumnSettings<T>)
|
|
115
|
-
let rows = [...data] // Need to copy the array to prevent mutating the ordering of the original data
|
|
116
|
-
if (sorts.length) {
|
|
117
|
-
let sortChain = createSortChain(sorts)
|
|
118
|
-
rows.sort((a, b) => {
|
|
119
|
-
for (let sort of sortChain) {
|
|
120
|
-
let result = sort(a, b)
|
|
121
|
-
if (result) {
|
|
122
|
-
return result
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return 0
|
|
126
|
-
})
|
|
127
|
-
}
|
|
101
|
+
export class SpectricTableElement<T = any>
|
|
102
|
+
extends LitElement
|
|
103
|
+
implements TableProps<T>
|
|
104
|
+
{
|
|
105
|
+
@property({ type: Array, attribute: false })
|
|
106
|
+
data: T[] = [];
|
|
107
|
+
@property({ type: Object, attribute: false })
|
|
108
|
+
pagination?: PaginationProps;
|
|
109
|
+
@property({ attribute: false })
|
|
110
|
+
columns: ColumnSettings<T>[] = [];
|
|
111
|
+
@property({ type: String, reflect: true })
|
|
112
|
+
select: TableSelectOptionsTypes = TableSelectOptions.none;
|
|
113
|
+
@property({ type: String, reflect: true })
|
|
114
|
+
sort: TableSortOptionTypes = TableSortOption.single;
|
|
128
115
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
116
|
+
@property({ type: Array, reflect: false })
|
|
117
|
+
sortOrder: string[] = [];
|
|
118
|
+
/**
|
|
119
|
+
* Needed for virtualization
|
|
120
|
+
*/
|
|
121
|
+
@property({ type: Number, reflect: true })
|
|
122
|
+
rowHeight: number = 25;
|
|
123
|
+
/**
|
|
124
|
+
* Needed for virtualization
|
|
125
|
+
*/
|
|
126
|
+
@property({ type: Number, reflect: true })
|
|
127
|
+
fontSize: number = 16;
|
|
128
|
+
static getDefaultDataSorterAndPaginatior<T>(data: T[]) {
|
|
129
|
+
return (props: TableDataOptions<T>) => {
|
|
130
|
+
//let sorts = props.columns.filter(column => column.sortable && column.sortDirection && column.sortDirection !== TableSortDirection.none)
|
|
131
|
+
let sorts = (props.sortOrder || []).map(
|
|
132
|
+
(key) =>
|
|
133
|
+
props.columns.find((col) => col.key === key) as ColumnSettings<T>
|
|
134
|
+
);
|
|
135
|
+
let rows = [...data]; // Need to copy the array to prevent mutating the ordering of the original data
|
|
136
|
+
if (sorts.length) {
|
|
137
|
+
let sortChain = createSortChain(sorts);
|
|
138
|
+
rows.sort((a, b) => {
|
|
139
|
+
for (let sort of sortChain) {
|
|
140
|
+
let result = sort(a, b);
|
|
141
|
+
if (result) {
|
|
142
|
+
return result;
|
|
135
143
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
144
|
+
}
|
|
145
|
+
return 0;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
139
148
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
this.dispatchEvent(new CustomEvent<PaginationChangeProps>("paginationChange", { detail: e.detail }))
|
|
151
|
-
this._emitChange()
|
|
149
|
+
if (!props.pagination) {
|
|
150
|
+
return rows;
|
|
151
|
+
}
|
|
152
|
+
let { page, pageSize } = props.pagination;
|
|
153
|
+
if (!page || !pageSize) {
|
|
154
|
+
return rows;
|
|
155
|
+
}
|
|
156
|
+
return !props.pagination
|
|
157
|
+
? rows
|
|
158
|
+
: rows.slice((page - 1) * pageSize, page * pageSize);
|
|
152
159
|
};
|
|
153
|
-
|
|
154
|
-
let columnSetting = e.detail
|
|
155
|
-
let column = this.columns.find(col => col.key == columnSetting.key)
|
|
156
|
-
if (!column || column.key === undefined) {
|
|
157
|
-
console.warn("Unable to find sort column")
|
|
158
|
-
return
|
|
159
|
-
}
|
|
160
|
-
if (this.sort == TableSortOption.single) {
|
|
161
|
-
//Single column sort so we reset the sort direction for all columns
|
|
162
|
-
this.columns.forEach(col => {
|
|
163
|
-
col.sortDirection = TableSortDirection.none
|
|
164
|
-
})
|
|
165
|
-
this.sortOrder = []
|
|
166
|
-
}
|
|
167
|
-
column.sortDirection = columnSetting.sortDirection;
|
|
168
|
-
if (!column.sortDirection || column.sortDirection === "none") {
|
|
169
|
-
let index = this.sortOrder.findIndex(col => col === column.key)
|
|
170
|
-
if (index !== -1) {
|
|
171
|
-
this.sortOrder.splice(index, 1)
|
|
172
|
-
}
|
|
173
|
-
} else {
|
|
174
|
-
let index = this.sortOrder.findIndex(col => col === column.key)
|
|
175
|
-
if (index === -1) {
|
|
176
|
-
this.sortOrder = [...this.sortOrder, column.key]
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
this.columns = [...this.columns]
|
|
180
|
-
this._emitChange()
|
|
181
|
-
}
|
|
182
|
-
private _handleColumnResize = (e: CustomEvent<ColumnSettings<T>>) => {
|
|
183
|
-
let columnSetting = e.detail
|
|
184
|
-
let index = this.columns.findIndex(col => col.key == columnSetting.key)
|
|
185
|
-
this.columns[index] = { ...this.columns[index] }
|
|
186
|
-
this.columns = [...this.columns]
|
|
187
|
-
this._emitChange()
|
|
188
|
-
}
|
|
160
|
+
}
|
|
189
161
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
162
|
+
private _handlePaginationChange = (e: CustomEvent<PaginationChangeProps>) => {
|
|
163
|
+
if (this.pagination) {
|
|
164
|
+
let pagination = { ...this.pagination, ...e.detail };
|
|
165
|
+
|
|
166
|
+
let { totalItems, page, pageSize } = pagination;
|
|
167
|
+
if (
|
|
168
|
+
totalItems &&
|
|
169
|
+
page &&
|
|
170
|
+
pageSize &&
|
|
171
|
+
(page - 1) * pageSize > totalItems
|
|
172
|
+
) {
|
|
173
|
+
pagination.page = 1;
|
|
174
|
+
}
|
|
175
|
+
this.pagination = pagination;
|
|
193
176
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
177
|
+
this.dispatchEvent(
|
|
178
|
+
new CustomEvent<PaginationChangeProps>("paginationChange", {
|
|
179
|
+
detail: e.detail,
|
|
180
|
+
})
|
|
181
|
+
);
|
|
182
|
+
this._emitChange();
|
|
183
|
+
};
|
|
184
|
+
private _handleSortChange = (e: CustomEvent<ColumnSettings<T>>) => {
|
|
185
|
+
let columnSetting = e.detail;
|
|
186
|
+
let column = this.columns.find((col) => col.key == columnSetting.key);
|
|
187
|
+
if (!column || column.key === undefined) {
|
|
188
|
+
console.warn("Unable to find sort column");
|
|
189
|
+
return;
|
|
199
190
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
191
|
+
if (this.sort == TableSortOption.single) {
|
|
192
|
+
//Single column sort so we reset the sort direction for all columns
|
|
193
|
+
this.columns.forEach((col) => {
|
|
194
|
+
col.sortDirection = TableSortDirection.none;
|
|
195
|
+
});
|
|
196
|
+
this.sortOrder = [];
|
|
204
197
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
198
|
+
column.sortDirection = columnSetting.sortDirection;
|
|
199
|
+
if (!column.sortDirection || column.sortDirection === "none") {
|
|
200
|
+
let index = this.sortOrder.findIndex((col) => col === column.key);
|
|
201
|
+
if (index !== -1) {
|
|
202
|
+
this.sortOrder.splice(index, 1);
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
let index = this.sortOrder.findIndex((col) => col === column.key);
|
|
206
|
+
if (index === -1) {
|
|
207
|
+
this.sortOrder = [...this.sortOrder, column.key];
|
|
208
|
+
}
|
|
208
209
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
210
|
+
this.columns = [...this.columns];
|
|
211
|
+
this._emitChange();
|
|
212
|
+
};
|
|
213
|
+
private _handleColumnResize = (e: CustomEvent<ColumnSettings<T>>) => {
|
|
214
|
+
let columnSetting = e.detail;
|
|
215
|
+
let index = this.columns.findIndex((col) => col.key == columnSetting.key);
|
|
216
|
+
this.columns[index] = { ...this.columns[index] };
|
|
217
|
+
this.columns = [...this.columns];
|
|
218
|
+
this._emitChange();
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
private _emitChange = () => {
|
|
222
|
+
let { pagination, columns, sortOrder } = this;
|
|
223
|
+
this.dispatchEvent(
|
|
224
|
+
new CustomEvent<TableDataOptions<T>>("change", {
|
|
225
|
+
detail: { pagination, columns, sortOrder },
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
};
|
|
229
|
+
//@ts-ignore
|
|
230
|
+
private __DO_NOT_USE_filter = () => {
|
|
231
|
+
//This is only here to auto document events that bubble up from lower components
|
|
232
|
+
this.dispatchEvent(new CustomEvent<FilterEvent<T>>("filter"));
|
|
233
|
+
this.dispatchEvent(new CustomEvent<ColumnSettings<T>>("sortChange"));
|
|
234
|
+
};
|
|
235
|
+
@state()
|
|
236
|
+
private selected: T[] = [];
|
|
237
|
+
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
240
|
+
forceRefreshofSelectionColumn() {
|
|
241
|
+
// Because lit reuses dom elements for speed/effeciency it wont update unless the props are a different object.
|
|
242
|
+
// So we set the selection colum to a "new object" to force the rerender
|
|
243
|
+
let index = this.columns.findIndex(
|
|
244
|
+
(col) => col[TABLE_CREATED_SELECTION_COLUMN]
|
|
245
|
+
);
|
|
246
|
+
if (index !== -1) {
|
|
247
|
+
this.columns[index] = { ...this.selectColumnConfig };
|
|
212
248
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
249
|
+
}
|
|
250
|
+
setSelected(selected: T[]) {
|
|
251
|
+
this.selected = selected;
|
|
252
|
+
this.forceRefreshofSelectionColumn();
|
|
253
|
+
}
|
|
254
|
+
deselectAll() {
|
|
255
|
+
this.selected = [];
|
|
256
|
+
this.forceRefreshofSelectionColumn();
|
|
257
|
+
this.dispatchEvent(new CustomEvent("selected", { detail: this.selected }));
|
|
258
|
+
}
|
|
259
|
+
selectAll() {
|
|
260
|
+
this.selected = [...this.data];
|
|
261
|
+
this.forceRefreshofSelectionColumn();
|
|
262
|
+
this.dispatchEvent(new CustomEvent("selected", { detail: this.selected }));
|
|
263
|
+
}
|
|
264
|
+
_handleSelectAllChange = (e: DomEvent<HTMLInputElement>) => {
|
|
265
|
+
e.stopPropagation();
|
|
266
|
+
if (e.target.checked) {
|
|
267
|
+
this.selectAll();
|
|
268
|
+
} else {
|
|
269
|
+
this.deselectAll();
|
|
220
270
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
if (changedProperties.has("select")) {
|
|
259
|
-
if (this.select === "single" && this.selected.length > 1) {
|
|
260
|
-
this.selected = [this.selected[0]]
|
|
261
|
-
this.dispatchEvent(new CustomEvent("selected", { detail: [...this.selected] }))
|
|
271
|
+
};
|
|
272
|
+
private selectColumnConfig: ColumnSettings<T> = {
|
|
273
|
+
[TABLE_CREATED_SELECTION_COLUMN]: true,
|
|
274
|
+
width: 39,
|
|
275
|
+
title: (table) => {
|
|
276
|
+
return table.select === "multi"
|
|
277
|
+
? html`<spectric-input
|
|
278
|
+
variant="checkbox"
|
|
279
|
+
@change=${table._handleSelectAllChange}
|
|
280
|
+
.helperText=${"Select All"}
|
|
281
|
+
></spectric-input>`
|
|
282
|
+
: null;
|
|
283
|
+
},
|
|
284
|
+
render: (row: T, _index, table) => {
|
|
285
|
+
let checked = table.selected.includes(row);
|
|
286
|
+
let template = html`<spectric-input
|
|
287
|
+
variant="checkbox"
|
|
288
|
+
class="table-checkbox-${table.select}"
|
|
289
|
+
.helperText=${""}
|
|
290
|
+
${spreadProps({ checked })}
|
|
291
|
+
@change=${(e: DomEvent<HTMLInputElement>) => {
|
|
292
|
+
e.stopPropagation();
|
|
293
|
+
let index = table.selected.findIndex((value) => value === row);
|
|
294
|
+
if (e.target.checked && index !== -1) {
|
|
295
|
+
return;
|
|
296
|
+
} else if (!e.target.checked && index === -1) {
|
|
297
|
+
return;
|
|
298
|
+
} else if (!e.target.checked && index !== -1) {
|
|
299
|
+
table.selected.splice(index, 1);
|
|
300
|
+
}
|
|
301
|
+
if (e.target.checked) {
|
|
302
|
+
if (table.select === "single") {
|
|
303
|
+
table.selected = [];
|
|
304
|
+
table.forceRefreshofSelectionColumn();
|
|
262
305
|
}
|
|
306
|
+
table.selected.push(row);
|
|
307
|
+
}
|
|
308
|
+
table.dispatchEvent(
|
|
309
|
+
new CustomEvent("selected", { detail: [...table.selected] })
|
|
310
|
+
);
|
|
311
|
+
}}
|
|
312
|
+
></spectric-input>`;
|
|
313
|
+
return template;
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
protected update(changedProperties: PropertyValues): void {
|
|
317
|
+
if (changedProperties.has("columns")) {
|
|
318
|
+
if (this.select !== TableSelectOptions.none) {
|
|
319
|
+
if (!this.columns.find((col) => col[TABLE_CREATED_SELECTION_COLUMN])) {
|
|
320
|
+
this.columns.unshift(this.selectColumnConfig);
|
|
263
321
|
}
|
|
264
|
-
|
|
322
|
+
}
|
|
265
323
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
324
|
+
if (changedProperties.has("select")) {
|
|
325
|
+
if (this.select === "single" && this.selected.length > 1) {
|
|
326
|
+
this.selected = [this.selected[0]];
|
|
327
|
+
this.dispatchEvent(
|
|
328
|
+
new CustomEvent("selected", { detail: [...this.selected] })
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
super.update(changedProperties);
|
|
333
|
+
}
|
|
334
|
+
protected render(): unknown {
|
|
335
|
+
let columns = this.columns.filter((column) => !column.hidden);
|
|
336
|
+
let rowHeight = this.rowHeight - TD_BorderAndPadding;
|
|
337
|
+
if (rowHeight < this.fontSize + TD_BorderAndPadding) {
|
|
338
|
+
rowHeight = this.fontSize + TD_BorderAndPadding;
|
|
281
339
|
}
|
|
340
|
+
return html`
|
|
341
|
+
<div
|
|
342
|
+
class="table-wrapper"
|
|
343
|
+
style="--rowHeight:${rowHeight}px;--fontSize:${this
|
|
344
|
+
.fontSize}px;--lineClamp:${Math.floor(rowHeight / this.fontSize)}"
|
|
345
|
+
>
|
|
346
|
+
<div role="table">
|
|
347
|
+
<spectric-table-header
|
|
348
|
+
.columns=${columns}
|
|
349
|
+
.table=${this}
|
|
350
|
+
@sortChange=${this._handleSortChange}
|
|
351
|
+
@columnResize=${this._handleColumnResize}
|
|
352
|
+
></spectric-table-header>
|
|
353
|
+
<spectric-table-virtual-body
|
|
354
|
+
.columns=${columns}
|
|
355
|
+
.data=${this.data}
|
|
356
|
+
.table=${this}
|
|
357
|
+
.rowHeight=${rowHeight}
|
|
358
|
+
></spectric-table-virtual-body>
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
${this.pagination
|
|
362
|
+
? html`<spectric-pagination
|
|
363
|
+
${spreadProps(this.pagination)}
|
|
364
|
+
@change=${this._handlePaginationChange}
|
|
365
|
+
></spectric-pagination>`
|
|
366
|
+
: null}
|
|
367
|
+
`;
|
|
368
|
+
}
|
|
282
369
|
}
|
|
283
370
|
|
|
284
371
|
interface TableEvents {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
372
|
+
change: (event: CustomEvent<TableDataOptions<any>>) => void;
|
|
373
|
+
paginationChange: (event: CustomEvent<PaginationChangeProps>) => void;
|
|
374
|
+
filter: (event: CustomEvent<FilterEvent<any>>) => void;
|
|
375
|
+
sortChange: (event: CustomEvent<ColumnSettings<any>>) => void;
|
|
376
|
+
selected: (event: CustomEvent<any[]>) => void;
|
|
290
377
|
}
|
|
291
378
|
|
|
292
379
|
declare global {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
380
|
+
interface HTMLElementTagNameMap {
|
|
381
|
+
[TableElementTag]: HTMLElementTagWithEvents<
|
|
382
|
+
SpectricTableElement<any>,
|
|
383
|
+
TableEvents
|
|
384
|
+
>;
|
|
385
|
+
}
|
|
386
|
+
namespace JSX {
|
|
387
|
+
interface IntrinsicElements {
|
|
388
|
+
/**
|
|
389
|
+
* @see {@link TableElement}
|
|
390
|
+
*/
|
|
391
|
+
[TableElementTag]: ReactElementWithPropsAndEvents<
|
|
392
|
+
SpectricTableElement<any>,
|
|
393
|
+
TableProps<any>,
|
|
394
|
+
TableEvents
|
|
395
|
+
>;
|
|
296
396
|
}
|
|
397
|
+
}
|
|
398
|
+
namespace React {
|
|
297
399
|
namespace JSX {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* @see {@link TableElement}
|
|
310
|
-
*/
|
|
311
|
-
[TableElementTag]: ReactElementWithPropsAndEvents<SpectricTableElement<any>, TableProps<any>, TableEvents>
|
|
312
|
-
}
|
|
313
|
-
}
|
|
400
|
+
interface IntrinsicElements {
|
|
401
|
+
/**
|
|
402
|
+
* @see {@link TableElement}
|
|
403
|
+
*/
|
|
404
|
+
[TableElementTag]: ReactElementWithPropsAndEvents<
|
|
405
|
+
SpectricTableElement<any>,
|
|
406
|
+
TableProps<any>,
|
|
407
|
+
TableEvents
|
|
408
|
+
>;
|
|
409
|
+
}
|
|
314
410
|
}
|
|
411
|
+
}
|
|
315
412
|
}
|