@sondor-technology/sondor-components 1.0.1-develop.12 → 1.0.1-develop.14
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/alert/alert.constants.d.ts +3 -0
- package/dist/components/alert/alert.constants.d.ts.map +1 -0
- package/dist/components/alert/alert.constants.js +2 -0
- package/dist/components/alert/alert.constants.js.map +1 -0
- package/dist/components/alert/alert.d.ts +4 -3
- package/dist/components/alert/alert.d.ts.map +1 -1
- package/dist/components/alert/alert.js +21 -11
- package/dist/components/alert/alert.js.map +1 -0
- package/dist/components/badge/badge.constants.d.ts +3 -0
- package/dist/components/badge/badge.constants.d.ts.map +1 -0
- package/dist/components/badge/badge.constants.js +2 -0
- package/dist/components/badge/badge.constants.js.map +1 -0
- package/dist/components/badge/badge.d.ts +1 -1
- package/dist/components/badge/badge.d.ts.map +1 -1
- package/dist/components/badge/badge.js +3 -2
- package/dist/components/badge/badge.js.map +1 -0
- package/dist/components/breadcrumb/breadcrumb.d.ts.map +1 -1
- package/dist/components/breadcrumb/breadcrumb.js +2 -1
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/components/button/button.constants.d.ts +7 -0
- package/dist/components/button/button.constants.d.ts.map +1 -0
- package/dist/components/button/button.constants.js +4 -0
- package/dist/components/button/button.constants.js.map +1 -0
- package/dist/components/button/button.d.ts +8 -4
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/button.js +181 -137
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/button-group/button-group.d.ts +1 -0
- package/dist/components/button-group/button-group.d.ts.map +1 -1
- package/dist/components/button-group/button-group.js +17 -21
- package/dist/components/button-group/button-group.js.map +1 -0
- package/dist/components/checkbox/checkbox.constants.d.ts +3 -0
- package/dist/components/checkbox/checkbox.constants.d.ts.map +1 -0
- package/dist/components/checkbox/checkbox.constants.js +2 -0
- package/dist/components/checkbox/checkbox.constants.js.map +1 -0
- package/dist/components/checkbox/checkbox.d.ts +5 -1
- package/dist/components/checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox/checkbox.js +21 -5
- package/dist/components/checkbox/checkbox.js.map +1 -0
- package/dist/components/code-block/code-block.d.ts +7 -7
- package/dist/components/code-block/code-block.d.ts.map +1 -1
- package/dist/components/code-block/code-block.js +130 -66
- package/dist/components/code-block/code-block.js.map +1 -0
- package/dist/components/content-card/content-card.d.ts.map +1 -1
- package/dist/components/content-card/content-card.js +10 -15
- package/dist/components/content-card/content-card.js.map +1 -0
- package/dist/components/divider/divider.constants.d.ts +5 -0
- package/dist/components/divider/divider.constants.d.ts.map +1 -0
- package/dist/components/divider/divider.constants.js +3 -0
- package/dist/components/divider/divider.constants.js.map +1 -0
- package/dist/components/divider/divider.d.ts +4 -2
- package/dist/components/divider/divider.d.ts.map +1 -1
- package/dist/components/divider/divider.js +18 -9
- package/dist/components/divider/divider.js.map +1 -0
- package/dist/components/drawer/drawer.d.ts +7 -4
- package/dist/components/drawer/drawer.d.ts.map +1 -1
- package/dist/components/drawer/drawer.js +73 -30
- package/dist/components/drawer/drawer.js.map +1 -0
- package/dist/components/field/field.d.ts +2 -2
- package/dist/components/field/field.d.ts.map +1 -1
- package/dist/components/field/field.js +8 -9
- package/dist/components/field/field.js.map +1 -0
- package/dist/components/footer/footer.d.ts +8 -1
- package/dist/components/footer/footer.d.ts.map +1 -1
- package/dist/components/footer/footer.js +42 -12
- package/dist/components/footer/footer.js.map +1 -0
- package/dist/components/form/form-step.js +1 -0
- package/dist/components/form/form-step.js.map +1 -0
- package/dist/components/form/form.d.ts +3 -0
- package/dist/components/form/form.d.ts.map +1 -1
- package/dist/components/form/form.js +109 -69
- package/dist/components/form/form.js.map +1 -0
- package/dist/components/grid/grid-row.d.ts +3 -3
- package/dist/components/grid/grid-row.d.ts.map +1 -1
- package/dist/components/grid/grid-row.js +36 -22
- package/dist/components/grid/grid-row.js.map +1 -0
- package/dist/components/grid/grid.d.ts +2 -2
- package/dist/components/grid/grid.d.ts.map +1 -1
- package/dist/components/grid/grid.js +5 -2
- package/dist/components/grid/grid.js.map +1 -0
- package/dist/components/icon/icon-paths.d.ts +161 -86
- package/dist/components/icon/icon-paths.d.ts.map +1 -1
- package/dist/components/icon/icon-paths.js +176 -106
- package/dist/components/icon/icon-paths.js.map +1 -0
- package/dist/components/icon/icon.d.ts +1 -1
- package/dist/components/icon/icon.d.ts.map +1 -1
- package/dist/components/icon/icon.js +6 -5
- package/dist/components/icon/icon.js.map +1 -0
- package/dist/components/input/input.d.ts +9 -0
- package/dist/components/input/input.d.ts.map +1 -1
- package/dist/components/input/input.js +30 -37
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/link/link.d.ts +6 -6
- package/dist/components/link/link.d.ts.map +1 -1
- package/dist/components/link/link.js +42 -19
- package/dist/components/link/link.js.map +1 -0
- package/dist/components/metadata/metadata.d.ts +3 -3
- package/dist/components/metadata/metadata.d.ts.map +1 -1
- package/dist/components/metadata/metadata.js +23 -20
- package/dist/components/metadata/metadata.js.map +1 -0
- package/dist/components/modal/modal.d.ts +4 -16
- package/dist/components/modal/modal.d.ts.map +1 -1
- package/dist/components/modal/modal.js +99 -62
- package/dist/components/modal/modal.js.map +1 -0
- package/dist/components/page-layout/page-layout.d.ts +4 -3
- package/dist/components/page-layout/page-layout.d.ts.map +1 -1
- package/dist/components/page-layout/page-layout.js +95 -68
- package/dist/components/page-layout/page-layout.js.map +1 -0
- package/dist/components/radio/radio.d.ts +8 -0
- package/dist/components/radio/radio.d.ts.map +1 -1
- package/dist/components/radio/radio.js +8 -12
- package/dist/components/radio/radio.js.map +1 -0
- package/dist/components/radio-group/radio-group.d.ts +6 -1
- package/dist/components/radio-group/radio-group.d.ts.map +1 -1
- package/dist/components/radio-group/radio-group.js +44 -18
- package/dist/components/radio-group/radio-group.js.map +1 -0
- package/dist/components/router/router.d.ts +5 -7
- package/dist/components/router/router.d.ts.map +1 -1
- package/dist/components/router/router.js +54 -38
- package/dist/components/router/router.js.map +1 -0
- package/dist/components/select/select.d.ts +6 -3
- package/dist/components/select/select.d.ts.map +1 -1
- package/dist/components/select/select.js +14 -5
- package/dist/components/select/select.js.map +1 -0
- package/dist/components/skeleton/skeleton.d.ts +3 -2
- package/dist/components/skeleton/skeleton.d.ts.map +1 -1
- package/dist/components/skeleton/skeleton.js +10 -13
- package/dist/components/skeleton/skeleton.js.map +1 -0
- package/dist/components/switch/switch.d.ts +12 -0
- package/dist/components/switch/switch.d.ts.map +1 -1
- package/dist/components/switch/switch.js +28 -22
- package/dist/components/switch/switch.js.map +1 -0
- package/dist/components/table/data-table.d.ts +3 -25
- package/dist/components/table/data-table.d.ts.map +1 -1
- package/dist/components/table/data-table.js +211 -146
- package/dist/components/table/data-table.js.map +1 -0
- package/dist/components/table/table.d.ts +3 -3
- package/dist/components/table/table.d.ts.map +1 -1
- package/dist/components/table/table.js +39 -20
- package/dist/components/table/table.js.map +1 -0
- package/dist/components/tabs/tab-panel.d.ts +3 -1
- package/dist/components/tabs/tab-panel.d.ts.map +1 -1
- package/dist/components/tabs/tab-panel.js +21 -11
- package/dist/components/tabs/tab-panel.js.map +1 -0
- package/dist/components/tabs/tab.d.ts +5 -1
- package/dist/components/tabs/tab.d.ts.map +1 -1
- package/dist/components/tabs/tab.js +46 -28
- package/dist/components/tabs/tab.js.map +1 -0
- package/dist/components/tabs/tabs.d.ts +4 -0
- package/dist/components/tabs/tabs.d.ts.map +1 -1
- package/dist/components/tabs/tabs.js +76 -13
- package/dist/components/tabs/tabs.js.map +1 -0
- package/dist/components/textarea/textarea.d.ts +13 -0
- package/dist/components/textarea/textarea.d.ts.map +1 -1
- package/dist/components/textarea/textarea.js +59 -13
- package/dist/components/textarea/textarea.js.map +1 -0
- package/dist/components/theme-toggle/theme-toggle.constants.d.ts +3 -0
- package/dist/components/theme-toggle/theme-toggle.constants.d.ts.map +1 -0
- package/dist/components/theme-toggle/theme-toggle.constants.js +2 -0
- package/dist/components/theme-toggle/theme-toggle.constants.js.map +1 -0
- package/dist/components/theme-toggle/theme-toggle.d.ts +3 -2
- package/dist/components/theme-toggle/theme-toggle.d.ts.map +1 -1
- package/dist/components/theme-toggle/theme-toggle.js +46 -19
- package/dist/components/theme-toggle/theme-toggle.js.map +1 -0
- package/dist/components/vertical-nav/vertical-nav-group.d.ts +5 -2
- package/dist/components/vertical-nav/vertical-nav-group.d.ts.map +1 -1
- package/dist/components/vertical-nav/vertical-nav-group.js +50 -14
- package/dist/components/vertical-nav/vertical-nav-group.js.map +1 -0
- package/dist/components/vertical-nav/vertical-nav-item.d.ts +3 -2
- package/dist/components/vertical-nav/vertical-nav-item.d.ts.map +1 -1
- package/dist/components/vertical-nav/vertical-nav-item.js +30 -8
- package/dist/components/vertical-nav/vertical-nav-item.js.map +1 -0
- package/dist/styles/index.css +48 -17
- package/dist/styles/reset.js +1 -0
- package/dist/styles/reset.js.map +1 -0
- package/package.json +2 -1
- package/src/components/alert/alert.constants.ts +2 -0
- package/src/components/alert/alert.ts +24 -15
- package/src/components/badge/badge.constants.ts +2 -0
- package/src/components/badge/badge.ts +3 -4
- package/src/components/breadcrumb/breadcrumb.ts +2 -2
- package/src/components/button/button.constants.ts +8 -0
- package/src/components/button/button.ts +184 -144
- package/src/components/button-group/button-group.ts +18 -22
- package/src/components/checkbox/checkbox.constants.ts +2 -0
- package/src/components/checkbox/checkbox.ts +33 -18
- package/src/components/code-block/code-block.ts +151 -84
- package/src/components/content-card/content-card.ts +10 -16
- package/src/components/divider/divider.constants.ts +5 -0
- package/src/components/divider/divider.ts +22 -11
- package/src/components/drawer/drawer.ts +79 -34
- package/src/components/field/field.ts +9 -11
- package/src/components/footer/footer.ts +43 -12
- package/src/components/form/form.ts +121 -84
- package/src/components/grid/grid-row.ts +45 -32
- package/src/components/grid/grid.ts +7 -4
- package/src/components/icon/icon-paths.ts +175 -106
- package/src/components/icon/icon.ts +6 -6
- package/src/components/input/input.ts +32 -42
- package/src/components/link/link.ts +45 -21
- package/src/components/metadata/metadata.ts +26 -24
- package/src/components/modal/modal.ts +108 -74
- package/src/components/page-layout/page-layout.ts +97 -72
- package/src/components/radio/radio.ts +8 -13
- package/src/components/radio-group/radio-group.ts +45 -21
- package/src/components/router/router.ts +73 -50
- package/src/components/select/select.ts +23 -18
- package/src/components/skeleton/skeleton.ts +14 -14
- package/src/components/switch/switch.ts +31 -25
- package/src/components/table/data-table.ts +248 -177
- package/src/components/table/table.ts +52 -29
- package/src/components/tabs/tab-panel.ts +25 -13
- package/src/components/tabs/tab.ts +58 -33
- package/src/components/tabs/tabs.ts +77 -15
- package/src/components/textarea/textarea.ts +63 -15
- package/src/components/theme-toggle/theme-toggle.constants.ts +2 -0
- package/src/components/theme-toggle/theme-toggle.ts +47 -22
- package/src/components/vertical-nav/vertical-nav-group.ts +57 -18
- package/src/components/vertical-nav/vertical-nav-item.ts +35 -12
- package/src/styles/globals.css +27 -4
- package/src/styles/theme.css +38 -32
- package/tsconfig.json +2 -1
- package/dist/components/card/card.d.ts +0 -11
- package/dist/components/card/card.d.ts.map +0 -1
- package/dist/components/card/card.js +0 -54
- package/src/components/card/card.ts +0 -53
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import {LitElement, html, css, PropertyValues} from "lit";
|
|
2
|
+
import {customElement, property, state} from "lit/decorators.js";
|
|
3
|
+
import {classMap} from "lit/directives/class-map.js";
|
|
4
|
+
import {resetStyles} from "../../styles/reset.js";
|
|
5
|
+
import {ifDefined} from "lit/directives/if-defined.js";
|
|
5
6
|
|
|
6
7
|
export interface DataTableColumn {
|
|
7
8
|
header: string;
|
|
@@ -12,52 +13,24 @@ export interface DataTableColumn {
|
|
|
12
13
|
|
|
13
14
|
export interface SortConfig {
|
|
14
15
|
key: string;
|
|
15
|
-
direction:
|
|
16
|
+
direction: "asc" | "desc";
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
@customElement(
|
|
19
|
+
@customElement("st-data-table")
|
|
19
20
|
export class StDataTable extends LitElement {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@property({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@property({ type: Array }) data: Record<string, any>[] = [];
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Total number of rows available on the server (used for pagination).
|
|
32
|
-
*/
|
|
33
|
-
@property({ type: Number, attribute: 'total-rows' }) totalRows = 0;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Current page number (1-indexed).
|
|
37
|
-
*/
|
|
38
|
-
@property({ type: Number }) page = 1;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Number of rows per page.
|
|
42
|
-
*/
|
|
43
|
-
@property({ type: Number, attribute: 'page-size' }) pageSize = 10;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Enables holding 'Shift' to sort by multiple columns sequentially.
|
|
47
|
-
*/
|
|
48
|
-
@property({ type: Boolean, attribute: 'multi-sort' }) multiSort = false;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Displays loading skeleton rows and locks controls.
|
|
52
|
-
*/
|
|
53
|
-
@property({ type: Boolean, reflect: true }) loading = false;
|
|
54
|
-
|
|
55
|
-
// --- Internal State ---
|
|
21
|
+
@property({type: Array}) columns: DataTableColumn[] = [];
|
|
22
|
+
@property({type: Array}) data: Record<string, any>[] = [];
|
|
23
|
+
@property({type: Number, attribute: "total-rows"}) totalRows = 0;
|
|
24
|
+
@property({type: Number}) page = 1;
|
|
25
|
+
@property({type: Number, attribute: "page-size"}) pageSize = 10;
|
|
26
|
+
@property({type: Boolean, attribute: "multi-sort"}) multiSort = false;
|
|
27
|
+
@property({type: Boolean, reflect: true}) loading = false;
|
|
28
|
+
|
|
56
29
|
@state() private internalColumns: DataTableColumn[] = [];
|
|
57
30
|
@state() private sortState: SortConfig[] = [];
|
|
58
|
-
@state() private searchQuery =
|
|
31
|
+
@state() private searchQuery = "";
|
|
59
32
|
@state() private showColumnMenu = false;
|
|
60
|
-
|
|
33
|
+
|
|
61
34
|
private searchTimeout?: number;
|
|
62
35
|
private draggedColumnKey: string | null = null;
|
|
63
36
|
|
|
@@ -251,59 +224,60 @@ export class StDataTable extends LitElement {
|
|
|
251
224
|
.drag-handle:hover {
|
|
252
225
|
opacity: 0.7;
|
|
253
226
|
}
|
|
254
|
-
|
|
227
|
+
`,
|
|
255
228
|
];
|
|
256
229
|
|
|
257
|
-
willUpdate(changedProperties: PropertyValues) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
firstUpdated() {
|
|
266
|
-
if (this.internalColumns.length === 0 && this.columns.length > 0) {
|
|
267
|
-
this.internalColumns = [...this.columns];
|
|
230
|
+
override willUpdate(changedProperties: PropertyValues) {
|
|
231
|
+
// 🚀 FIX: Properly sync dynamically updated columns while preserving user visibility states
|
|
232
|
+
if (changedProperties.has("columns") && this.columns) {
|
|
233
|
+
this.internalColumns = this.columns.map((newCol) => {
|
|
234
|
+
const existing = this.internalColumns.find((ic) => ic.key === newCol.key);
|
|
235
|
+
return {...newCol, hidden: existing ? existing.hidden : newCol.hidden};
|
|
236
|
+
});
|
|
268
237
|
}
|
|
269
|
-
this.emitChange();
|
|
270
238
|
}
|
|
271
239
|
|
|
272
240
|
connectedCallback() {
|
|
273
241
|
super.connectedCallback();
|
|
274
|
-
document.addEventListener(
|
|
242
|
+
document.addEventListener("click", this.handleOutsideClick);
|
|
275
243
|
}
|
|
276
244
|
|
|
277
245
|
disconnectedCallback() {
|
|
278
|
-
document.removeEventListener(
|
|
246
|
+
document.removeEventListener("click", this.handleOutsideClick);
|
|
279
247
|
super.disconnectedCallback();
|
|
280
248
|
}
|
|
281
249
|
|
|
282
|
-
private handleOutsideClick = (e:
|
|
283
|
-
const
|
|
284
|
-
|
|
250
|
+
private handleOutsideClick = (e: Event) => {
|
|
251
|
+
const path = e.composedPath();
|
|
252
|
+
const toggleWrapper = this.shadowRoot?.querySelector(".columns-toggle-wrapper");
|
|
253
|
+
|
|
254
|
+
// 🚀 THE FIX: Use composedPath() to pierce the Shadow DOM and check if
|
|
255
|
+
// the click originated from inside the wrapper element.
|
|
256
|
+
if (toggleWrapper && !path.includes(toggleWrapper)) {
|
|
285
257
|
this.showColumnMenu = false;
|
|
286
258
|
}
|
|
287
259
|
};
|
|
288
260
|
|
|
289
261
|
private emitChange() {
|
|
290
|
-
this.dispatchEvent(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
262
|
+
this.dispatchEvent(
|
|
263
|
+
new CustomEvent("st-data-change", {
|
|
264
|
+
detail: {
|
|
265
|
+
page: this.page,
|
|
266
|
+
pageSize: this.pageSize,
|
|
267
|
+
search: this.searchQuery,
|
|
268
|
+
sort: this.sortState,
|
|
269
|
+
},
|
|
270
|
+
bubbles: true,
|
|
271
|
+
composed: true,
|
|
272
|
+
}),
|
|
273
|
+
);
|
|
300
274
|
}
|
|
301
275
|
|
|
302
276
|
private handleSearchInput(e: Event) {
|
|
303
277
|
if (this.loading) return;
|
|
304
278
|
const val = (e.target as HTMLInputElement).value;
|
|
305
279
|
window.clearTimeout(this.searchTimeout);
|
|
306
|
-
|
|
280
|
+
|
|
307
281
|
this.searchTimeout = window.setTimeout(() => {
|
|
308
282
|
this.searchQuery = val;
|
|
309
283
|
this.page = 1;
|
|
@@ -314,11 +288,11 @@ export class StDataTable extends LitElement {
|
|
|
314
288
|
private handleSort(key: string, e: MouseEvent) {
|
|
315
289
|
if (this.loading) return;
|
|
316
290
|
const isShift = e.shiftKey && this.multiSort;
|
|
317
|
-
const existingIndex = this.sortState.findIndex(s => s.key === key);
|
|
318
|
-
let newDirection:
|
|
291
|
+
const existingIndex = this.sortState.findIndex((s) => s.key === key);
|
|
292
|
+
let newDirection: "asc" | "desc" | null = "asc";
|
|
319
293
|
|
|
320
294
|
if (existingIndex !== -1) {
|
|
321
|
-
newDirection = this.sortState[existingIndex].direction ===
|
|
295
|
+
newDirection = this.sortState[existingIndex].direction === "asc" ? "desc" : null;
|
|
322
296
|
}
|
|
323
297
|
|
|
324
298
|
let newSortState = [...this.sortState];
|
|
@@ -328,14 +302,14 @@ export class StDataTable extends LitElement {
|
|
|
328
302
|
if (existingIndex !== -1) {
|
|
329
303
|
newSortState[existingIndex].direction = newDirection;
|
|
330
304
|
} else {
|
|
331
|
-
newSortState.push({
|
|
305
|
+
newSortState.push({key, direction: newDirection});
|
|
332
306
|
}
|
|
333
307
|
} else {
|
|
334
308
|
newSortState.splice(existingIndex, 1);
|
|
335
309
|
}
|
|
336
310
|
} else {
|
|
337
311
|
if (newDirection) {
|
|
338
|
-
newSortState = [{
|
|
312
|
+
newSortState = [{key, direction: newDirection}];
|
|
339
313
|
} else {
|
|
340
314
|
newSortState = [];
|
|
341
315
|
}
|
|
@@ -365,41 +339,41 @@ export class StDataTable extends LitElement {
|
|
|
365
339
|
}
|
|
366
340
|
|
|
367
341
|
private toggleColumnVisibility(key: string) {
|
|
368
|
-
this.internalColumns = this.internalColumns.map(col =>
|
|
369
|
-
col.key === key ? {
|
|
342
|
+
this.internalColumns = this.internalColumns.map((col) =>
|
|
343
|
+
col.key === key ? {...col, hidden: !col.hidden} : col,
|
|
370
344
|
);
|
|
371
345
|
}
|
|
372
346
|
|
|
373
347
|
private handleDragStart(e: DragEvent, key: string) {
|
|
374
348
|
this.draggedColumnKey = key;
|
|
375
349
|
if (e.dataTransfer) {
|
|
376
|
-
e.dataTransfer.effectAllowed =
|
|
377
|
-
e.dataTransfer.setData(
|
|
350
|
+
e.dataTransfer.effectAllowed = "move";
|
|
351
|
+
e.dataTransfer.setData("text/plain", key);
|
|
378
352
|
}
|
|
379
353
|
}
|
|
380
354
|
|
|
381
355
|
private handleDragOver(e: DragEvent) {
|
|
382
356
|
e.preventDefault();
|
|
383
|
-
if (e.dataTransfer) e.dataTransfer.dropEffect =
|
|
384
|
-
const target = (e.target as HTMLElement).closest(
|
|
385
|
-
if (target) target.classList.add(
|
|
357
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
358
|
+
const target = (e.target as HTMLElement).closest("th");
|
|
359
|
+
if (target) target.classList.add("drag-over");
|
|
386
360
|
}
|
|
387
361
|
|
|
388
362
|
private handleDragLeave(e: DragEvent) {
|
|
389
|
-
const target = (e.target as HTMLElement).closest(
|
|
390
|
-
if (target) target.classList.remove(
|
|
363
|
+
const target = (e.target as HTMLElement).closest("th");
|
|
364
|
+
if (target) target.classList.remove("drag-over");
|
|
391
365
|
}
|
|
392
366
|
|
|
393
367
|
private handleDrop(e: DragEvent, targetKey: string) {
|
|
394
368
|
e.preventDefault();
|
|
395
|
-
const targetEl = (e.target as HTMLElement).closest(
|
|
396
|
-
if (targetEl) targetEl.classList.remove(
|
|
369
|
+
const targetEl = (e.target as HTMLElement).closest("th");
|
|
370
|
+
if (targetEl) targetEl.classList.remove("drag-over");
|
|
397
371
|
|
|
398
372
|
if (!this.draggedColumnKey || this.draggedColumnKey === targetKey) return;
|
|
399
373
|
|
|
400
374
|
const newCols = [...this.internalColumns];
|
|
401
|
-
const fromIndex = newCols.findIndex(c => c.key === this.draggedColumnKey);
|
|
402
|
-
const toIndex = newCols.findIndex(c => c.key === targetKey);
|
|
375
|
+
const fromIndex = newCols.findIndex((c) => c.key === this.draggedColumnKey);
|
|
376
|
+
const toIndex = newCols.findIndex((c) => c.key === targetKey);
|
|
403
377
|
|
|
404
378
|
const [movedCol] = newCols.splice(fromIndex, 1);
|
|
405
379
|
newCols.splice(toIndex, 0, movedCol);
|
|
@@ -409,136 +383,233 @@ export class StDataTable extends LitElement {
|
|
|
409
383
|
}
|
|
410
384
|
|
|
411
385
|
private renderSortIcon(key: string) {
|
|
412
|
-
const sortIndex = this.sortState.findIndex(s => s.key === key);
|
|
386
|
+
const sortIndex = this.sortState.findIndex((s) => s.key === key);
|
|
413
387
|
if (sortIndex === -1) {
|
|
414
|
-
return html`<svg
|
|
388
|
+
return html`<svg
|
|
389
|
+
class="sort-icon"
|
|
390
|
+
viewBox="0 0 24 24"
|
|
391
|
+
fill="none"
|
|
392
|
+
stroke="currentColor"
|
|
393
|
+
stroke-width="2"
|
|
394
|
+
stroke-linecap="round"
|
|
395
|
+
stroke-linejoin="round"
|
|
396
|
+
>
|
|
397
|
+
<path d="m7 15 5 5 5-5" />
|
|
398
|
+
<path d="m7 9 5-5 5 5" />
|
|
399
|
+
</svg>`;
|
|
415
400
|
}
|
|
416
401
|
|
|
417
402
|
const sortConfig = this.sortState[sortIndex];
|
|
418
|
-
const icon =
|
|
419
|
-
|
|
420
|
-
|
|
403
|
+
const icon =
|
|
404
|
+
sortConfig.direction === "asc"
|
|
405
|
+
? html`<svg
|
|
406
|
+
class="sort-icon active"
|
|
407
|
+
viewBox="0 0 24 24"
|
|
408
|
+
fill="none"
|
|
409
|
+
stroke="currentColor"
|
|
410
|
+
stroke-width="2"
|
|
411
|
+
stroke-linecap="round"
|
|
412
|
+
stroke-linejoin="round"
|
|
413
|
+
>
|
|
414
|
+
<path d="m18 15-6-6-6 6" />
|
|
415
|
+
</svg>`
|
|
416
|
+
: html`<svg
|
|
417
|
+
class="sort-icon active"
|
|
418
|
+
viewBox="0 0 24 24"
|
|
419
|
+
fill="none"
|
|
420
|
+
stroke="currentColor"
|
|
421
|
+
stroke-width="2"
|
|
422
|
+
stroke-linecap="round"
|
|
423
|
+
stroke-linejoin="round"
|
|
424
|
+
>
|
|
425
|
+
<path d="m6 9 6 6 6-6" />
|
|
426
|
+
</svg>`;
|
|
421
427
|
|
|
422
|
-
const priority =
|
|
423
|
-
|
|
424
|
-
|
|
428
|
+
const priority =
|
|
429
|
+
this.sortState.length > 1 && this.multiSort
|
|
430
|
+
? html`<span class="sort-priority">${sortIndex + 1}</span>`
|
|
431
|
+
: "";
|
|
425
432
|
|
|
426
433
|
return html`${icon}${priority}`;
|
|
427
434
|
}
|
|
428
435
|
|
|
429
436
|
render() {
|
|
430
|
-
const visibleColumns = this.internalColumns.filter(c => !c.hidden);
|
|
437
|
+
const visibleColumns = this.internalColumns.filter((c) => !c.hidden);
|
|
431
438
|
const skeletonRowsCount = Math.min(this.pageSize, 5);
|
|
432
439
|
|
|
433
440
|
return html`
|
|
434
|
-
<!-- Toolbar -->
|
|
435
441
|
<div class="toolbar">
|
|
436
442
|
<div class="search-wrapper">
|
|
437
|
-
<svg
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
443
|
+
<svg
|
|
444
|
+
class="search-icon"
|
|
445
|
+
aria-hidden="true"
|
|
446
|
+
viewBox="0 0 24 24"
|
|
447
|
+
fill="none"
|
|
448
|
+
stroke="currentColor"
|
|
449
|
+
stroke-width="2"
|
|
450
|
+
stroke-linecap="round"
|
|
451
|
+
stroke-linejoin="round"
|
|
452
|
+
>
|
|
453
|
+
<circle cx="11" cy="11" r="8"></circle>
|
|
454
|
+
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
455
|
+
</svg>
|
|
456
|
+
<input
|
|
457
|
+
type="text"
|
|
458
|
+
class="search-input"
|
|
459
|
+
placeholder="Search..."
|
|
460
|
+
aria-label="Search data table"
|
|
461
|
+
spellcheck="false"
|
|
462
|
+
autocapitalize="none"
|
|
442
463
|
?disabled=${this.loading}
|
|
443
464
|
@input=${this.handleSearchInput}
|
|
444
|
-
|
|
465
|
+
/>
|
|
445
466
|
</div>
|
|
446
467
|
|
|
447
468
|
<div class="columns-toggle-wrapper">
|
|
448
|
-
<st-button
|
|
449
|
-
variant="secondary"
|
|
450
|
-
size="sm"
|
|
451
|
-
|
|
469
|
+
<st-button
|
|
470
|
+
variant="secondary"
|
|
471
|
+
size="sm"
|
|
472
|
+
aria-haspopup="menu"
|
|
473
|
+
aria-expanded=${this.showColumnMenu}
|
|
474
|
+
@click=${() => (this.showColumnMenu = !this.showColumnMenu)}
|
|
452
475
|
>
|
|
453
476
|
Columns
|
|
454
477
|
</st-button>
|
|
455
|
-
|
|
456
|
-
${this.showColumnMenu
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
478
|
+
|
|
479
|
+
${this.showColumnMenu
|
|
480
|
+
? html`
|
|
481
|
+
<div class="columns-menu" role="menu">
|
|
482
|
+
${this.internalColumns.map(
|
|
483
|
+
(col) => html`
|
|
484
|
+
<label
|
|
485
|
+
class="column-option"
|
|
486
|
+
role="menuitemcheckbox"
|
|
487
|
+
aria-checked=${!col.hidden}
|
|
488
|
+
>
|
|
489
|
+
<input
|
|
490
|
+
type="checkbox"
|
|
491
|
+
.checked=${!col.hidden}
|
|
492
|
+
@change=${() => this.toggleColumnVisibility(col.key)}
|
|
493
|
+
/>
|
|
494
|
+
${col.header}
|
|
495
|
+
</label>
|
|
496
|
+
`,
|
|
497
|
+
)}
|
|
498
|
+
</div>
|
|
499
|
+
`
|
|
500
|
+
: ""}
|
|
470
501
|
</div>
|
|
471
502
|
</div>
|
|
472
503
|
|
|
473
|
-
<!-- Table -->
|
|
474
504
|
<div class="table-wrapper">
|
|
475
|
-
<table>
|
|
505
|
+
<table aria-busy=${this.loading}>
|
|
476
506
|
<thead>
|
|
477
507
|
<tr>
|
|
478
|
-
${visibleColumns.map(col =>
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
508
|
+
${visibleColumns.map((col) => {
|
|
509
|
+
const sortItem = this.sortState.find((s) => s.key === col.key);
|
|
510
|
+
const ariaSort = sortItem
|
|
511
|
+
? sortItem.direction === "asc"
|
|
512
|
+
? "ascending"
|
|
513
|
+
: "descending"
|
|
514
|
+
: "none";
|
|
515
|
+
|
|
516
|
+
return html`
|
|
517
|
+
<th
|
|
518
|
+
scope="col"
|
|
519
|
+
aria-sort=${ifDefined(col.sortable ? ariaSort : undefined)}
|
|
520
|
+
draggable="true"
|
|
521
|
+
@dragstart=${(e: DragEvent) => this.handleDragStart(e, col.key)}
|
|
522
|
+
@dragover=${this.handleDragOver}
|
|
523
|
+
@dragleave=${this.handleDragLeave}
|
|
524
|
+
@drop=${(e: DragEvent) => this.handleDrop(e, col.key)}
|
|
525
|
+
>
|
|
526
|
+
<div class="th-content">
|
|
527
|
+
<svg
|
|
528
|
+
class="drag-handle"
|
|
529
|
+
aria-hidden="true"
|
|
530
|
+
width="12"
|
|
531
|
+
height="12"
|
|
532
|
+
viewBox="0 0 24 24"
|
|
533
|
+
fill="none"
|
|
534
|
+
stroke="currentColor"
|
|
535
|
+
stroke-width="2"
|
|
536
|
+
stroke-linecap="round"
|
|
537
|
+
stroke-linejoin="round"
|
|
538
|
+
>
|
|
539
|
+
<circle cx="9" cy="12" r="1" />
|
|
540
|
+
<circle cx="9" cy="5" r="1" />
|
|
541
|
+
<circle cx="9" cy="19" r="1" />
|
|
542
|
+
<circle cx="15" cy="12" r="1" />
|
|
543
|
+
<circle cx="15" cy="5" r="1" />
|
|
544
|
+
<circle cx="15" cy="19" r="1" />
|
|
545
|
+
</svg>
|
|
546
|
+
|
|
547
|
+
<div
|
|
548
|
+
class=${classMap({"sortable-header": !!col.sortable})}
|
|
549
|
+
@click=${(e: MouseEvent) => col.sortable && this.handleSort(col.key, e)}
|
|
550
|
+
>
|
|
551
|
+
${col.header} ${col.sortable ? this.renderSortIcon(col.key) : ""}
|
|
552
|
+
</div>
|
|
495
553
|
</div>
|
|
496
|
-
</
|
|
497
|
-
|
|
498
|
-
|
|
554
|
+
</th>
|
|
555
|
+
`;
|
|
556
|
+
})}
|
|
499
557
|
</tr>
|
|
500
558
|
</thead>
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
${
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
`
|
|
519
|
-
|
|
520
|
-
|
|
559
|
+
|
|
560
|
+
<tbody aria-live="polite">
|
|
561
|
+
${this.loading
|
|
562
|
+
? html`
|
|
563
|
+
${Array.from({length: skeletonRowsCount}).map(
|
|
564
|
+
() => html`
|
|
565
|
+
<tr>
|
|
566
|
+
${visibleColumns.map(
|
|
567
|
+
() => html`
|
|
568
|
+
<td><st-skeleton variant="text" width="75%"></st-skeleton></td>
|
|
569
|
+
`,
|
|
570
|
+
)}
|
|
571
|
+
</tr>
|
|
572
|
+
`,
|
|
573
|
+
)}
|
|
574
|
+
`
|
|
575
|
+
: this.data.length === 0
|
|
576
|
+
? html`
|
|
577
|
+
<tr>
|
|
578
|
+
<td
|
|
579
|
+
colspan=${visibleColumns.length}
|
|
580
|
+
style="text-align: center; padding: 2rem;"
|
|
581
|
+
>
|
|
582
|
+
No results found.
|
|
583
|
+
</td>
|
|
584
|
+
</tr>
|
|
585
|
+
`
|
|
586
|
+
: this.data.map(
|
|
587
|
+
(row) => html`
|
|
588
|
+
<tr>
|
|
589
|
+
${visibleColumns.map((col) => html`<td>${row[col.key] ?? ""}</td>`)}
|
|
590
|
+
</tr>
|
|
591
|
+
`,
|
|
592
|
+
)}
|
|
521
593
|
</tbody>
|
|
522
594
|
</table>
|
|
523
595
|
</div>
|
|
524
596
|
|
|
525
|
-
<!-- Pagination -->
|
|
526
597
|
<div class="pagination">
|
|
527
598
|
<div class="pagination-info">
|
|
528
599
|
Page ${this.page} of ${this.totalPages} (${this.totalRows} total items)
|
|
529
600
|
</div>
|
|
530
601
|
<div class="pagination-controls">
|
|
531
|
-
<st-button
|
|
532
|
-
variant="secondary"
|
|
533
|
-
size="sm"
|
|
602
|
+
<st-button
|
|
603
|
+
variant="secondary"
|
|
604
|
+
size="sm"
|
|
534
605
|
?disabled=${this.loading || this.page === 1}
|
|
535
606
|
@click=${this.prevPage}
|
|
536
607
|
>
|
|
537
608
|
Prev
|
|
538
609
|
</st-button>
|
|
539
|
-
<st-button
|
|
540
|
-
variant="secondary"
|
|
541
|
-
size="sm"
|
|
610
|
+
<st-button
|
|
611
|
+
variant="secondary"
|
|
612
|
+
size="sm"
|
|
542
613
|
?disabled=${this.loading || this.page === this.totalPages}
|
|
543
614
|
@click=${this.nextPage}
|
|
544
615
|
>
|
|
@@ -552,6 +623,6 @@ export class StDataTable extends LitElement {
|
|
|
552
623
|
|
|
553
624
|
declare global {
|
|
554
625
|
interface HTMLElementTagNameMap {
|
|
555
|
-
|
|
626
|
+
"st-data-table": StDataTable;
|
|
556
627
|
}
|
|
557
|
-
}
|
|
628
|
+
}
|