@ims360/svelte-ivory 0.1.1 → 0.1.3
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/layout/dialog/Dialog.svelte +0 -3
- package/dist/components/layout/dialog/Dialog.svelte.d.ts.map +1 -1
- package/dist/components/table/Column.svelte +1 -1
- package/dist/components/table/Table.svelte +36 -31
- package/dist/components/table/Table.svelte.d.ts +0 -4
- package/dist/components/table/Table.svelte.d.ts.map +1 -1
- package/dist/components/table/VirtualList.svelte +32 -21
- package/dist/components/table/VirtualList.svelte.d.ts.map +1 -1
- package/dist/components/table/columnController.svelte.js +7 -7
- package/package.json +15 -15
- package/src/lib/components/layout/dialog/Dialog.svelte +0 -3
- package/src/lib/components/table/Column.svelte +1 -1
- package/src/lib/components/table/Table.svelte +36 -31
- package/src/lib/components/table/VirtualList.svelte +32 -21
- package/src/lib/components/table/columnController.svelte.ts +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/dialog/Dialog.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAOlE,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,WAAW,CAAC,EAAE,eAAe;IAC7E,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"Dialog.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/layout/dialog/Dialog.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAOlE,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,WAAW,CAAC,EAAE,eAAe;IAC7E,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AA2DL,QAAA,MAAM,MAAM,iDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
|
|
34
34
|
// Register the new column if this is the first table row that was rendered
|
|
35
35
|
const tableContext = getTableContext();
|
|
36
|
-
const rowContext = getRowContext();
|
|
37
36
|
const column = tableContext.registerColumn({ resizable, ...props });
|
|
37
|
+
const rowContext = getRowContext();
|
|
38
38
|
|
|
39
39
|
const finalOnClick = $derived(onclick || rowContext.onclick);
|
|
40
40
|
const allowClicking = $derived(!!(onclick || rowContext.onclick));
|
|
@@ -21,8 +21,6 @@
|
|
|
21
21
|
rowHeight?: number;
|
|
22
22
|
/** Renders the rows */
|
|
23
23
|
children?: Snippet<[{ row: T; nestingLevel?: number; index: number }]>;
|
|
24
|
-
/** Add columns in front of the tree-indicator */
|
|
25
|
-
firstColumn?: Snippet<[{ row: T }]>;
|
|
26
24
|
rowClass?: ClassValue;
|
|
27
25
|
headerClass?: ClassValue;
|
|
28
26
|
search?: {
|
|
@@ -68,7 +66,6 @@
|
|
|
68
66
|
class: clazz,
|
|
69
67
|
data,
|
|
70
68
|
children: passedChildren,
|
|
71
|
-
firstColumn,
|
|
72
69
|
rowClass = 'hover:bg-surface-950-50/10 transition-colors',
|
|
73
70
|
headerClass,
|
|
74
71
|
rowHeight = 64,
|
|
@@ -82,7 +79,17 @@
|
|
|
82
79
|
}: TableProps<T> = $props();
|
|
83
80
|
|
|
84
81
|
let columns = $state<ColumnController[]>(externalColumns ?? []);
|
|
85
|
-
|
|
82
|
+
|
|
83
|
+
const treeIndicatorColumnConfig: ColumnConfig = {
|
|
84
|
+
id: treeIndicatorId,
|
|
85
|
+
resizable: false,
|
|
86
|
+
header: '',
|
|
87
|
+
width: 0,
|
|
88
|
+
minWidth: 0
|
|
89
|
+
};
|
|
90
|
+
let treeIndicatorColumn = $state<ColumnController>(
|
|
91
|
+
new ColumnController(treeIndicatorColumnConfig)
|
|
92
|
+
);
|
|
86
93
|
|
|
87
94
|
setTableContext({
|
|
88
95
|
toggleExpansion,
|
|
@@ -206,7 +213,7 @@
|
|
|
206
213
|
)
|
|
207
214
|
)}
|
|
208
215
|
>
|
|
209
|
-
{#if
|
|
216
|
+
{#if results.someHaveChildren}
|
|
210
217
|
<ColumnHead column={treeIndicatorColumn}></ColumnHead>
|
|
211
218
|
{/if}
|
|
212
219
|
{#each externalColumns || columns as column (column.id)}
|
|
@@ -226,33 +233,31 @@
|
|
|
226
233
|
{/snippet}
|
|
227
234
|
{#snippet children({ row: { node, id, nestingLevel }, index })}
|
|
228
235
|
<Row href={href?.(node)} onclick={onclick ? () => onclick(node) : undefined}>
|
|
229
|
-
{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
ignoreWidth={results.someHaveChildren}
|
|
238
|
-
width={results.someHaveChildren ? treeIndicatorInset : 0}
|
|
239
|
-
minWidth={0}
|
|
240
|
-
>
|
|
241
|
-
<div
|
|
242
|
-
class="flex h-full items-center justify-end"
|
|
243
|
-
style="width: calc(var(--spacing) * {nestingLevel * nestingInset -
|
|
244
|
-
2} + {treeIndicatorInset}px);"
|
|
236
|
+
{#if results.someHaveChildren}
|
|
237
|
+
<ColumnComponent
|
|
238
|
+
{...treeIndicatorColumnConfig}
|
|
239
|
+
onclick={() => {
|
|
240
|
+
toggleExpansion(node.id);
|
|
241
|
+
}}
|
|
242
|
+
width={treeIndicatorInset}
|
|
243
|
+
ignoreWidth
|
|
245
244
|
>
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
245
|
+
<div
|
|
246
|
+
class="flex h-full items-center justify-end"
|
|
247
|
+
style="width: calc(var(--spacing) * {nestingLevel * nestingInset -
|
|
248
|
+
2} + {treeIndicatorInset}px);"
|
|
249
|
+
>
|
|
250
|
+
{#if node.children}
|
|
251
|
+
<ChevronRight
|
|
252
|
+
class={[
|
|
253
|
+
'ml-auto aspect-square shrink-0 transition-transform duration-100',
|
|
254
|
+
expanded.has(id) && 'rotate-90'
|
|
255
|
+
]}
|
|
256
|
+
/>
|
|
257
|
+
{/if}
|
|
258
|
+
</div>
|
|
259
|
+
</ColumnComponent>
|
|
260
|
+
{/if}
|
|
256
261
|
{@render passedChildren?.({ row: node, nestingLevel, index })}
|
|
257
262
|
</Row>
|
|
258
263
|
{/snippet}
|
|
@@ -15,10 +15,6 @@ export interface TableProps<T extends TableRow<T>> {
|
|
|
15
15
|
nestingLevel?: number;
|
|
16
16
|
index: number;
|
|
17
17
|
}]>;
|
|
18
|
-
/** Add columns in front of the tree-indicator */
|
|
19
|
-
firstColumn?: Snippet<[{
|
|
20
|
-
row: T;
|
|
21
|
-
}]>;
|
|
22
18
|
rowClass?: ClassValue;
|
|
23
19
|
headerClass?: ClassValue;
|
|
24
20
|
search?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/table/Table.svelte.ts"],"names":[],"mappings":"AAKI,OAAO,EAAmC,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAKzD,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;IAC7C,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,GAAG,EAAE,CAAC,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACvE,
|
|
1
|
+
{"version":3,"file":"Table.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/table/Table.svelte.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends { id: string }">
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import { onMount, type Snippet } from 'svelte';
|
|
3
|
+
import { onMount, tick, type Snippet } from 'svelte';
|
|
4
4
|
import type { ClassValue } from 'svelte/elements';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
twMerge(clsx(['flex w-full shrink-0 grow flex-row items-center overflow-hidden', rowClass]))
|
|
31
31
|
);
|
|
32
32
|
|
|
33
|
+
let viewportReactivity = $state(0);
|
|
33
34
|
let scroll_top = $state(b_scrollTop ?? 0);
|
|
34
35
|
let scroll_left = $state(0);
|
|
35
36
|
let header_width = $state(0);
|
|
@@ -64,8 +65,13 @@
|
|
|
64
65
|
const top = $derived(start * rowHeight);
|
|
65
66
|
const bottom = $derived((data.length - end) * rowHeight);
|
|
66
67
|
|
|
67
|
-
function onscroll() {
|
|
68
|
-
if (!viewport)
|
|
68
|
+
async function onscroll() {
|
|
69
|
+
if (!viewport) {
|
|
70
|
+
viewportReactivity++;
|
|
71
|
+
await tick();
|
|
72
|
+
onscroll();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
69
75
|
scroll_top = viewport.scrollTop;
|
|
70
76
|
scroll_left = viewport.scrollLeft;
|
|
71
77
|
b_scrollTop = scroll_top;
|
|
@@ -93,25 +99,30 @@
|
|
|
93
99
|
</div>
|
|
94
100
|
</div>
|
|
95
101
|
{/if}
|
|
96
|
-
|
|
97
|
-
class="flex !min-w-full grow overflow-auto [scrollbar-gutter:stable]"
|
|
98
|
-
bind:this={viewport}
|
|
99
|
-
bind:offsetHeight={viewport_height}
|
|
100
|
-
{onscroll}
|
|
101
|
-
>
|
|
102
|
+
{#key viewportReactivity}
|
|
102
103
|
<div
|
|
103
|
-
class="flex
|
|
104
|
-
|
|
104
|
+
class="flex min-w-full! grow overflow-auto [scrollbar-gutter:stable]"
|
|
105
|
+
bind:this={viewport}
|
|
106
|
+
bind:offsetHeight={viewport_height}
|
|
107
|
+
{onscroll}
|
|
105
108
|
>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
<div
|
|
110
|
+
class="flex h-fit shrink-0 flex-col"
|
|
111
|
+
style="padding-top: {top}px; padding-bottom: {bottom}px; min-width: max(100%, {header_width}px) !important;"
|
|
112
|
+
>
|
|
113
|
+
{#each visible as row, i (row.data.id)}
|
|
114
|
+
<virtual-list-row
|
|
115
|
+
class={finalRowClass}
|
|
116
|
+
style="height: {rowHeight}px !important;"
|
|
117
|
+
>
|
|
118
|
+
{@render children({
|
|
119
|
+
row: row.data,
|
|
120
|
+
domIndex: i,
|
|
121
|
+
index: row.index
|
|
122
|
+
})}
|
|
123
|
+
</virtual-list-row>
|
|
124
|
+
{/each}
|
|
125
|
+
</div>
|
|
115
126
|
</div>
|
|
116
|
-
|
|
127
|
+
{/key}
|
|
117
128
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualList.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/table/VirtualList.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"VirtualList.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/table/VirtualList.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAI9C,KAAK,KAAK,CAAC,CAAC,IAAI;IACZ,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,QAAQ,EAAE,OAAO,CAAC,CAAC;QAAE,GAAG,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAAC,iBAAS,QAAQ,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;WAwGpB,KAAK,CAAC,CAAC,CAAC;aAAwB;QAAE,QAAQ,SA1E1C,MAAM,SAAS,MAAM,UA0EsC;KAAE;;;;EAA0E;AACpK,cAAM,iBAAiB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAC5C,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,MAAM,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,QAAQ;IACR,OAAO;yBAhFkB,MAAM,SAAS,MAAM;;CAiFjD;AAED,UAAU,qBAAqB;IAC3B,KAAK,CAAC,SAAS;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACnZ,CAAC,CAAC,SAAS;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAClJ,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,WAAW,EAAE,qBAAmC,CAAC;AACrC,KAAK,WAAW,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,IAAI,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AACnF,eAAe,WAAW,CAAC"}
|
|
@@ -17,15 +17,15 @@ export class ColumnController {
|
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
updateConfig(conf) {
|
|
20
|
-
if (
|
|
20
|
+
if (typeof this.width === 'undefined') {
|
|
21
|
+
const newWidth = typeof conf.width === 'undefined' ? DEFAULT_WIDTH : conf.width;
|
|
22
|
+
this.width = newWidth;
|
|
23
|
+
}
|
|
24
|
+
if (typeof conf.minWidth !== 'undefined') {
|
|
21
25
|
this.minimalWidth = conf.minWidth;
|
|
22
26
|
}
|
|
23
27
|
else {
|
|
24
|
-
this.minimalWidth =
|
|
25
|
-
}
|
|
26
|
-
if (this.width === undefined) {
|
|
27
|
-
const newWidth = typeof conf.width === 'undefined' ? DEFAULT_WIDTH : conf.width;
|
|
28
|
-
this.width = newWidth;
|
|
28
|
+
this.minimalWidth = this.width * MINIMAL_WIDTH_MULTIPLIER;
|
|
29
29
|
}
|
|
30
30
|
if (!this.header)
|
|
31
31
|
this.header = conf.header;
|
|
@@ -35,7 +35,7 @@ export class ColumnController {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
resize(newWidth) {
|
|
38
|
-
if (newWidth === undefined)
|
|
38
|
+
if (typeof newWidth === 'undefined')
|
|
39
39
|
return;
|
|
40
40
|
if (newWidth < this.minimalWidth) {
|
|
41
41
|
this.width = this.minimalWidth;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ims360/svelte-ivory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"svelte"
|
|
6
6
|
],
|
|
@@ -72,29 +72,29 @@
|
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@floating-ui/dom": "^1.7.4",
|
|
75
|
-
"@lucide/svelte": "^0.
|
|
75
|
+
"@lucide/svelte": "^0.553.0",
|
|
76
76
|
"@tailwindcss/forms": "^0.5.10",
|
|
77
77
|
"@tailwindcss/typography": "^0.5.19",
|
|
78
|
-
"@tailwindcss/vite": "^4.1.
|
|
78
|
+
"@tailwindcss/vite": "^4.1.17",
|
|
79
79
|
"clsx": "^2.1.1",
|
|
80
80
|
"dompurify": "^3.3.0",
|
|
81
|
-
"jsdom": "^
|
|
82
|
-
"marked": "^
|
|
83
|
-
"tailwind-merge": "^3.
|
|
84
|
-
"tailwindcss": "^4.1.
|
|
81
|
+
"jsdom": "^27.2.0",
|
|
82
|
+
"marked": "^17.0.0",
|
|
83
|
+
"tailwind-merge": "^3.4.0",
|
|
84
|
+
"tailwindcss": "^4.1.17"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
87
|
"@eslint/compat": "^1.4.1",
|
|
88
88
|
"@eslint/js": "^9.39.1",
|
|
89
|
-
"@sveltejs/adapter-auto": "^
|
|
89
|
+
"@sveltejs/adapter-auto": "^7.0.0",
|
|
90
90
|
"@sveltejs/package": "^2.5.4",
|
|
91
91
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
92
92
|
"@testing-library/jest-dom": "^6.9.1",
|
|
93
93
|
"@testing-library/svelte": "^5.2.8",
|
|
94
94
|
"@testing-library/user-event": "^14.6.1",
|
|
95
|
-
"@vitest/browser": "^4.0.
|
|
96
|
-
"@vitest/coverage-v8": "^4.0.
|
|
97
|
-
"@vitest/spy": "^4.0.
|
|
95
|
+
"@vitest/browser": "^4.0.8",
|
|
96
|
+
"@vitest/coverage-v8": "^4.0.8",
|
|
97
|
+
"@vitest/spy": "^4.0.8",
|
|
98
98
|
"eslint": "^9.39.1",
|
|
99
99
|
"eslint-config-prettier": "^10.1.8",
|
|
100
100
|
"eslint-plugin-svelte": "^3.13.0",
|
|
@@ -104,11 +104,11 @@
|
|
|
104
104
|
"prettier-plugin-svelte": "^3.4.0",
|
|
105
105
|
"prettier-plugin-tailwindcss": "^0.7.1",
|
|
106
106
|
"publint": "^0.3.15",
|
|
107
|
-
"svelte-check": "^4.3.
|
|
107
|
+
"svelte-check": "^4.3.4",
|
|
108
108
|
"typescript": "^5.9.3",
|
|
109
|
-
"typescript-eslint": "^8.46.
|
|
110
|
-
"vite": "^7.
|
|
111
|
-
"vitest": "^4.0.
|
|
109
|
+
"typescript-eslint": "^8.46.4",
|
|
110
|
+
"vite": "^7.2.2",
|
|
111
|
+
"vitest": "^4.0.8"
|
|
112
112
|
},
|
|
113
113
|
"peerDependencies": {
|
|
114
114
|
"@skeletonlabs/skeleton": "^3.1.1",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
|
|
34
34
|
// Register the new column if this is the first table row that was rendered
|
|
35
35
|
const tableContext = getTableContext();
|
|
36
|
-
const rowContext = getRowContext();
|
|
37
36
|
const column = tableContext.registerColumn({ resizable, ...props });
|
|
37
|
+
const rowContext = getRowContext();
|
|
38
38
|
|
|
39
39
|
const finalOnClick = $derived(onclick || rowContext.onclick);
|
|
40
40
|
const allowClicking = $derived(!!(onclick || rowContext.onclick));
|
|
@@ -21,8 +21,6 @@
|
|
|
21
21
|
rowHeight?: number;
|
|
22
22
|
/** Renders the rows */
|
|
23
23
|
children?: Snippet<[{ row: T; nestingLevel?: number; index: number }]>;
|
|
24
|
-
/** Add columns in front of the tree-indicator */
|
|
25
|
-
firstColumn?: Snippet<[{ row: T }]>;
|
|
26
24
|
rowClass?: ClassValue;
|
|
27
25
|
headerClass?: ClassValue;
|
|
28
26
|
search?: {
|
|
@@ -68,7 +66,6 @@
|
|
|
68
66
|
class: clazz,
|
|
69
67
|
data,
|
|
70
68
|
children: passedChildren,
|
|
71
|
-
firstColumn,
|
|
72
69
|
rowClass = 'hover:bg-surface-950-50/10 transition-colors',
|
|
73
70
|
headerClass,
|
|
74
71
|
rowHeight = 64,
|
|
@@ -82,7 +79,17 @@
|
|
|
82
79
|
}: TableProps<T> = $props();
|
|
83
80
|
|
|
84
81
|
let columns = $state<ColumnController[]>(externalColumns ?? []);
|
|
85
|
-
|
|
82
|
+
|
|
83
|
+
const treeIndicatorColumnConfig: ColumnConfig = {
|
|
84
|
+
id: treeIndicatorId,
|
|
85
|
+
resizable: false,
|
|
86
|
+
header: '',
|
|
87
|
+
width: 0,
|
|
88
|
+
minWidth: 0
|
|
89
|
+
};
|
|
90
|
+
let treeIndicatorColumn = $state<ColumnController>(
|
|
91
|
+
new ColumnController(treeIndicatorColumnConfig)
|
|
92
|
+
);
|
|
86
93
|
|
|
87
94
|
setTableContext({
|
|
88
95
|
toggleExpansion,
|
|
@@ -206,7 +213,7 @@
|
|
|
206
213
|
)
|
|
207
214
|
)}
|
|
208
215
|
>
|
|
209
|
-
{#if
|
|
216
|
+
{#if results.someHaveChildren}
|
|
210
217
|
<ColumnHead column={treeIndicatorColumn}></ColumnHead>
|
|
211
218
|
{/if}
|
|
212
219
|
{#each externalColumns || columns as column (column.id)}
|
|
@@ -226,33 +233,31 @@
|
|
|
226
233
|
{/snippet}
|
|
227
234
|
{#snippet children({ row: { node, id, nestingLevel }, index })}
|
|
228
235
|
<Row href={href?.(node)} onclick={onclick ? () => onclick(node) : undefined}>
|
|
229
|
-
{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
ignoreWidth={results.someHaveChildren}
|
|
238
|
-
width={results.someHaveChildren ? treeIndicatorInset : 0}
|
|
239
|
-
minWidth={0}
|
|
240
|
-
>
|
|
241
|
-
<div
|
|
242
|
-
class="flex h-full items-center justify-end"
|
|
243
|
-
style="width: calc(var(--spacing) * {nestingLevel * nestingInset -
|
|
244
|
-
2} + {treeIndicatorInset}px);"
|
|
236
|
+
{#if results.someHaveChildren}
|
|
237
|
+
<ColumnComponent
|
|
238
|
+
{...treeIndicatorColumnConfig}
|
|
239
|
+
onclick={() => {
|
|
240
|
+
toggleExpansion(node.id);
|
|
241
|
+
}}
|
|
242
|
+
width={treeIndicatorInset}
|
|
243
|
+
ignoreWidth
|
|
245
244
|
>
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
245
|
+
<div
|
|
246
|
+
class="flex h-full items-center justify-end"
|
|
247
|
+
style="width: calc(var(--spacing) * {nestingLevel * nestingInset -
|
|
248
|
+
2} + {treeIndicatorInset}px);"
|
|
249
|
+
>
|
|
250
|
+
{#if node.children}
|
|
251
|
+
<ChevronRight
|
|
252
|
+
class={[
|
|
253
|
+
'ml-auto aspect-square shrink-0 transition-transform duration-100',
|
|
254
|
+
expanded.has(id) && 'rotate-90'
|
|
255
|
+
]}
|
|
256
|
+
/>
|
|
257
|
+
{/if}
|
|
258
|
+
</div>
|
|
259
|
+
</ColumnComponent>
|
|
260
|
+
{/if}
|
|
256
261
|
{@render passedChildren?.({ row: node, nestingLevel, index })}
|
|
257
262
|
</Row>
|
|
258
263
|
{/snippet}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends { id: string }">
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import { onMount, type Snippet } from 'svelte';
|
|
3
|
+
import { onMount, tick, type Snippet } from 'svelte';
|
|
4
4
|
import type { ClassValue } from 'svelte/elements';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
twMerge(clsx(['flex w-full shrink-0 grow flex-row items-center overflow-hidden', rowClass]))
|
|
31
31
|
);
|
|
32
32
|
|
|
33
|
+
let viewportReactivity = $state(0);
|
|
33
34
|
let scroll_top = $state(b_scrollTop ?? 0);
|
|
34
35
|
let scroll_left = $state(0);
|
|
35
36
|
let header_width = $state(0);
|
|
@@ -64,8 +65,13 @@
|
|
|
64
65
|
const top = $derived(start * rowHeight);
|
|
65
66
|
const bottom = $derived((data.length - end) * rowHeight);
|
|
66
67
|
|
|
67
|
-
function onscroll() {
|
|
68
|
-
if (!viewport)
|
|
68
|
+
async function onscroll() {
|
|
69
|
+
if (!viewport) {
|
|
70
|
+
viewportReactivity++;
|
|
71
|
+
await tick();
|
|
72
|
+
onscroll();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
69
75
|
scroll_top = viewport.scrollTop;
|
|
70
76
|
scroll_left = viewport.scrollLeft;
|
|
71
77
|
b_scrollTop = scroll_top;
|
|
@@ -93,25 +99,30 @@
|
|
|
93
99
|
</div>
|
|
94
100
|
</div>
|
|
95
101
|
{/if}
|
|
96
|
-
|
|
97
|
-
class="flex !min-w-full grow overflow-auto [scrollbar-gutter:stable]"
|
|
98
|
-
bind:this={viewport}
|
|
99
|
-
bind:offsetHeight={viewport_height}
|
|
100
|
-
{onscroll}
|
|
101
|
-
>
|
|
102
|
+
{#key viewportReactivity}
|
|
102
103
|
<div
|
|
103
|
-
class="flex
|
|
104
|
-
|
|
104
|
+
class="flex min-w-full! grow overflow-auto [scrollbar-gutter:stable]"
|
|
105
|
+
bind:this={viewport}
|
|
106
|
+
bind:offsetHeight={viewport_height}
|
|
107
|
+
{onscroll}
|
|
105
108
|
>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
<div
|
|
110
|
+
class="flex h-fit shrink-0 flex-col"
|
|
111
|
+
style="padding-top: {top}px; padding-bottom: {bottom}px; min-width: max(100%, {header_width}px) !important;"
|
|
112
|
+
>
|
|
113
|
+
{#each visible as row, i (row.data.id)}
|
|
114
|
+
<virtual-list-row
|
|
115
|
+
class={finalRowClass}
|
|
116
|
+
style="height: {rowHeight}px !important;"
|
|
117
|
+
>
|
|
118
|
+
{@render children({
|
|
119
|
+
row: row.data,
|
|
120
|
+
domIndex: i,
|
|
121
|
+
index: row.index
|
|
122
|
+
})}
|
|
123
|
+
</virtual-list-row>
|
|
124
|
+
{/each}
|
|
125
|
+
</div>
|
|
115
126
|
</div>
|
|
116
|
-
|
|
127
|
+
{/key}
|
|
117
128
|
</div>
|
|
@@ -32,15 +32,15 @@ export class ColumnController {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
updateConfig(conf: ColumnConfig) {
|
|
35
|
-
if (
|
|
36
|
-
this.minimalWidth = conf.minWidth;
|
|
37
|
-
} else {
|
|
38
|
-
this.minimalWidth = (conf.width ?? DEFAULT_WIDTH) * MINIMAL_WIDTH_MULTIPLIER;
|
|
39
|
-
}
|
|
40
|
-
if (this.width === undefined) {
|
|
35
|
+
if (typeof this.width === 'undefined') {
|
|
41
36
|
const newWidth = typeof conf.width === 'undefined' ? DEFAULT_WIDTH : conf.width;
|
|
42
37
|
this.width = newWidth;
|
|
43
38
|
}
|
|
39
|
+
if (typeof conf.minWidth !== 'undefined') {
|
|
40
|
+
this.minimalWidth = conf.minWidth;
|
|
41
|
+
} else {
|
|
42
|
+
this.minimalWidth = this.width * MINIMAL_WIDTH_MULTIPLIER;
|
|
43
|
+
}
|
|
44
44
|
if (!this.header) this.header = conf.header;
|
|
45
45
|
const newResizable = conf.resizable ?? false;
|
|
46
46
|
if (newResizable !== this.resizable) {
|
|
@@ -49,7 +49,7 @@ export class ColumnController {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
resize(newWidth?: number) {
|
|
52
|
-
if (newWidth === undefined) return;
|
|
52
|
+
if (typeof newWidth === 'undefined') return;
|
|
53
53
|
if (newWidth < this.minimalWidth) {
|
|
54
54
|
this.width = this.minimalWidth;
|
|
55
55
|
} else {
|