@ibobbyts/svelte-ui-utils 0.1.2
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 +21 -0
- package/README.md +379 -0
- package/dist/data-table/BaseDataTable.svelte +322 -0
- package/dist/data-table/BaseDataTable.svelte.d.ts +49 -0
- package/dist/data-table/BaseDataTable.svelte.d.ts.map +1 -0
- package/dist/data-table/DataTable.svelte +104 -0
- package/dist/data-table/DataTable.svelte.d.ts +59 -0
- package/dist/data-table/DataTable.svelte.d.ts.map +1 -0
- package/dist/data-table/DateRangeFilter.svelte +174 -0
- package/dist/data-table/DateRangeFilter.svelte.d.ts +30 -0
- package/dist/data-table/DateRangeFilter.svelte.d.ts.map +1 -0
- package/dist/data-table/FilterControl.svelte +184 -0
- package/dist/data-table/FilterControl.svelte.d.ts +5 -0
- package/dist/data-table/FilterControl.svelte.d.ts.map +1 -0
- package/dist/data-table/FilterTable.svelte +25 -0
- package/dist/data-table/FilterTable.svelte.d.ts +24 -0
- package/dist/data-table/FilterTable.svelte.d.ts.map +1 -0
- package/dist/data-table/NumberRangeFilter.svelte +80 -0
- package/dist/data-table/NumberRangeFilter.svelte.d.ts +32 -0
- package/dist/data-table/NumberRangeFilter.svelte.d.ts.map +1 -0
- package/dist/data-table/filter.d.ts +23 -0
- package/dist/data-table/filter.d.ts.map +1 -0
- package/dist/data-table/filter.js +38 -0
- package/dist/data-table/index.d.ts +11 -0
- package/dist/data-table/index.d.ts.map +1 -0
- package/dist/data-table/index.js +8 -0
- package/dist/data-table/state.d.ts +11 -0
- package/dist/data-table/state.d.ts.map +1 -0
- package/dist/data-table/state.js +58 -0
- package/dist/data-table/types.d.ts +167 -0
- package/dist/data-table/types.d.ts.map +1 -0
- package/dist/data-table/types.js +1 -0
- package/dist/dropdown/Dropdown.svelte +159 -0
- package/dist/dropdown/Dropdown.svelte.d.ts +28 -0
- package/dist/dropdown/Dropdown.svelte.d.ts.map +1 -0
- package/dist/dropdown/index.d.ts +3 -0
- package/dist/dropdown/index.d.ts.map +1 -0
- package/dist/dropdown/index.js +1 -0
- package/dist/dropdown/types.d.ts +9 -0
- package/dist/dropdown/types.d.ts.map +1 -0
- package/dist/dropdown/types.js +1 -0
- package/dist/dropdown-search/DropdownSearch.svelte +312 -0
- package/dist/dropdown-search/DropdownSearch.svelte.d.ts +51 -0
- package/dist/dropdown-search/DropdownSearch.svelte.d.ts.map +1 -0
- package/dist/dropdown-search/index.d.ts +6 -0
- package/dist/dropdown-search/index.d.ts.map +1 -0
- package/dist/dropdown-search/index.js +3 -0
- package/dist/dropdown-search/state.d.ts +15 -0
- package/dist/dropdown-search/state.d.ts.map +1 -0
- package/dist/dropdown-search/state.js +44 -0
- package/dist/dropdown-search/types.d.ts +24 -0
- package/dist/dropdown-search/types.d.ts.map +1 -0
- package/dist/dropdown-search/types.js +1 -0
- package/dist/i18n.d.ts +31 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +118 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/pagination/Pagination.svelte +112 -0
- package/dist/pagination/Pagination.svelte.d.ts +30 -0
- package/dist/pagination/Pagination.svelte.d.ts.map +1 -0
- package/dist/pagination/index.d.ts +6 -0
- package/dist/pagination/index.d.ts.map +1 -0
- package/dist/pagination/index.js +3 -0
- package/dist/style.css +1110 -0
- package/dist/toast/Toast.svelte +37 -0
- package/dist/toast/Toast.svelte.d.ts +26 -0
- package/dist/toast/Toast.svelte.d.ts.map +1 -0
- package/dist/toast/ToastManager.svelte +29 -0
- package/dist/toast/ToastManager.svelte.d.ts +26 -0
- package/dist/toast/ToastManager.svelte.d.ts.map +1 -0
- package/dist/toast/index.d.ts +7 -0
- package/dist/toast/index.d.ts.map +1 -0
- package/dist/toast/index.js +4 -0
- package/dist/toast/store.d.ts +7 -0
- package/dist/toast/store.d.ts.map +1 -0
- package/dist/toast/store.js +114 -0
- package/dist/toast/types.d.ts +36 -0
- package/dist/toast/types.d.ts.map +1 -0
- package/dist/toast/types.js +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte';
|
|
3
|
+
import { getUiMessages, type UiLanguage } from '../i18n.js';
|
|
4
|
+
import { getAriaSort, getCellValue, toggleSort } from './state.js';
|
|
5
|
+
import type {
|
|
6
|
+
DataTableCellValue,
|
|
7
|
+
DataTableColumn,
|
|
8
|
+
DataTableLayout,
|
|
9
|
+
DataTableRowAttributes,
|
|
10
|
+
DataTableRowKey,
|
|
11
|
+
DataTableSortChangeHandler,
|
|
12
|
+
SortState
|
|
13
|
+
} from './types.js';
|
|
14
|
+
|
|
15
|
+
export let rows: unknown[] = [];
|
|
16
|
+
export let columns: DataTableColumn[] = [];
|
|
17
|
+
export let sort: SortState | null = null;
|
|
18
|
+
export let zebra = true;
|
|
19
|
+
export let bordered = true;
|
|
20
|
+
export let verticalSeparators = false;
|
|
21
|
+
export let tableLayout: DataTableLayout = 'auto';
|
|
22
|
+
export let stickyHeader = true;
|
|
23
|
+
export let stickyHeaderTop: string | undefined = undefined;
|
|
24
|
+
export let stickyHeaderOffset: string | undefined = undefined;
|
|
25
|
+
export let preserveScrollOnSort = true;
|
|
26
|
+
export let language: UiLanguage = 'en_us';
|
|
27
|
+
export let emptyText: string | undefined = undefined;
|
|
28
|
+
export let rowKey: DataTableRowKey | undefined = undefined;
|
|
29
|
+
export let rowClass: string | ((row: unknown, index: number) => string | undefined | null) | undefined = undefined;
|
|
30
|
+
export let rowAttributes: DataTableRowAttributes | undefined = undefined;
|
|
31
|
+
export let onSortChange: DataTableSortChangeHandler | undefined = undefined;
|
|
32
|
+
|
|
33
|
+
let scrollRestoreSequence = 0;
|
|
34
|
+
let tableElement: HTMLTableElement | undefined = undefined;
|
|
35
|
+
let stickyHeaderVisible = false;
|
|
36
|
+
let stickyHeaderLeft = 0;
|
|
37
|
+
let stickyHeaderWidth = 0;
|
|
38
|
+
let stickyHeaderColumnWidths: number[] = [];
|
|
39
|
+
let stickyHeaderUpdateFrame: number | null = null;
|
|
40
|
+
let stickyHeaderOffsetProbe: HTMLSpanElement | undefined = undefined;
|
|
41
|
+
$: messages = getUiMessages(language);
|
|
42
|
+
$: resolvedEmptyText = emptyText ?? messages.table.emptyText;
|
|
43
|
+
$: resolvedStickyHeaderTop = stickyHeaderOffset ?? stickyHeaderTop;
|
|
44
|
+
|
|
45
|
+
function restoreScrollPosition(scrollX: number, scrollY: number, sequence: number) {
|
|
46
|
+
if (!preserveScrollOnSort || typeof window === 'undefined' || sequence !== scrollRestoreSequence) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
window.scrollTo(scrollX, scrollY);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function queueScrollRestore(scrollX: number, scrollY: number, sequence: number) {
|
|
54
|
+
if (!preserveScrollOnSort || typeof window === 'undefined') {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const restore = () => restoreScrollPosition(scrollX, scrollY, sequence);
|
|
59
|
+
restore();
|
|
60
|
+
window.requestAnimationFrame?.(restore);
|
|
61
|
+
setTimeout(restore, 0);
|
|
62
|
+
setTimeout(restore, 50);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function updateStickyHeader() {
|
|
66
|
+
if (!stickyHeader || typeof window === 'undefined' || !tableElement) {
|
|
67
|
+
stickyHeaderVisible = false;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const header = tableElement.tHead;
|
|
72
|
+
const firstHeaderCell = header?.querySelector('th');
|
|
73
|
+
if (!header || !firstHeaderCell) {
|
|
74
|
+
stickyHeaderVisible = false;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const tableRect = tableElement.getBoundingClientRect();
|
|
79
|
+
const headerRect = header.getBoundingClientRect();
|
|
80
|
+
const stickyTop = stickyHeaderOffsetProbe?.getBoundingClientRect().top ?? 0;
|
|
81
|
+
const nextVisible = headerRect.top <= stickyTop && tableRect.bottom > stickyTop + headerRect.height;
|
|
82
|
+
stickyHeaderVisible = nextVisible;
|
|
83
|
+
|
|
84
|
+
if (!nextVisible) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
stickyHeaderLeft = tableRect.left;
|
|
89
|
+
stickyHeaderWidth = tableRect.width;
|
|
90
|
+
stickyHeaderColumnWidths = Array.from(header.querySelectorAll('th')).map((cell) => cell.getBoundingClientRect().width);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function queueStickyHeaderUpdate() {
|
|
94
|
+
if (typeof window === 'undefined') {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (stickyHeaderUpdateFrame !== null) {
|
|
99
|
+
window.cancelAnimationFrame(stickyHeaderUpdateFrame);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
stickyHeaderUpdateFrame = window.requestAnimationFrame(() => {
|
|
103
|
+
stickyHeaderUpdateFrame = null;
|
|
104
|
+
updateStickyHeader();
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function handleSort(column: DataTableColumn) {
|
|
109
|
+
if (!column.sortable) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const shouldPreserveScroll = preserveScrollOnSort && typeof window !== 'undefined';
|
|
114
|
+
const scrollX = shouldPreserveScroll ? window.scrollX : 0;
|
|
115
|
+
const scrollY = shouldPreserveScroll ? window.scrollY : 0;
|
|
116
|
+
const sequence = shouldPreserveScroll ? scrollRestoreSequence + 1 : scrollRestoreSequence;
|
|
117
|
+
scrollRestoreSequence = sequence;
|
|
118
|
+
|
|
119
|
+
const sortResult = onSortChange?.(toggleSort(sort, column.key));
|
|
120
|
+
if (!shouldPreserveScroll) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
queueScrollRestore(scrollX, scrollY, sequence);
|
|
125
|
+
try {
|
|
126
|
+
await sortResult;
|
|
127
|
+
} finally {
|
|
128
|
+
queueScrollRestore(scrollX, scrollY, sequence);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function resolveRowKey(row: unknown, index: number) {
|
|
133
|
+
if (typeof rowKey === 'function') {
|
|
134
|
+
return rowKey(row, index);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (rowKey && row && typeof row === 'object' && rowKey in row) {
|
|
138
|
+
return (row as Record<string, unknown>)[rowKey] as string | number;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return index;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function resolveRowClass(row: unknown, index: number) {
|
|
145
|
+
if (typeof rowClass === 'function') {
|
|
146
|
+
return rowClass(row, index) ?? '';
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return rowClass ?? '';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function resolveRowAttributes(row: unknown, index: number) {
|
|
153
|
+
return rowAttributes?.(row, index) ?? {};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function resolveCellClass(column: DataTableColumn, row: unknown, value: DataTableCellValue) {
|
|
157
|
+
if (typeof column.class === 'function') {
|
|
158
|
+
return column.class(row, value, column) ?? '';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return column.class ?? '';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
onMount(() => {
|
|
165
|
+
const update = () => queueStickyHeaderUpdate();
|
|
166
|
+
const observer = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(update) : undefined;
|
|
167
|
+
|
|
168
|
+
if (tableElement) {
|
|
169
|
+
observer?.observe(tableElement);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
window.addEventListener('scroll', update, { passive: true });
|
|
173
|
+
window.addEventListener('resize', update);
|
|
174
|
+
queueStickyHeaderUpdate();
|
|
175
|
+
|
|
176
|
+
return () => {
|
|
177
|
+
window.removeEventListener('scroll', update);
|
|
178
|
+
window.removeEventListener('resize', update);
|
|
179
|
+
observer?.disconnect();
|
|
180
|
+
if (stickyHeaderUpdateFrame !== null) {
|
|
181
|
+
window.cancelAnimationFrame(stickyHeaderUpdateFrame);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
$: {
|
|
187
|
+
rows;
|
|
188
|
+
columns;
|
|
189
|
+
sort;
|
|
190
|
+
stickyHeader;
|
|
191
|
+
resolvedStickyHeaderTop;
|
|
192
|
+
queueStickyHeaderUpdate();
|
|
193
|
+
}
|
|
194
|
+
</script>
|
|
195
|
+
|
|
196
|
+
<div class:suu-table-wrap--borderless={!bordered} class="suu-table-wrap" style:--suu-table-sticky-top={resolvedStickyHeaderTop}>
|
|
197
|
+
<span bind:this={stickyHeaderOffsetProbe} class="suu-table__sticky-offset-probe" aria-hidden="true"></span>
|
|
198
|
+
|
|
199
|
+
{#if stickyHeaderVisible}
|
|
200
|
+
<div
|
|
201
|
+
class="suu-table__sticky-clone"
|
|
202
|
+
style:left={`${stickyHeaderLeft}px`}
|
|
203
|
+
style:width={`${stickyHeaderWidth}px`}
|
|
204
|
+
aria-hidden="true"
|
|
205
|
+
>
|
|
206
|
+
<table
|
|
207
|
+
class:suu-table--layout-auto={tableLayout === 'auto'}
|
|
208
|
+
class:suu-table--layout-fixed={tableLayout === 'fixed'}
|
|
209
|
+
class:suu-table--sticky-header={stickyHeader}
|
|
210
|
+
class:suu-table--zebra={zebra}
|
|
211
|
+
class:suu-table--vertical-separators={verticalSeparators}
|
|
212
|
+
class="suu-table"
|
|
213
|
+
>
|
|
214
|
+
<thead>
|
|
215
|
+
<tr>
|
|
216
|
+
{#each columns as column, columnIndex (column.key)}
|
|
217
|
+
<th
|
|
218
|
+
class={column.headerClass}
|
|
219
|
+
aria-sort={column.sortable ? getAriaSort(sort, column.key) : undefined}
|
|
220
|
+
data-align={column.align ?? 'left'}
|
|
221
|
+
scope="col"
|
|
222
|
+
style:width={stickyHeaderColumnWidths[columnIndex] ? `${stickyHeaderColumnWidths[columnIndex]}px` : undefined}
|
|
223
|
+
style:min-width={stickyHeaderColumnWidths[columnIndex] ? `${stickyHeaderColumnWidths[columnIndex]}px` : undefined}
|
|
224
|
+
style:max-width={stickyHeaderColumnWidths[columnIndex] ? `${stickyHeaderColumnWidths[columnIndex]}px` : undefined}
|
|
225
|
+
>
|
|
226
|
+
{#if column.sortable}
|
|
227
|
+
<button class="suu-table__sort-button" type="button" on:click={() => handleSort(column)}>
|
|
228
|
+
<span><slot name="header" {column} {sort}>{column.header}</slot></span>
|
|
229
|
+
<span class="suu-table__sort-indicator" aria-hidden="true">
|
|
230
|
+
{#if sort?.key === column.key && sort.direction === 'asc'}
|
|
231
|
+
<svg class="suu-table__sort-icon suu-table__sort-icon--asc" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
232
|
+
<path d="M5 9.5 8 6.5l3 3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6" />
|
|
233
|
+
</svg>
|
|
234
|
+
{:else if sort?.key === column.key}
|
|
235
|
+
<svg class="suu-table__sort-icon suu-table__sort-icon--desc" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
236
|
+
<path d="m5 6.5 3 3 3-3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6" />
|
|
237
|
+
</svg>
|
|
238
|
+
{:else}
|
|
239
|
+
<svg class="suu-table__sort-icon suu-table__sort-icon--both" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
240
|
+
<path d="M5 6.5 8 3.5l3 3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6" />
|
|
241
|
+
<path d="m5 9.5 3 3 3-3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6" />
|
|
242
|
+
</svg>
|
|
243
|
+
{/if}
|
|
244
|
+
</span>
|
|
245
|
+
</button>
|
|
246
|
+
{:else}
|
|
247
|
+
<slot name="header" {column} {sort}>{column.header}</slot>
|
|
248
|
+
{/if}
|
|
249
|
+
</th>
|
|
250
|
+
{/each}
|
|
251
|
+
</tr>
|
|
252
|
+
</thead>
|
|
253
|
+
</table>
|
|
254
|
+
</div>
|
|
255
|
+
{/if}
|
|
256
|
+
|
|
257
|
+
<table
|
|
258
|
+
bind:this={tableElement}
|
|
259
|
+
class:suu-table--layout-auto={tableLayout === 'auto'}
|
|
260
|
+
class:suu-table--layout-fixed={tableLayout === 'fixed'}
|
|
261
|
+
class:suu-table--sticky-header={stickyHeader}
|
|
262
|
+
class:suu-table--sticky-header-shadowed={stickyHeaderVisible}
|
|
263
|
+
class:suu-table--zebra={zebra}
|
|
264
|
+
class:suu-table--vertical-separators={verticalSeparators}
|
|
265
|
+
class="suu-table"
|
|
266
|
+
>
|
|
267
|
+
<thead>
|
|
268
|
+
<tr>
|
|
269
|
+
{#each columns as column (column.key)}
|
|
270
|
+
<th
|
|
271
|
+
class={column.headerClass}
|
|
272
|
+
aria-sort={column.sortable ? getAriaSort(sort, column.key) : undefined}
|
|
273
|
+
data-align={column.align ?? 'left'}
|
|
274
|
+
scope="col"
|
|
275
|
+
>
|
|
276
|
+
{#if column.sortable}
|
|
277
|
+
<button class="suu-table__sort-button" type="button" on:click={() => handleSort(column)}>
|
|
278
|
+
<span><slot name="header" {column} {sort}>{column.header}</slot></span>
|
|
279
|
+
<span class="suu-table__sort-indicator" aria-hidden="true">
|
|
280
|
+
{#if sort?.key === column.key && sort.direction === 'asc'}
|
|
281
|
+
<svg class="suu-table__sort-icon suu-table__sort-icon--asc" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
282
|
+
<path d="M5 9.5 8 6.5l3 3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6" />
|
|
283
|
+
</svg>
|
|
284
|
+
{:else if sort?.key === column.key}
|
|
285
|
+
<svg class="suu-table__sort-icon suu-table__sort-icon--desc" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
286
|
+
<path d="m5 6.5 3 3 3-3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6" />
|
|
287
|
+
</svg>
|
|
288
|
+
{:else}
|
|
289
|
+
<svg class="suu-table__sort-icon suu-table__sort-icon--both" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
|
|
290
|
+
<path d="M5 6.5 8 3.5l3 3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6" />
|
|
291
|
+
<path d="m5 9.5 3 3 3-3" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6" />
|
|
292
|
+
</svg>
|
|
293
|
+
{/if}
|
|
294
|
+
</span>
|
|
295
|
+
</button>
|
|
296
|
+
{:else}
|
|
297
|
+
<slot name="header" {column} {sort}>{column.header}</slot>
|
|
298
|
+
{/if}
|
|
299
|
+
</th>
|
|
300
|
+
{/each}
|
|
301
|
+
</tr>
|
|
302
|
+
</thead>
|
|
303
|
+
<tbody>
|
|
304
|
+
{#if rows.length > 0}
|
|
305
|
+
{#each rows as row, rowIndex (resolveRowKey(row, rowIndex))}
|
|
306
|
+
<tr {...resolveRowAttributes(row, rowIndex)} class={resolveRowClass(row, rowIndex)}>
|
|
307
|
+
{#each columns as column (column.key)}
|
|
308
|
+
{@const value = getCellValue(row, column)}
|
|
309
|
+
<td class={resolveCellClass(column, row, value)} data-align={column.align ?? 'left'} data-nowrap={column.nowrap === false ? 'false' : 'true'}>
|
|
310
|
+
<slot name="cell" {row} {column} {value}>{value as string}</slot>
|
|
311
|
+
</td>
|
|
312
|
+
{/each}
|
|
313
|
+
</tr>
|
|
314
|
+
{/each}
|
|
315
|
+
{:else}
|
|
316
|
+
<tr>
|
|
317
|
+
<td class="suu-table__empty" colspan={Math.max(1, columns.length)}>{resolvedEmptyText}</td>
|
|
318
|
+
</tr>
|
|
319
|
+
{/if}
|
|
320
|
+
</tbody>
|
|
321
|
+
</table>
|
|
322
|
+
</div>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type UiLanguage } from '../i18n.js';
|
|
2
|
+
import type { DataTableColumn, DataTableLayout, DataTableRowAttributes, DataTableRowKey, DataTableSortChangeHandler, SortState } from './types.js';
|
|
3
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
4
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
5
|
+
$$bindings?: Bindings;
|
|
6
|
+
} & Exports;
|
|
7
|
+
(internal: unknown, props: Props & {
|
|
8
|
+
$$events?: Events;
|
|
9
|
+
$$slots?: Slots;
|
|
10
|
+
}): Exports & {
|
|
11
|
+
$set?: any;
|
|
12
|
+
$on?: any;
|
|
13
|
+
};
|
|
14
|
+
z_$$bindings?: Bindings;
|
|
15
|
+
}
|
|
16
|
+
declare const BaseDataTable: $$__sveltets_2_IsomorphicComponent<{
|
|
17
|
+
rows?: unknown[];
|
|
18
|
+
columns?: DataTableColumn[];
|
|
19
|
+
sort?: SortState | null;
|
|
20
|
+
zebra?: boolean;
|
|
21
|
+
bordered?: boolean;
|
|
22
|
+
verticalSeparators?: boolean;
|
|
23
|
+
tableLayout?: DataTableLayout;
|
|
24
|
+
stickyHeader?: boolean;
|
|
25
|
+
stickyHeaderTop?: string | undefined;
|
|
26
|
+
stickyHeaderOffset?: string | undefined;
|
|
27
|
+
preserveScrollOnSort?: boolean;
|
|
28
|
+
language?: UiLanguage;
|
|
29
|
+
emptyText?: string | undefined;
|
|
30
|
+
rowKey?: DataTableRowKey | undefined;
|
|
31
|
+
rowClass?: string | ((row: unknown, index: number) => string | undefined | null) | undefined;
|
|
32
|
+
rowAttributes?: DataTableRowAttributes | undefined;
|
|
33
|
+
onSortChange?: DataTableSortChangeHandler | undefined;
|
|
34
|
+
}, {
|
|
35
|
+
[evt: string]: CustomEvent<any>;
|
|
36
|
+
}, {
|
|
37
|
+
header: {
|
|
38
|
+
column: DataTableColumn<unknown>;
|
|
39
|
+
sort: SortState | null;
|
|
40
|
+
};
|
|
41
|
+
cell: {
|
|
42
|
+
row: unknown;
|
|
43
|
+
column: DataTableColumn<unknown>;
|
|
44
|
+
value: any;
|
|
45
|
+
};
|
|
46
|
+
}, {}, string>;
|
|
47
|
+
type BaseDataTable = InstanceType<typeof BaseDataTable>;
|
|
48
|
+
export default BaseDataTable;
|
|
49
|
+
//# sourceMappingURL=BaseDataTable.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseDataTable.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/BaseDataTable.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,KAAK,EAER,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,SAAS,EACV,MAAM,YAAY,CAAC;AA6RtB,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAUD,QAAA,MAAM,aAAa;WAfic,OAAO,EAAE;cAAY,eAAe,EAAE;WAAS,SAAS,GAAG,IAAI;;;;kBAAkH,eAAe;;sBAAwD,MAAM,GAAG,SAAS;yBAAuB,MAAM,GAAG,SAAS;;eAAiE,UAAU;gBAAc,MAAM,GAAG,SAAS;aAAW,eAAe,GAAG,SAAS;eAAa,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,SAAS;oBAAkB,sBAAsB,GAAG,SAAS;mBAAiB,0BAA0B,GAAG,SAAS;;;;;;;;;;;;;cAez/B,CAAC;AACvF,KAAK,aAAa,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import BaseDataTable from './BaseDataTable.svelte';
|
|
3
|
+
import Pagination from '../pagination/Pagination.svelte';
|
|
4
|
+
import { getUiMessages, type UiLanguage } from '../i18n.js';
|
|
5
|
+
import type {
|
|
6
|
+
DataTableColumn,
|
|
7
|
+
DataTableLayout,
|
|
8
|
+
DataTableRowAttributes,
|
|
9
|
+
DataTableRowKey,
|
|
10
|
+
DataTableSortChangeHandler,
|
|
11
|
+
PaginationChangeHandler,
|
|
12
|
+
PaginationState,
|
|
13
|
+
SortState
|
|
14
|
+
} from './types.js';
|
|
15
|
+
|
|
16
|
+
export let rows: unknown[] = [];
|
|
17
|
+
export let columns: DataTableColumn[] = [];
|
|
18
|
+
export let rowKey: DataTableRowKey | undefined = undefined;
|
|
19
|
+
export let language: UiLanguage = 'en_us';
|
|
20
|
+
export let emptyText: string | undefined = undefined;
|
|
21
|
+
export let sort: SortState | null = null;
|
|
22
|
+
export let onSortChange: DataTableSortChangeHandler | undefined = undefined;
|
|
23
|
+
export let showPagination = true;
|
|
24
|
+
export let page = 1;
|
|
25
|
+
export let pageSize = 20;
|
|
26
|
+
export let totalRows: number | undefined = undefined;
|
|
27
|
+
export let pageSizeOptions: number[] = [10, 20, 50, 100];
|
|
28
|
+
export let pageSizeLabel: string | undefined = undefined;
|
|
29
|
+
export let maxPageButtons = 15;
|
|
30
|
+
export let onPaginationChange: PaginationChangeHandler | undefined = undefined;
|
|
31
|
+
export let zebra = true;
|
|
32
|
+
export let bordered = true;
|
|
33
|
+
export let verticalSeparators = true;
|
|
34
|
+
export let tableLayout: DataTableLayout = 'auto';
|
|
35
|
+
export let stickyHeader = true;
|
|
36
|
+
export let stickyHeaderTop: string | undefined = undefined;
|
|
37
|
+
export let stickyHeaderOffset: string | undefined = undefined;
|
|
38
|
+
export let preserveScrollOnSort = true;
|
|
39
|
+
export let rowClass: string | ((row: unknown, index: number) => string | undefined | null) | undefined = undefined;
|
|
40
|
+
export let rowAttributes: DataTableRowAttributes | undefined = undefined;
|
|
41
|
+
|
|
42
|
+
$: messages = getUiMessages(language);
|
|
43
|
+
$: resolvedEmptyText = emptyText ?? messages.table.emptyText;
|
|
44
|
+
$: resolvedPageSizeLabel = pageSizeLabel ?? messages.table.pageSizeLabel;
|
|
45
|
+
$: resolvedTotalRows = totalRows ?? rows.length;
|
|
46
|
+
$: minimumPageSizeOption = pageSizeOptions.length > 0 ? Math.min(...pageSizeOptions) : 0;
|
|
47
|
+
$: shouldShowPagination = showPagination && (minimumPageSizeOption <= 0 || resolvedTotalRows >= minimumPageSizeOption);
|
|
48
|
+
$: pagination = { page, pageSize };
|
|
49
|
+
|
|
50
|
+
function updatePagination(next: PaginationState) {
|
|
51
|
+
void onPaginationChange?.(next);
|
|
52
|
+
}
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<div class="suu-data-table">
|
|
56
|
+
{#if shouldShowPagination}
|
|
57
|
+
<Pagination
|
|
58
|
+
{pagination}
|
|
59
|
+
{language}
|
|
60
|
+
totalRows={resolvedTotalRows}
|
|
61
|
+
{pageSizeOptions}
|
|
62
|
+
pageSizeLabel={resolvedPageSizeLabel}
|
|
63
|
+
{maxPageButtons}
|
|
64
|
+
pageSizeDropdownPlacement="down"
|
|
65
|
+
onPaginationChange={updatePagination}
|
|
66
|
+
/>
|
|
67
|
+
{/if}
|
|
68
|
+
|
|
69
|
+
<BaseDataTable
|
|
70
|
+
{rows}
|
|
71
|
+
{columns}
|
|
72
|
+
{sort}
|
|
73
|
+
{zebra}
|
|
74
|
+
{bordered}
|
|
75
|
+
{verticalSeparators}
|
|
76
|
+
{tableLayout}
|
|
77
|
+
{stickyHeader}
|
|
78
|
+
{stickyHeaderTop}
|
|
79
|
+
{stickyHeaderOffset}
|
|
80
|
+
{preserveScrollOnSort}
|
|
81
|
+
{language}
|
|
82
|
+
emptyText={resolvedEmptyText}
|
|
83
|
+
{rowKey}
|
|
84
|
+
{rowClass}
|
|
85
|
+
{rowAttributes}
|
|
86
|
+
{onSortChange}
|
|
87
|
+
>
|
|
88
|
+
<slot name="header" slot="header" let:column let:sort {column} {sort}>{column.header}</slot>
|
|
89
|
+
<slot name="cell" slot="cell" let:row let:column let:value {row} {column} {value}>{value}</slot>
|
|
90
|
+
</BaseDataTable>
|
|
91
|
+
|
|
92
|
+
{#if shouldShowPagination}
|
|
93
|
+
<Pagination
|
|
94
|
+
{pagination}
|
|
95
|
+
{language}
|
|
96
|
+
totalRows={resolvedTotalRows}
|
|
97
|
+
{pageSizeOptions}
|
|
98
|
+
pageSizeLabel={resolvedPageSizeLabel}
|
|
99
|
+
{maxPageButtons}
|
|
100
|
+
pageSizeDropdownPlacement="up"
|
|
101
|
+
onPaginationChange={updatePagination}
|
|
102
|
+
/>
|
|
103
|
+
{/if}
|
|
104
|
+
</div>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type UiLanguage } from '../i18n.js';
|
|
2
|
+
import type { DataTableColumn, DataTableLayout, DataTableRowAttributes, DataTableRowKey, DataTableSortChangeHandler, PaginationChangeHandler, SortState } from './types.js';
|
|
3
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
4
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
5
|
+
$$bindings?: Bindings;
|
|
6
|
+
} & Exports;
|
|
7
|
+
(internal: unknown, props: Props & {
|
|
8
|
+
$$events?: Events;
|
|
9
|
+
$$slots?: Slots;
|
|
10
|
+
}): Exports & {
|
|
11
|
+
$set?: any;
|
|
12
|
+
$on?: any;
|
|
13
|
+
};
|
|
14
|
+
z_$$bindings?: Bindings;
|
|
15
|
+
}
|
|
16
|
+
declare const DataTable: $$__sveltets_2_IsomorphicComponent<{
|
|
17
|
+
rows?: unknown[];
|
|
18
|
+
columns?: DataTableColumn[];
|
|
19
|
+
rowKey?: DataTableRowKey | undefined;
|
|
20
|
+
language?: UiLanguage;
|
|
21
|
+
emptyText?: string | undefined;
|
|
22
|
+
sort?: SortState | null;
|
|
23
|
+
onSortChange?: DataTableSortChangeHandler | undefined;
|
|
24
|
+
showPagination?: boolean;
|
|
25
|
+
page?: number;
|
|
26
|
+
pageSize?: number;
|
|
27
|
+
totalRows?: number | undefined;
|
|
28
|
+
pageSizeOptions?: number[];
|
|
29
|
+
pageSizeLabel?: string | undefined;
|
|
30
|
+
maxPageButtons?: number;
|
|
31
|
+
onPaginationChange?: PaginationChangeHandler | undefined;
|
|
32
|
+
zebra?: boolean;
|
|
33
|
+
bordered?: boolean;
|
|
34
|
+
verticalSeparators?: boolean;
|
|
35
|
+
tableLayout?: DataTableLayout;
|
|
36
|
+
stickyHeader?: boolean;
|
|
37
|
+
stickyHeaderTop?: string | undefined;
|
|
38
|
+
stickyHeaderOffset?: string | undefined;
|
|
39
|
+
preserveScrollOnSort?: boolean;
|
|
40
|
+
rowClass?: string | ((row: unknown, index: number) => string | undefined | null) | undefined;
|
|
41
|
+
rowAttributes?: DataTableRowAttributes | undefined;
|
|
42
|
+
}, {
|
|
43
|
+
[evt: string]: CustomEvent<any>;
|
|
44
|
+
}, {
|
|
45
|
+
header: {
|
|
46
|
+
slot: string;
|
|
47
|
+
column: DataTableColumn<unknown>;
|
|
48
|
+
sort: SortState | null;
|
|
49
|
+
};
|
|
50
|
+
cell: {
|
|
51
|
+
slot: string;
|
|
52
|
+
row: unknown;
|
|
53
|
+
column: DataTableColumn<unknown>;
|
|
54
|
+
value: any;
|
|
55
|
+
};
|
|
56
|
+
}, {}, string>;
|
|
57
|
+
type DataTable = InstanceType<typeof DataTable>;
|
|
58
|
+
export default DataTable;
|
|
59
|
+
//# sourceMappingURL=DataTable.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/DataTable.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EACR,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,uBAAuB,EAEvB,SAAS,EACV,MAAM,YAAY,CAAC;AAgEtB,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAUD,QAAA,MAAM,SAAS;WAf2qB,OAAO,EAAE;cAAY,eAAe,EAAE;aAAW,eAAe,GAAG,SAAS;eAAa,UAAU;gBAAc,MAAM,GAAG,SAAS;WAAS,SAAS,GAAG,IAAI;mBAAiB,0BAA0B,GAAG,SAAS;;;;gBAAsG,MAAM,GAAG,SAAS;sBAAoB,MAAM,EAAE;oBAAkB,MAAM,GAAG,SAAS;;yBAA+D,uBAAuB,GAAG,SAAS;;;;kBAAkH,eAAe;;sBAAwD,MAAM,GAAG,SAAS;yBAAuB,MAAM,GAAG,SAAS;;eAAiE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,SAAS;oBAAkB,sBAAsB,GAAG,SAAS;;;;;;;;;;;;;;;cAe7/C,CAAC;AACnF,KAAK,SAAS,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,CAAC;AAClD,eAAe,SAAS,CAAC"}
|