svelte-tably 1.0.0-next.5 → 1.0.0-next.6
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/README.md +2 -1
- package/dist/{Table/Column.svelte → Column.svelte} +27 -19
- package/dist/{Table/Column.svelte.d.ts → Column.svelte.d.ts} +22 -3
- package/dist/{Table/Panel.svelte → Panel.svelte} +6 -6
- package/dist/{prototype/Table.svelte.d.ts → Panel.svelte.d.ts} +27 -27
- package/dist/{Table/Table.svelte → Table.svelte} +160 -53
- package/dist/{Table/Table.svelte.d.ts → Table.svelte.d.ts} +25 -6
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/package.json +3 -1
- package/dist/Table/Panel.svelte.d.ts +0 -31
- package/dist/Table/index.d.ts +0 -1
- package/dist/Table/index.js +0 -1
- package/dist/prototype/Headers.svelte +0 -33
- package/dist/prototype/Headers.svelte.d.ts +0 -15
- package/dist/prototype/Panels.svelte +0 -25
- package/dist/prototype/Panels.svelte.d.ts +0 -15
- package/dist/prototype/Rows.svelte +0 -35
- package/dist/prototype/Rows.svelte.d.ts +0 -27
- package/dist/prototype/Statusbar.svelte +0 -35
- package/dist/prototype/Statusbar.svelte.d.ts +0 -13
- package/dist/prototype/Table.svelte +0 -336
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
<!-- @component
|
|
2
|
-
|
|
3
|
-
This is a description, \
|
|
4
|
-
on how to use this.
|
|
5
|
-
|
|
6
|
-
@example
|
|
7
|
-
<Component />
|
|
8
|
-
|
|
9
|
-
-->
|
|
10
|
-
|
|
11
|
-
<script lang='ts' generics='T extends Record<PropertyKey, unknown>'>
|
|
12
|
-
|
|
13
|
-
import type { Snippet } from 'svelte'
|
|
14
|
-
import { getTableState } from './Table.svelte'
|
|
15
|
-
|
|
16
|
-
interface Props {
|
|
17
|
-
[key: string]: Snippet<[data: T]>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
let rows: Props = $props()
|
|
21
|
-
const table = getTableState<T>()
|
|
22
|
-
|
|
23
|
-
let keys = [] as string[]
|
|
24
|
-
|
|
25
|
-
$effect.pre(() => {
|
|
26
|
-
keys.forEach(key => delete table.columns[key].row)
|
|
27
|
-
keys = []
|
|
28
|
-
|
|
29
|
-
for(const [key, value] of Object.entries(rows)) {
|
|
30
|
-
table.updateColumn(key, { row: value })
|
|
31
|
-
keys.push(key)
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
</script>
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
declare class __sveltets_Render<T extends Record<PropertyKey, unknown>> {
|
|
3
|
-
props(): {
|
|
4
|
-
[key: string]: Snippet<[data: T]>;
|
|
5
|
-
};
|
|
6
|
-
events(): {};
|
|
7
|
-
slots(): {};
|
|
8
|
-
bindings(): "";
|
|
9
|
-
exports(): {};
|
|
10
|
-
}
|
|
11
|
-
interface $$IsomorphicComponent {
|
|
12
|
-
new <T extends Record<PropertyKey, unknown>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
13
|
-
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
14
|
-
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
15
|
-
<T extends Record<PropertyKey, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
16
|
-
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* This is a description, \
|
|
20
|
-
* on how to use this.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* <Component />
|
|
24
|
-
*/
|
|
25
|
-
declare const Rows: $$IsomorphicComponent;
|
|
26
|
-
type Rows<T extends Record<PropertyKey, unknown>> = InstanceType<typeof Rows<T>>;
|
|
27
|
-
export default Rows;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
<!-- @component
|
|
2
|
-
|
|
3
|
-
This is a description, \
|
|
4
|
-
on how to use this.
|
|
5
|
-
|
|
6
|
-
@example
|
|
7
|
-
<Component />
|
|
8
|
-
|
|
9
|
-
-->
|
|
10
|
-
|
|
11
|
-
<script lang='ts'>
|
|
12
|
-
|
|
13
|
-
import type { Snippet } from 'svelte'
|
|
14
|
-
import { getTableState, type TableState } from './Table.svelte'
|
|
15
|
-
|
|
16
|
-
interface Props {
|
|
17
|
-
[key: string]: Snippet<[data: T[]]>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
let statusbars: Props = $props()
|
|
21
|
-
const table = getTableState()
|
|
22
|
-
|
|
23
|
-
let keys = [] as string[]
|
|
24
|
-
|
|
25
|
-
$effect.pre(() => {
|
|
26
|
-
keys.forEach(key => delete table.columns[key].statusbar)
|
|
27
|
-
keys = []
|
|
28
|
-
for(const [key, value] of Object.entries(statusbars)) {
|
|
29
|
-
table.updateColumn(key, { statusbar: value })
|
|
30
|
-
keys.push(key)
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
</script>
|
|
35
|
-
<!---------------------------------------------------->
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
/**
|
|
3
|
-
* This is a description, \
|
|
4
|
-
* on how to use this.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* <Component />
|
|
8
|
-
*/
|
|
9
|
-
declare const Statusbar: import("svelte").Component<{
|
|
10
|
-
[key: string]: Snippet<[data: T[]]>;
|
|
11
|
-
}, {}, "">;
|
|
12
|
-
type Statusbar = ReturnType<typeof Statusbar>;
|
|
13
|
-
export default Statusbar;
|
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
<!-- @component
|
|
2
|
-
|
|
3
|
-
This is a description, \
|
|
4
|
-
on how to use this.
|
|
5
|
-
|
|
6
|
-
@example
|
|
7
|
-
<Component />
|
|
8
|
-
|
|
9
|
-
-->
|
|
10
|
-
|
|
11
|
-
<script module lang='ts'>
|
|
12
|
-
|
|
13
|
-
export interface ColumnOptions {
|
|
14
|
-
sticky(): ColumnOptions
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface Column<T = unknown> {
|
|
18
|
-
header?: Snippet<[options: ColumnOptions]>
|
|
19
|
-
row?: Snippet<[data: T]>
|
|
20
|
-
statusbar?: Snippet<[data: T[]]>
|
|
21
|
-
defaults?: {
|
|
22
|
-
sticky?: boolean
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface TableState<T = unknown> {
|
|
27
|
-
columns: Record<string, Column<T>>
|
|
28
|
-
order: {
|
|
29
|
-
sticky: string[]
|
|
30
|
-
scroll: string[]
|
|
31
|
-
}
|
|
32
|
-
panels: Record<string, Snippet<[table: TableState]>>
|
|
33
|
-
readonly data: T[]
|
|
34
|
-
updateColumn(key: string, options: Column<T>): void
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function getTableState<T>() {
|
|
38
|
-
return getContext('svelte-dynamic-table') as TableState<T>
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
</script>
|
|
42
|
-
|
|
43
|
-
<script lang='ts' generics='T extends Record<PropertyKey, unknown>'>
|
|
44
|
-
|
|
45
|
-
import { getContext, setContext, type Snippet } from 'svelte'
|
|
46
|
-
import { sineInOut } from 'svelte/easing'
|
|
47
|
-
import { Spring, Tween } from 'svelte/motion'
|
|
48
|
-
import { fly } from 'svelte/transition'
|
|
49
|
-
|
|
50
|
-
interface Props {
|
|
51
|
-
children?: Snippet
|
|
52
|
-
data: T[]
|
|
53
|
-
panel?: string
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
let {
|
|
57
|
-
children,
|
|
58
|
-
data,
|
|
59
|
-
panel = $bindable()
|
|
60
|
-
}: Props = $props()
|
|
61
|
-
|
|
62
|
-
const table: TableState<T> = $state({
|
|
63
|
-
columns: {},
|
|
64
|
-
order: {
|
|
65
|
-
sticky: [],
|
|
66
|
-
scroll: []
|
|
67
|
-
},
|
|
68
|
-
panels: {},
|
|
69
|
-
get data() {
|
|
70
|
-
return data
|
|
71
|
-
},
|
|
72
|
-
updateColumn(key, options) {
|
|
73
|
-
if(!(key in table.columns)) {
|
|
74
|
-
const column = $state({})
|
|
75
|
-
table.columns[key] = column
|
|
76
|
-
}
|
|
77
|
-
Object.assign(table.columns[key], options)
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const columns = $derived([...table.order.sticky, ...table.order.scroll])
|
|
82
|
-
|
|
83
|
-
/** Passed to header */
|
|
84
|
-
function columnOptions(key: string) {
|
|
85
|
-
const options = $state({}) as NonNullable<Column['defaults']>
|
|
86
|
-
table.updateColumn(key, { defaults: options })
|
|
87
|
-
return {
|
|
88
|
-
sticky() {
|
|
89
|
-
options.sticky = true
|
|
90
|
-
return this
|
|
91
|
-
}
|
|
92
|
-
} as ColumnOptions
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
setContext('svelte-dynamic-table', table)
|
|
96
|
-
|
|
97
|
-
const widths = $state({}) as Record<string, number>
|
|
98
|
-
const headers = new WeakMap<HTMLDivElement, string>()
|
|
99
|
-
|
|
100
|
-
const tableId = Array.from({length: 12}, () => String.fromCharCode(Math.floor(Math.random() * 26) + 97)).join('')
|
|
101
|
-
|
|
102
|
-
const style = $derived(`
|
|
103
|
-
#${tableId} > .headers, #${tableId} > .rows > .row, #${tableId} > .statusbar {
|
|
104
|
-
grid-template-columns: ${columns.map((key, i, arr) => i === arr.length - 1 ? `minmax(${widths[key] || 150}px, 1fr)` : `${widths[key] || 150}px`).join(' ')};
|
|
105
|
-
}
|
|
106
|
-
`)
|
|
107
|
-
|
|
108
|
-
const observer = typeof MutationObserver === 'undefined' ? undefined : new MutationObserver(mutations => {
|
|
109
|
-
const target = mutations[0].target as HTMLDivElement
|
|
110
|
-
const column = headers.get(target)
|
|
111
|
-
if (!column) return
|
|
112
|
-
widths[column] = parseFloat(target.style.width)
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
function observe(node: HTMLDivElement, column: string) {
|
|
116
|
-
observer?.observe(node, {attributes: true})
|
|
117
|
-
headers.set(node, column)
|
|
118
|
-
return {
|
|
119
|
-
destroy: () => observer?.disconnect()
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
let elements = $state({}) as Record<string, HTMLElement>
|
|
124
|
-
function onscroll(event: Event) {
|
|
125
|
-
const target = event.target as HTMLDivElement
|
|
126
|
-
elements.headers.scrollLeft = target.scrollLeft
|
|
127
|
-
elements.statusbar.scrollLeft = target.scrollLeft
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const panelTween = new Tween(0, { duration: 300, easing: sineInOut })
|
|
131
|
-
let panelWidth = $state(0)
|
|
132
|
-
let panelTransitioning = $state(false)
|
|
133
|
-
$effect(() => {
|
|
134
|
-
panelTransitioning = true
|
|
135
|
-
panelTween.set(panel ? panelWidth : 0).then(() => panelTransitioning = false)
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
</script>
|
|
139
|
-
<!---------------------------------------------------->
|
|
140
|
-
|
|
141
|
-
<svelte:head>
|
|
142
|
-
{@html `<style>${style}</style>`}
|
|
143
|
-
</svelte:head>
|
|
144
|
-
|
|
145
|
-
<div id={tableId} class='table'>
|
|
146
|
-
|
|
147
|
-
<div class='headers' bind:this={elements.headers}>
|
|
148
|
-
{#each table.order.sticky as column, i (column)}
|
|
149
|
-
<div class='column sticky' use:observe={column}>
|
|
150
|
-
{@render table.columns[column]?.header?.({ sticky() {} } as ColumnOptions)}
|
|
151
|
-
</div>
|
|
152
|
-
{/each}
|
|
153
|
-
{#each table.order.scroll as column, i (column)}
|
|
154
|
-
<div class='column' use:observe={column}>
|
|
155
|
-
{@render table.columns[column]?.header?.({ sticky() {} } as ColumnOptions)}
|
|
156
|
-
</div>
|
|
157
|
-
{/each}
|
|
158
|
-
|
|
159
|
-
</div>
|
|
160
|
-
|
|
161
|
-
<div class="rows" {onscroll}>
|
|
162
|
-
{#each data as item}
|
|
163
|
-
<div class='row'>
|
|
164
|
-
{#each table.order.sticky as column, i (column)}
|
|
165
|
-
<div class='column sticky' class:border={i == table.order.sticky.length - 1}>
|
|
166
|
-
{@render table.columns[column]?.row?.(item)}
|
|
167
|
-
</div>
|
|
168
|
-
{/each}
|
|
169
|
-
{#each table.order.scroll as column, i (column)}
|
|
170
|
-
<div class='column'>
|
|
171
|
-
{@render table.columns[column]?.row?.(item)}
|
|
172
|
-
</div>
|
|
173
|
-
{/each}
|
|
174
|
-
</div>
|
|
175
|
-
{/each}
|
|
176
|
-
</div>
|
|
177
|
-
|
|
178
|
-
<div class='statusbar' bind:this={elements.statusbar}>
|
|
179
|
-
{#each table.order.sticky as column, i (column)}
|
|
180
|
-
<div class='column sticky' class:border={i == table.order.sticky.length - 1}>
|
|
181
|
-
{@render table.columns[column]?.statusbar?.(data)}
|
|
182
|
-
</div>
|
|
183
|
-
{/each}
|
|
184
|
-
{#each table.order.scroll as column, i (column)}
|
|
185
|
-
<div class='column'>
|
|
186
|
-
{@render table.columns[column]?.statusbar?.(data)}
|
|
187
|
-
</div>
|
|
188
|
-
{/each}
|
|
189
|
-
</div>
|
|
190
|
-
|
|
191
|
-
<div class='panel' style='width: {panelTween.current}px;' style:overflow={panelTransitioning ? 'hidden' : 'auto'}>
|
|
192
|
-
{#if panel && table.panels[panel]}
|
|
193
|
-
<div class="panel-content" bind:clientWidth={panelWidth} in:fly={{ x: 100, easing: sineInOut, duration:300 }} out:fly={{ x:100, duration:200, easing: sineInOut }}>
|
|
194
|
-
{@render table.panels[panel](table as TableState)}
|
|
195
|
-
</div>
|
|
196
|
-
{/if}
|
|
197
|
-
</div>
|
|
198
|
-
</div>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
{@render children?.()}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
<!---------------------------------------------------->
|
|
207
|
-
<style>
|
|
208
|
-
|
|
209
|
-
.table, .table * {
|
|
210
|
-
box-sizing: border-box;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.sticky {
|
|
214
|
-
position: sticky;
|
|
215
|
-
left: 0px;
|
|
216
|
-
/* right: 100px; */
|
|
217
|
-
background-color: white;
|
|
218
|
-
z-index: 1;
|
|
219
|
-
&.border {
|
|
220
|
-
border-right: 1px solid hsla(0, 0%, 90%);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.headers > .column {
|
|
225
|
-
border-right: 1px solid hsla(0, 0%, 90%);
|
|
226
|
-
resize: horizontal;
|
|
227
|
-
overflow: hidden;
|
|
228
|
-
padding: var(--padding-y) 0;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
.table {
|
|
232
|
-
--panel: 250px;
|
|
233
|
-
--padding-x: 1rem;
|
|
234
|
-
--padding-y: .5rem;
|
|
235
|
-
--gap: .25rem;
|
|
236
|
-
--header-height: 2.5rem;
|
|
237
|
-
|
|
238
|
-
display: grid;
|
|
239
|
-
|
|
240
|
-
grid-template-areas:
|
|
241
|
-
"headers panel"
|
|
242
|
-
"rows panel"
|
|
243
|
-
"statusbar panel"
|
|
244
|
-
;
|
|
245
|
-
|
|
246
|
-
grid-template-columns: auto min-content;
|
|
247
|
-
grid-template-rows: auto 1fr auto;
|
|
248
|
-
|
|
249
|
-
border: 1px solid hsla(0, 0%, 90%);
|
|
250
|
-
border-radius: .25rem;
|
|
251
|
-
|
|
252
|
-
max-height: 100%;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
.headers {
|
|
256
|
-
grid-area: headers;
|
|
257
|
-
z-index: 2;
|
|
258
|
-
overflow: hidden;
|
|
259
|
-
padding-right: 1rem;
|
|
260
|
-
> .column {
|
|
261
|
-
width: auto !important;
|
|
262
|
-
background-color: white;
|
|
263
|
-
border-bottom: 1px solid hsla(0, 0%, 90%);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
.rows {
|
|
268
|
-
grid-area: rows;
|
|
269
|
-
display: grid;
|
|
270
|
-
overflow: auto;
|
|
271
|
-
scrollbar-width: thin;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
.statusbar {
|
|
275
|
-
grid-area: statusbar;
|
|
276
|
-
overflow: hidden;
|
|
277
|
-
padding-right: 1rem;
|
|
278
|
-
> .column {
|
|
279
|
-
background-color: hsla(0, 0%, 99%);
|
|
280
|
-
border-top: 1px solid hsla(0, 0%, 90%);
|
|
281
|
-
padding: calc(var(--padding-y) / 2) 0;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
.headers, .row, .statusbar {
|
|
286
|
-
display: grid;
|
|
287
|
-
width: 100%;
|
|
288
|
-
height: 100%;
|
|
289
|
-
|
|
290
|
-
& > .column {
|
|
291
|
-
display: flex;
|
|
292
|
-
padding-left: var(--padding-x);
|
|
293
|
-
overflow: hidden;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
& > *:last-child {
|
|
297
|
-
width: 100%;
|
|
298
|
-
padding-right: var(--padding-x);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
.row:nth-child(1) > * {
|
|
303
|
-
padding-top: calc(var(--padding-y) + var(--gap));
|
|
304
|
-
}
|
|
305
|
-
.row:nth-last-child(1) > * {
|
|
306
|
-
padding-bottom: calc(var(--padding-y) + var(--gap));
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
.row > * {
|
|
310
|
-
padding: var(--gap) 0;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
.panel {
|
|
314
|
-
position: relative;
|
|
315
|
-
grid-area: panel;
|
|
316
|
-
width: var(--panel);
|
|
317
|
-
height: 100%;
|
|
318
|
-
background-color: white;
|
|
319
|
-
|
|
320
|
-
border-left: 1px solid hsla(0, 0%, 90%);
|
|
321
|
-
|
|
322
|
-
> .panel-content {
|
|
323
|
-
position: absolute;
|
|
324
|
-
top: 0;
|
|
325
|
-
right: 0;
|
|
326
|
-
width: min-content;
|
|
327
|
-
overflow: hidden;
|
|
328
|
-
padding: var(--padding-y) var(--padding-x);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
.statusbar {
|
|
333
|
-
grid-area: statusbar;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
</style>
|