svelte-tably 1.0.0-next.13 → 1.0.0-next.15
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/column/column.svelte.js +3 -0
- package/dist/expandable/expandable.svelte.js +9 -2
- package/dist/size-tween.svelte.d.ts +2 -0
- package/dist/size-tween.svelte.js +3 -0
- package/dist/table/Table.svelte +184 -87
- package/dist/utility.svelte.d.ts +1 -0
- package/dist/utility.svelte.js +12 -0
- package/package.json +1 -1
|
@@ -40,6 +40,9 @@ export class ColumnState {
|
|
|
40
40
|
filter: this.#props.filter,
|
|
41
41
|
value: this.#props.value,
|
|
42
42
|
resizeable: this.#props.resizeable ?? true,
|
|
43
|
+
style: this.#props.style,
|
|
44
|
+
class: this.#props.class,
|
|
45
|
+
onclick: this.#props.onclick
|
|
43
46
|
});
|
|
44
47
|
toggleVisiblity() {
|
|
45
48
|
const index = this.table.positions.hidden.indexOf(this);
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { TableState } from '../table/table.svelte.js';
|
|
2
|
+
import { sineInOut } from 'svelte/easing';
|
|
2
3
|
export class ExpandableState {
|
|
3
4
|
#table;
|
|
4
|
-
#props =
|
|
5
|
+
#props = {};
|
|
5
6
|
snippets = $derived({
|
|
6
7
|
content: this.#props.content
|
|
7
8
|
});
|
|
8
9
|
options = $derived({
|
|
9
|
-
slide:
|
|
10
|
+
slide: {
|
|
11
|
+
duration: this.#props.slide?.duration ?? 150,
|
|
12
|
+
easing: this.#props.slide?.easing ?? sineInOut
|
|
13
|
+
},
|
|
14
|
+
click: this.#props.click ?? true,
|
|
15
|
+
chevron: this.#props.chevron ?? 'hover',
|
|
16
|
+
multiple: this.#props.multiple ?? false
|
|
10
17
|
});
|
|
11
18
|
constructor(props) {
|
|
12
19
|
this.#props = props;
|
package/dist/table/Table.svelte
CHANGED
|
@@ -13,19 +13,20 @@
|
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
15
|
<script lang="ts">
|
|
16
|
-
import { untrack, type Snippet } from 'svelte'
|
|
16
|
+
import { tick, untrack, type Snippet } from 'svelte'
|
|
17
17
|
import { fly } from 'svelte/transition'
|
|
18
18
|
import { sineInOut } from 'svelte/easing'
|
|
19
19
|
import reorder, { type ItemState } from 'runic-reorder'
|
|
20
20
|
import { Virtualization } from './virtualization.svelte.js'
|
|
21
|
-
import { TableState, type HeaderSelectCtx, type RowSelectCtx, type TableProps } from './table.svelte.js'
|
|
21
|
+
import { TableState, type HeaderSelectCtx, type RowCtx, type RowSelectCtx, type TableProps } from './table.svelte.js'
|
|
22
22
|
import Panel, { PanelTween } from '../panel/Panel.svelte'
|
|
23
23
|
import Column from '../column/Column.svelte'
|
|
24
|
-
import { fromProps, mounted } from '../utility.svelte.js'
|
|
24
|
+
import { assignDescriptors, fromProps, mounted } from '../utility.svelte.js'
|
|
25
25
|
import { conditional } from '../conditional.svelte.js'
|
|
26
|
-
import { ColumnState } from '../column/column.svelte.js'
|
|
26
|
+
import { ColumnState, type RowColumnCtx } from '../column/column.svelte.js'
|
|
27
27
|
import Expandable from '../expandable/Expandable.svelte'
|
|
28
28
|
import { SizeTween } from '../size-tween.svelte.js'
|
|
29
|
+
import { on } from 'svelte/events'
|
|
29
30
|
|
|
30
31
|
type T = $$Generic<Record<PropertyKey, unknown>>
|
|
31
32
|
|
|
@@ -122,7 +123,13 @@
|
|
|
122
123
|
})
|
|
123
124
|
.join('')
|
|
124
125
|
|
|
125
|
-
|
|
126
|
+
const columnStyling = columns.map(column => !column.options.style ? '' : `
|
|
127
|
+
#${table.id} .column[data-column='${column.id}'] {
|
|
128
|
+
${column.options.style}
|
|
129
|
+
}
|
|
130
|
+
`).join('')
|
|
131
|
+
|
|
132
|
+
return templateColumns + stickyLeft + columnStyling
|
|
126
133
|
})
|
|
127
134
|
|
|
128
135
|
function observeColumnWidth(node: HTMLDivElement, isHeader = false) {
|
|
@@ -223,8 +230,39 @@
|
|
|
223
230
|
// * --- CSV --- *
|
|
224
231
|
|
|
225
232
|
|
|
226
|
-
|
|
227
|
-
let
|
|
233
|
+
let expandedRow = $state([]) as T[]
|
|
234
|
+
let expandTick = false
|
|
235
|
+
function toggleExpand(item: T, value?: boolean) {
|
|
236
|
+
if(expandTick) return
|
|
237
|
+
expandTick = true
|
|
238
|
+
requestAnimationFrame(() => expandTick = false)
|
|
239
|
+
|
|
240
|
+
let indexOf = expandedRow.indexOf(item)
|
|
241
|
+
if(value === undefined) {
|
|
242
|
+
value = indexOf === -1
|
|
243
|
+
}
|
|
244
|
+
if(!value) {
|
|
245
|
+
expandedRow.splice(indexOf, 1)
|
|
246
|
+
return
|
|
247
|
+
}
|
|
248
|
+
if(table.expandable?.options.multiple === true) {
|
|
249
|
+
expandedRow.push(item)
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
expandedRow[0] = item
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function addRowColumnEvents(
|
|
257
|
+
node: HTMLTableColElement,
|
|
258
|
+
opts: ['header' | 'row' | 'statusbar', ColumnState, () => RowColumnCtx<T, any>]
|
|
259
|
+
) {
|
|
260
|
+
const [where, column, value] = opts
|
|
261
|
+
if(where !== 'row') return
|
|
262
|
+
if(column.options.onclick) {
|
|
263
|
+
$effect(() => on(node, 'click', e => column.options.onclick!(e, value())))
|
|
264
|
+
}
|
|
265
|
+
}
|
|
228
266
|
|
|
229
267
|
</script>
|
|
230
268
|
|
|
@@ -251,7 +289,8 @@
|
|
|
251
289
|
value: column.options.value?.(row),
|
|
252
290
|
isHovered: false,
|
|
253
291
|
itemState: { index: i, dragging: false, positioning: false } as ItemState<any>,
|
|
254
|
-
selected: false
|
|
292
|
+
selected: false,
|
|
293
|
+
expanded: false
|
|
255
294
|
})}
|
|
256
295
|
</td>
|
|
257
296
|
{/each}
|
|
@@ -266,19 +305,17 @@
|
|
|
266
305
|
{@html `<style>${style}</style>`}
|
|
267
306
|
</svelte:head>
|
|
268
307
|
|
|
269
|
-
{#snippet chevronSnippet(
|
|
308
|
+
{#snippet chevronSnippet(rotation: number = 0)}
|
|
270
309
|
<svg
|
|
271
|
-
class="sorting-icon"
|
|
272
|
-
class:reversed
|
|
273
310
|
xmlns="http://www.w3.org/2000/svg"
|
|
274
311
|
width="16"
|
|
275
312
|
height="16"
|
|
276
313
|
viewBox="0 0 16 16"
|
|
277
|
-
style="
|
|
314
|
+
style="transform: rotate({rotation}deg)"
|
|
278
315
|
>
|
|
279
316
|
<path
|
|
280
317
|
fill="currentColor"
|
|
281
|
-
d="M3.2
|
|
318
|
+
d="M3.2 10.26a.75.75 0 0 0 1.06.04L8 6.773l3.74 3.527a.75.75 0 1 0 1.02-1.1l-4.25-4a.75.75 0 0 0-1.02 0l-4.25 4a.75.75 0 0 0-.04 1.06"
|
|
282
319
|
></path>
|
|
283
320
|
</svg>
|
|
284
321
|
{/snippet}
|
|
@@ -295,15 +332,20 @@
|
|
|
295
332
|
{#snippet columnsSnippet(
|
|
296
333
|
renderable: (column: ColumnState) => Snippet<[arg0?: any, arg1?: any]> | undefined,
|
|
297
334
|
arg: null | ((column: ColumnState) => any[]) = null,
|
|
298
|
-
|
|
335
|
+
where: 'header' | 'row' | 'statusbar'
|
|
299
336
|
)}
|
|
337
|
+
{@const isHeader = where === 'header'}
|
|
300
338
|
{#each fixed as column, i (column)}
|
|
301
339
|
{#if !hidden.includes(column)}
|
|
302
340
|
{@const args = arg ? arg(column) : []}
|
|
303
341
|
{@const sortable = isHeader && column.options.sort && !table.options.reorderable}
|
|
304
342
|
<svelte:element
|
|
305
343
|
this={isHeader ? 'th' : 'td'}
|
|
306
|
-
class=
|
|
344
|
+
class={column.options.class ?? ''}
|
|
345
|
+
class:column={true}
|
|
346
|
+
class:sticky={true}
|
|
347
|
+
class:fixed={true}
|
|
348
|
+
use:addRowColumnEvents={[where, column, () => args[1]]}
|
|
307
349
|
data-column={column.id}
|
|
308
350
|
class:header={isHeader}
|
|
309
351
|
class:sortable
|
|
@@ -311,7 +353,9 @@
|
|
|
311
353
|
>
|
|
312
354
|
{@render renderable(column)?.(args[0], args[1])}
|
|
313
355
|
{#if isHeader && data.sortby === column.id && sortable}
|
|
314
|
-
|
|
356
|
+
<span class='sorting-icon'>
|
|
357
|
+
{@render chevronSnippet(data.sortReverse ? 0 : 180)}
|
|
358
|
+
</span>
|
|
315
359
|
{/if}
|
|
316
360
|
</svelte:element>
|
|
317
361
|
{/if}
|
|
@@ -322,7 +366,10 @@
|
|
|
322
366
|
{@const sortable = isHeader && column.options.sort && !table.options.reorderable}
|
|
323
367
|
<svelte:element
|
|
324
368
|
this={isHeader ? 'th' : 'td'}
|
|
325
|
-
class=
|
|
369
|
+
class={column.options.class ?? ''}
|
|
370
|
+
class:column={true}
|
|
371
|
+
class:sticky={true}
|
|
372
|
+
use:addRowColumnEvents={[where, column, () => args[1]]}
|
|
326
373
|
use:observeColumnWidth={isHeader}
|
|
327
374
|
data-column={column.id}
|
|
328
375
|
class:header={isHeader}
|
|
@@ -333,7 +380,9 @@
|
|
|
333
380
|
>
|
|
334
381
|
{@render renderable(column)?.(args[0], args[1])}
|
|
335
382
|
{#if isHeader && data.sortby === column.id && sortable}
|
|
336
|
-
|
|
383
|
+
<span class='sorting-icon'>
|
|
384
|
+
{@render chevronSnippet(data.sortReverse ? 0 : 180)}
|
|
385
|
+
</span>
|
|
337
386
|
{/if}
|
|
338
387
|
</svelte:element>
|
|
339
388
|
{/if}
|
|
@@ -344,8 +393,10 @@
|
|
|
344
393
|
{@const sortable = isHeader && column!.options.sort && !table.options.reorderable}
|
|
345
394
|
<svelte:element
|
|
346
395
|
this={isHeader ? 'th' : 'td'}
|
|
347
|
-
class=
|
|
396
|
+
class={column.options.class ?? ''}
|
|
397
|
+
class:column={true}
|
|
348
398
|
data-column={column.id}
|
|
399
|
+
use:addRowColumnEvents={[where, column, () => args[1]]}
|
|
349
400
|
use:observeColumnWidth={isHeader}
|
|
350
401
|
class:resizeable={isHeader && column.options.resizeable && table.options.resizeable}
|
|
351
402
|
class:sortable
|
|
@@ -353,7 +404,9 @@
|
|
|
353
404
|
>
|
|
354
405
|
{@render renderable(column)?.(args[0], args[1])}
|
|
355
406
|
{#if isHeader && data.sortby === column.id && sortable}
|
|
356
|
-
|
|
407
|
+
<span class='sorting-icon'>
|
|
408
|
+
{@render chevronSnippet(data.sortReverse ? 0 : 180)}
|
|
409
|
+
</span>
|
|
357
410
|
{/if}
|
|
358
411
|
</svelte:element>
|
|
359
412
|
{/if}
|
|
@@ -361,8 +414,34 @@
|
|
|
361
414
|
{/snippet}
|
|
362
415
|
|
|
363
416
|
{#snippet rowSnippet(item: T, itemState?: ItemState<T>)}
|
|
364
|
-
{@const
|
|
365
|
-
|
|
417
|
+
{@const index = itemState?.index ?? 0}
|
|
418
|
+
|
|
419
|
+
{@const ctx: RowCtx<T> = {
|
|
420
|
+
get index() {
|
|
421
|
+
return index
|
|
422
|
+
},
|
|
423
|
+
get isHovered() {
|
|
424
|
+
return hoveredRow === item
|
|
425
|
+
},
|
|
426
|
+
get selected() {
|
|
427
|
+
return table.selected?.includes(item)
|
|
428
|
+
},
|
|
429
|
+
set selected(value) {
|
|
430
|
+
value ?
|
|
431
|
+
table.selected!.push(item)
|
|
432
|
+
: table.selected!.splice(table.selected!.indexOf(item), 1)
|
|
433
|
+
},
|
|
434
|
+
get itemState() {
|
|
435
|
+
return itemState
|
|
436
|
+
},
|
|
437
|
+
get expanded() {
|
|
438
|
+
return expandedRow.includes(item)
|
|
439
|
+
},
|
|
440
|
+
set expanded(value) {
|
|
441
|
+
toggleExpand(item, value)
|
|
442
|
+
}
|
|
443
|
+
}}
|
|
444
|
+
|
|
366
445
|
<tr
|
|
367
446
|
aria-rowindex={index + 1}
|
|
368
447
|
data-svelte-tably={table.id}
|
|
@@ -371,19 +450,19 @@
|
|
|
371
450
|
class:hover={hoveredRow === item}
|
|
372
451
|
class:dragging={itemState?.dragging}
|
|
373
452
|
class:selected={table.selected?.includes(item)}
|
|
374
|
-
class:first={
|
|
375
|
-
class:last={
|
|
453
|
+
class:first={index === 0}
|
|
454
|
+
class:last={index === virtualization.area.length - 1}
|
|
376
455
|
{...(table.options.href ? { href: table.options.href(item) } : {})}
|
|
377
456
|
{...(itemState?.dragging ? { 'data-svelte-tably': table.id } : {})}
|
|
378
457
|
onpointerenter={() => (hoveredRow = item)}
|
|
379
458
|
onpointerleave={() => (hoveredRow = null)}
|
|
380
459
|
onclick={(e) => {
|
|
381
|
-
if (table.expandable) {
|
|
460
|
+
if (table.expandable?.options.click === true) {
|
|
382
461
|
let target = e.target as HTMLElement
|
|
383
462
|
if(['INPUT', 'TEXTAREA', 'BUTTON', 'A'].includes(target.tagName)) {
|
|
384
463
|
return
|
|
385
464
|
}
|
|
386
|
-
|
|
465
|
+
ctx.expanded = !ctx.expanded
|
|
387
466
|
}
|
|
388
467
|
}}
|
|
389
468
|
>
|
|
@@ -392,34 +471,20 @@
|
|
|
392
471
|
(column) => {
|
|
393
472
|
return [
|
|
394
473
|
item,
|
|
395
|
-
{
|
|
396
|
-
get index() {
|
|
397
|
-
return index
|
|
398
|
-
},
|
|
474
|
+
assignDescriptors({
|
|
399
475
|
get value() {
|
|
400
476
|
return column.options.value ? column.options.value(item) : undefined
|
|
401
|
-
},
|
|
402
|
-
get isHovered() {
|
|
403
|
-
return hoveredRow === item
|
|
404
|
-
},
|
|
405
|
-
get selected() {
|
|
406
|
-
return table.selected?.includes(item)
|
|
407
|
-
},
|
|
408
|
-
set selected(value) {
|
|
409
|
-
value ?
|
|
410
|
-
table.selected!.push(item)
|
|
411
|
-
: table.selected!.splice(table.selected!.indexOf(item), 1)
|
|
412
|
-
},
|
|
413
|
-
get itemState() {
|
|
414
|
-
return itemState
|
|
415
477
|
}
|
|
416
|
-
}
|
|
478
|
+
}, ctx)
|
|
417
479
|
]
|
|
418
|
-
}
|
|
480
|
+
},
|
|
481
|
+
'row'
|
|
419
482
|
)}
|
|
420
483
|
</tr>
|
|
421
484
|
|
|
422
|
-
{@const expandableTween = new SizeTween(
|
|
485
|
+
{@const expandableTween = new SizeTween(
|
|
486
|
+
() => table.expandable && expandedRow.includes(item),
|
|
487
|
+
{ min: 1, duration: table.expandable?.options.slide.duration, easing: table.expandable?.options.slide.easing })}
|
|
423
488
|
{#if expandableTween.current > 0}
|
|
424
489
|
<tr class='expandable' style='height: {expandableTween.current}px'>
|
|
425
490
|
<td
|
|
@@ -428,13 +493,9 @@
|
|
|
428
493
|
>
|
|
429
494
|
<div
|
|
430
495
|
bind:offsetHeight={expandableTween.size}
|
|
431
|
-
style='width: {tbody.width -
|
|
496
|
+
style='width: {tbody.width - 3}px'
|
|
432
497
|
>
|
|
433
|
-
{@render table.expandable!.snippets.content?.(item,
|
|
434
|
-
close() {
|
|
435
|
-
expandedRow = undefined
|
|
436
|
-
}
|
|
437
|
-
})}
|
|
498
|
+
{@render table.expandable!.snippets.content?.(item, ctx)}
|
|
438
499
|
</div>
|
|
439
500
|
</td>
|
|
440
501
|
</tr>
|
|
@@ -447,16 +508,18 @@
|
|
|
447
508
|
style='--t: {virtualization.virtualTop}px; --b: {virtualization.virtualBottom}px;'
|
|
448
509
|
aria-rowcount={data.current.length}
|
|
449
510
|
>
|
|
450
|
-
|
|
451
|
-
{
|
|
452
|
-
(
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
511
|
+
{#if columns.some(v => v.snippets.header)}
|
|
512
|
+
<thead class='headers' bind:this={elements.headers}>
|
|
513
|
+
{@render columnsSnippet(
|
|
514
|
+
(column) => column.snippets.header,
|
|
515
|
+
() => [{
|
|
516
|
+
get header() { return true },
|
|
517
|
+
get data() { return data.current }
|
|
518
|
+
}],
|
|
519
|
+
'header'
|
|
520
|
+
)}
|
|
521
|
+
</thead>
|
|
522
|
+
{/if}
|
|
460
523
|
|
|
461
524
|
<tbody
|
|
462
525
|
class='content'
|
|
@@ -479,22 +542,25 @@
|
|
|
479
542
|
}
|
|
480
543
|
})}
|
|
481
544
|
{:else}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
545
|
+
{#each virtualization.area as item, i (item)}
|
|
546
|
+
{@render rowSnippet(item, { index: i + virtualization.topIndex } as ItemState)}
|
|
547
|
+
{/each}
|
|
485
548
|
{/if}
|
|
486
549
|
</tbody>
|
|
487
550
|
|
|
488
|
-
|
|
489
|
-
<
|
|
490
|
-
|
|
491
|
-
(
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
551
|
+
{#if columns.some(v => v.snippets.statusbar)}
|
|
552
|
+
<tfoot class='statusbar' bind:this={elements.statusbar}>
|
|
553
|
+
<tr>
|
|
554
|
+
{@render columnsSnippet(
|
|
555
|
+
(column) => column.snippets.statusbar,
|
|
556
|
+
() => [{
|
|
557
|
+
get data() { return data.current }
|
|
558
|
+
}],
|
|
559
|
+
'statusbar'
|
|
560
|
+
)}
|
|
561
|
+
</tr>
|
|
562
|
+
</tfoot>
|
|
563
|
+
{/if}
|
|
498
564
|
|
|
499
565
|
<caption
|
|
500
566
|
class='panel'
|
|
@@ -532,20 +598,25 @@
|
|
|
532
598
|
<input type='checkbox' bind:checked={ctx.isSelected} />
|
|
533
599
|
{/snippet}
|
|
534
600
|
|
|
535
|
-
{#if table.options.select || table.options.reorderable}
|
|
601
|
+
{#if table.options.select || table.options.reorderable || table.expandable}
|
|
536
602
|
{@const { select, reorderable } = table.options}
|
|
603
|
+
{@const expandable = table.expandable}
|
|
537
604
|
{@const {
|
|
538
605
|
show = 'hover',
|
|
539
606
|
style = 'column',
|
|
540
607
|
rowSnippet = rowSelected,
|
|
541
608
|
headerSnippet = headerSelected
|
|
542
609
|
} = typeof select === 'boolean' ? {} : select}
|
|
543
|
-
{#if show !== 'never' || reorderable}
|
|
610
|
+
{#if show !== 'never' || reorderable || expandable?.options.chevron !== 'never'}
|
|
544
611
|
<Column
|
|
545
612
|
id='__fixed'
|
|
546
613
|
{table}
|
|
547
614
|
fixed
|
|
548
|
-
width={Math.max(56,
|
|
615
|
+
width={Math.max(56, 0
|
|
616
|
+
+ (select && show !== 'never' ? 34 : 0)
|
|
617
|
+
+ (reorderable ? 34 : 0)
|
|
618
|
+
+ (expandable?.options.chevron !== 'never' ? 34 : 0)
|
|
619
|
+
)}
|
|
549
620
|
resizeable={false}
|
|
550
621
|
>
|
|
551
622
|
{#snippet header()}
|
|
@@ -580,14 +651,14 @@
|
|
|
580
651
|
{/snippet}
|
|
581
652
|
{#snippet row(item, row)}
|
|
582
653
|
<div class='__fixed'>
|
|
583
|
-
{#if reorderable}
|
|
654
|
+
{#if reorderable && row.itemState}
|
|
584
655
|
<span style='width: 16px; display: flex; align-items: center;' use:row.itemState.handle>
|
|
585
|
-
{#if (row.isHovered && !row.itemState
|
|
656
|
+
{#if (row.isHovered && !row.itemState.area.isTarget) || row.itemState.dragging}
|
|
586
657
|
{@render dragSnippet()}
|
|
587
658
|
{/if}
|
|
588
659
|
</span>
|
|
589
660
|
{/if}
|
|
590
|
-
{#if select && (row.selected || show === 'always' || (row.isHovered && show === 'hover'))}
|
|
661
|
+
{#if select && (row.selected || show === 'always' || (row.isHovered && show === 'hover') || row.expanded)}
|
|
591
662
|
{@render rowSnippet({
|
|
592
663
|
get isSelected() {
|
|
593
664
|
return row.selected
|
|
@@ -606,6 +677,11 @@
|
|
|
606
677
|
}
|
|
607
678
|
})}
|
|
608
679
|
{/if}
|
|
680
|
+
{#if expandable && (row.expanded || expandable.options.chevron === 'always' || (row.isHovered && expandable.options.chevron === 'hover'))}
|
|
681
|
+
<button class='expand-row' onclick={() => row.expanded = !row.expanded}>
|
|
682
|
+
{@render chevronSnippet(row.expanded ? 180 : 90)}
|
|
683
|
+
</button>
|
|
684
|
+
{/if}
|
|
609
685
|
</div>
|
|
610
686
|
{/snippet}
|
|
611
687
|
</Column>
|
|
@@ -646,12 +722,30 @@
|
|
|
646
722
|
> div {
|
|
647
723
|
position: absolute;
|
|
648
724
|
overflow: auto;
|
|
649
|
-
top:
|
|
725
|
+
top: -1.5px;
|
|
650
726
|
left: 0;
|
|
651
727
|
}
|
|
652
728
|
}
|
|
653
729
|
}
|
|
654
730
|
|
|
731
|
+
.expand-row {
|
|
732
|
+
display: flex;
|
|
733
|
+
justify-content: center;
|
|
734
|
+
align-items: center;
|
|
735
|
+
padding: 0;
|
|
736
|
+
outline: none;
|
|
737
|
+
border: none;
|
|
738
|
+
cursor: pointer;
|
|
739
|
+
background-color: transparent;
|
|
740
|
+
color: inherit;
|
|
741
|
+
width: 22px;
|
|
742
|
+
height: 100%;
|
|
743
|
+
|
|
744
|
+
> svg {
|
|
745
|
+
transition: transform 0.15s ease;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
655
749
|
caption {
|
|
656
750
|
all: unset;
|
|
657
751
|
}
|
|
@@ -669,10 +763,13 @@
|
|
|
669
763
|
}
|
|
670
764
|
|
|
671
765
|
.sorting-icon {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
766
|
+
align-items: center;
|
|
767
|
+
justify-items: end;
|
|
768
|
+
margin: 0;
|
|
769
|
+
margin-left: auto;
|
|
770
|
+
margin-right: var(--tably-padding-x, 1rem);
|
|
771
|
+
> svg {
|
|
772
|
+
transition: transform 0.15s ease;
|
|
676
773
|
}
|
|
677
774
|
}
|
|
678
775
|
|
package/dist/utility.svelte.d.ts
CHANGED
|
@@ -13,4 +13,5 @@ export declare function getters<T extends AnyRecord>(obj: T): { readonly [K in k
|
|
|
13
13
|
type SetterRecord = Record<PropertyKey, [() => any, (v: any) => void]>;
|
|
14
14
|
export declare function withSetters<T extends SetterRecord>(obj: T): T;
|
|
15
15
|
export declare function fromProps<T extends AnyRecord, B extends SetterRecord>(props: T, boundProps?: B): Simplify<{ [K in keyof B]: ReturnType<B[K][0]>; } & { readonly [K in keyof T]: T[K]; }>;
|
|
16
|
+
export declare function assignDescriptors<T extends AnyRecord, B extends AnyRecord>(target: T, source: B): T & B;
|
|
16
17
|
export {};
|
package/dist/utility.svelte.js
CHANGED
|
@@ -66,3 +66,15 @@ export function fromProps(props, boundProps) {
|
|
|
66
66
|
...withSetters(boundProps ?? {})
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
+
export function assignDescriptors(target, source) {
|
|
70
|
+
for (const key of Object.keys(source)) {
|
|
71
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
72
|
+
if (descriptor) {
|
|
73
|
+
Object.defineProperty(target, key, descriptor);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
target[key] = source[key]; // Copy regular values if descriptor is missing
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return target;
|
|
80
|
+
}
|