svelte-tably 1.0.0-next.3 → 1.0.0-next.5

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 CHANGED
@@ -23,52 +23,68 @@ A high performant dynamic table
23
23
 
24
24
  ### Usage Notes
25
25
 
26
- Simple example.
27
-
28
- Create a state for your data and a state for your active panel:
29
-
30
- ```markdown
26
+ ```html
31
27
  <script lang='ts'>
32
- import { Table } from '$lib/index.js'
28
+ import Table from 'svelte-tably'
33
29
 
34
- const data = $state([
35
- { name: 'John Doe', age: 30, email: 'johndoe@example.com' },
36
- { name: 'Jane Doe', age: 25, email: 'janedoe@example.com' },
37
- ])
30
+ const data = $state([
31
+ { name: 'John Doe', age: 30, email: 'johndoe@example.com' },
32
+ { name: 'Jane Doe', age: 25, email: 'janedoe@example.com' },
33
+ ])
34
+
35
+ let activePanel = $state('columns') as string | undefined
38
36
  </script>
39
37
 
40
- <Table {data}>
41
- <Table.Name>
42
- {#snippet header()}
43
- Name
44
- {/snippet}
45
- {#snippet row(item)}
46
- {item.name}
47
- {/snippet}
48
- </Table.Name>
49
- <Table.Age>
50
- {#snippet header()}
51
- Age
52
- {/snippet}
53
- {#snippet row(item)}
54
- {item.age}
55
- {/snippet}
56
- </Table.Age>
57
- <Table.Email>
58
- {#snippet header()}
59
- Email
60
- {/snippet}
61
- {#snippet row(item)}
62
- {item.email}
38
+ <Table {data} panel={activePanel}>
39
+ {#snippet content({ Column, Panel, state, data })}
40
+ <Column id='name' sticky>
41
+ {#snippet header()}
42
+ Name
43
+ {/snippet}
44
+ {#snippet row(row)}
45
+ {row.name}
46
+ {/snippet}
47
+
48
+ <!-- Optional per column. -->
49
+ {#snippet statusbar()}
50
+ {data.length}
51
+ {/snippet}
52
+ </Column>
53
+ <Column ...>
54
+ ...
55
+ </Column>
56
+ <!-- If you want to sort/filter a virtual value, that does not exist in the data -->
57
+ <Column id='virtual' value={row => row.age > 18}>
58
+ ...
59
+ {#snippet row(row, virtual)}
60
+ {virtual ? 'Adult' : 'Adolescent'}
61
+ {/snippet}
62
+ ...
63
+ </Column>
64
+
65
+ <Panel id='columns'>
66
+ <!-- Anything you might like -->
67
+ </Panel>
68
+ <Panel ...>
69
+ ...
70
+ </Panel>
63
71
  {/snippet}
64
- </Table.Email>
65
72
  </Table>
66
73
  ```
67
74
 
68
- To create a column, simply add a new `<Table.ColumnName>` component inside the `<Table>` component. Replace `ColumnName` with the actual name of the column you want to create.
75
+ #### Styling
76
+
77
+ For quick styling
78
+
79
+ | CSS Variable | Description | Default |
80
+ | - | - | - |
81
+ | --tably-bg | background-color | `hsl(0, 0%, 100%)` |
82
+ | --tably-color | color | `hsl(0, 0%, 0%)` |
83
+ | --tably-border | border | `hsl(0, 0%, 90%)` |
84
+ | --tably-padding-y | Padding above/below each column | `.5rem` |
85
+ | --tably-padding-x | Padding left of each column | `1rem` |
86
+ | --tably-radius | Table radius | `.25rem` |
87
+
88
+ Advanced styling can be done via `:global .svelte-tably`
69
89
 
70
- Inside the column component, you need to define three snippets:
71
90
 
72
- * `header`: the content of the column header
73
- * `row`: the content of each row in the column
74
- * `statusbar`: (optional) the content of the status bar for the column
@@ -13,7 +13,7 @@
13
13
  export interface Column<T = unknown, V = unknown> {
14
14
  header: Snippet
15
15
  row: Snippet<[item: T, value?: V]>
16
- statusbar?: Snippet<[data: T[]]>
16
+ statusbar?: Snippet
17
17
 
18
18
  /** Default options for initial table */
19
19
  defaults: {
@@ -30,7 +30,7 @@
30
30
 
31
31
  </script>
32
32
 
33
- <script lang='ts' generics='T extends Record<PropertyKey, any>, V'>
33
+ <script lang='ts' generics='T extends Record<PropertyKey, any>, V = unknown'>
34
34
 
35
35
  import { onDestroy, type Snippet } from 'svelte'
36
36
  import { getTableState } from './Table.svelte'
@@ -40,6 +40,8 @@
40
40
  row: Column<T, V>['row']
41
41
  statusbar?: Column<T, V>['statusbar']
42
42
 
43
+ id: string
44
+
43
45
  // options
44
46
  sticky?: boolean
45
47
  sort?: boolean
@@ -49,17 +51,14 @@
49
51
  }
50
52
 
51
53
  let {
52
- header, row, statusbar,
54
+ header, row, statusbar, id,
53
55
 
54
56
  sticky = false,
55
57
  sort = false,
56
58
  show = true,
57
59
 
58
- value, sorting,
59
-
60
- ...rest
60
+ value, sorting
61
61
  }: Props = $props()
62
- const key = (rest as unknown as { __key: string }).__key
63
62
 
64
63
  const column: Column<T, V> = $state({
65
64
  header,
@@ -77,10 +76,10 @@
77
76
  })
78
77
 
79
78
  const table = getTableState()
80
- table.addColumn(key, column as Column)
79
+ table.addColumn(id, column as Column)
81
80
 
82
81
  onDestroy(() => {
83
- table.removeColumn(key)
82
+ table.removeColumn(id)
84
83
  })
85
84
 
86
85
  </script>
@@ -1,7 +1,7 @@
1
1
  export interface Column<T = unknown, V = unknown> {
2
2
  header: Snippet;
3
3
  row: Snippet<[item: T, value?: V]>;
4
- statusbar?: Snippet<[data: T[]]>;
4
+ statusbar?: Snippet;
5
5
  /** Default options for initial table */
6
6
  defaults: {
7
7
  sticky?: boolean;
@@ -15,11 +15,12 @@ export interface Column<T = unknown, V = unknown> {
15
15
  };
16
16
  }
17
17
  import { type Snippet } from 'svelte';
18
- declare class __sveltets_Render<T extends Record<PropertyKey, any>, V> {
18
+ declare class __sveltets_Render<T extends Record<PropertyKey, any>, V = unknown> {
19
19
  props(): {
20
20
  header: Column<T_1, V_1>["header"];
21
21
  row: Column<T_1, V_1>["row"];
22
22
  statusbar?: Column<T_1, V_1>["statusbar"];
23
+ id: string;
23
24
  sticky?: boolean;
24
25
  sort?: boolean;
25
26
  show?: boolean;
@@ -32,10 +33,10 @@ declare class __sveltets_Render<T extends Record<PropertyKey, any>, V> {
32
33
  exports(): {};
33
34
  }
34
35
  interface $$IsomorphicComponent {
35
- new <T extends Record<PropertyKey, any>, V>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T, V>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T, V>['props']>, ReturnType<__sveltets_Render<T, V>['events']>, ReturnType<__sveltets_Render<T, V>['slots']>> & {
36
+ new <T extends Record<PropertyKey, any>, V = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T, V>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T, V>['props']>, ReturnType<__sveltets_Render<T, V>['events']>, ReturnType<__sveltets_Render<T, V>['slots']>> & {
36
37
  $$bindings?: ReturnType<__sveltets_Render<T, V>['bindings']>;
37
38
  } & ReturnType<__sveltets_Render<T, V>['exports']>;
38
- <T extends Record<PropertyKey, any>, V>(internal: unknown, props: ReturnType<__sveltets_Render<T, V>['props']> & {}): ReturnType<__sveltets_Render<T, V>['exports']>;
39
+ <T extends Record<PropertyKey, any>, V = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<T, V>['props']> & {}): ReturnType<__sveltets_Render<T, V>['exports']>;
39
40
  z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
40
41
  }
41
42
  /**
@@ -46,5 +47,5 @@ interface $$IsomorphicComponent {
46
47
  * <Component />
47
48
  */
48
49
  declare const Column: $$IsomorphicComponent;
49
- type Column<T extends Record<PropertyKey, any>, V> = InstanceType<typeof Column<T, V>>;
50
+ type Column<T extends Record<PropertyKey, any>, V = unknown> = InstanceType<typeof Column<T, V>>;
50
51
  export default Column;
@@ -13,7 +13,7 @@
13
13
  export interface Panel {
14
14
  /** A darkened backdrop? */
15
15
  backdrop: boolean
16
- content: Snippet<[table: TableState]>
16
+ content: Snippet
17
17
  }
18
18
 
19
19
  export class PanelTween {
@@ -29,9 +29,9 @@
29
29
  this.#tween.set(value).then(() => this.transitioning = false)
30
30
  }
31
31
 
32
- constructor(cb: () => string | undefined) {
32
+ constructor(cb: () => string | undefined, added = 0) {
33
33
  $effect.pre(() => {
34
- this.target = cb() ? this.width : 0
34
+ this.target = cb() ? this.width + added : 0
35
35
  })
36
36
  }
37
37
  }
@@ -46,28 +46,29 @@
46
46
  import { sineInOut } from 'svelte/easing'
47
47
 
48
48
  interface Props {
49
+ id: string
50
+
49
51
  /** A darkened backdrop? */
50
52
  backdrop?: boolean
51
- children: Snippet<[table: TableState]>
53
+ children: Snippet
52
54
  }
53
55
 
54
56
  let {
55
57
  backdrop = true,
56
58
  children,
57
- ...rest
59
+ id
58
60
  }: Props = $props()
59
- const key = (rest as unknown as { __key: string }).__key
60
-
61
+
61
62
  const panel: Panel = $state({
62
63
  backdrop,
63
64
  content: children
64
65
  })
65
66
 
66
67
  const table = getTableState()
67
- table.panels[key] = panel
68
+ table.panels[id] = panel
68
69
 
69
70
  onDestroy(() => {
70
- delete table.panels[key]
71
+ delete table.panels[id]
71
72
  })
72
73
 
73
74
  </script>
@@ -1,7 +1,7 @@
1
1
  export interface Panel {
2
2
  /** A darkened backdrop? */
3
3
  backdrop: boolean;
4
- content: Snippet<[table: TableState]>;
4
+ content: Snippet;
5
5
  }
6
6
  export declare class PanelTween {
7
7
  #private;
@@ -10,14 +10,14 @@ export declare class PanelTween {
10
10
  /** bind:clientWidth */
11
11
  width: number;
12
12
  set target(value: number);
13
- constructor(cb: () => string | undefined);
13
+ constructor(cb: () => string | undefined, added?: number);
14
14
  }
15
15
  import { type Snippet } from 'svelte';
16
- import { type TableState } from './Table.svelte';
17
16
  interface Props {
17
+ id: string;
18
18
  /** A darkened backdrop? */
19
19
  backdrop?: boolean;
20
- children: Snippet<[table: TableState]>;
20
+ children: Snippet;
21
21
  }
22
22
  /**
23
23
  * This is a description, \
@@ -11,8 +11,8 @@
11
11
  <script module lang='ts'>
12
12
 
13
13
  export interface TableState<T extends Record<PropertyKey, any> = Record<PropertyKey, any>> {
14
- columns: Record<string, Column<T, unknown>>
15
- panels: Record<string, Panel>
14
+ columns: Record<string, TColumn<T, unknown>>
15
+ panels: Record<string, TPanel>
16
16
  sortby?: string
17
17
  positions: {
18
18
  sticky: string[]
@@ -21,7 +21,7 @@
21
21
  toggle(key: string): void
22
22
  }
23
23
  readonly data: T[]
24
- addColumn(key: string, options: Column<T, unknown>): void
24
+ addColumn(key: string, options: TColumn<T, unknown>): void
25
25
  removeColumn(key: string): void
26
26
  }
27
27
 
@@ -34,28 +34,30 @@
34
34
  <script lang='ts' generics='T extends Record<PropertyKey, unknown>'>
35
35
 
36
36
  import { getContext, setContext, untrack, type Snippet } from 'svelte'
37
- import { type Column } from './Column.svelte'
38
- import { PanelTween, type Panel } from './Panel.svelte'
37
+ import Column, { type Column as TColumn } from './Column.svelte'
38
+ import Panel, { PanelTween, type Panel as TPanel } from './Panel.svelte'
39
39
  import { fly } from 'svelte/transition'
40
40
  import { sineInOut } from 'svelte/easing'
41
41
 
42
42
  interface Props {
43
- children?: Snippet
43
+ content: Snippet<[context: { Column: typeof Column<T>, Panel: typeof Panel, readonly state: TableState<T>, readonly data: T[] }]>
44
+
44
45
  panel?: string
45
46
  data?: T[]
46
47
  id?: string
47
48
  }
48
49
 
49
50
  let {
50
- children,
51
- panel,
51
+ content,
52
+
53
+ panel = $bindable(),
52
54
  data: _data = [],
53
55
  id = Array.from({length: 12}, () => String.fromCharCode(Math.floor(Math.random() * 26) + 97)).join('')
54
56
  }: Props = $props()
55
57
 
56
58
  const data = $derived(_data.toSorted())
57
59
 
58
- const elements = $state({}) as Record<'headers' | 'statusbar' | 'content', HTMLElement>
60
+ const elements = $state({}) as Record<'headers' | 'statusbar' | 'rows', HTMLElement>
59
61
 
60
62
 
61
63
  // * --- Virtualization --- *
@@ -66,12 +68,10 @@
66
68
  let renderItemLength = $derived(Math.ceil(Math.max(30, viewportHeight / (_heightPerItem / 3))))
67
69
 
68
70
  let heightPerItem = $derived.by(() => {
69
- if(!elements.content)
71
+ data
72
+ if(!elements.rows)
70
73
  return 8
71
- const rows = elements.content.querySelectorAll('.row') as NodeListOf<HTMLDivElement>
72
- const result = ((
73
- rows[rows.length - 1].offsetTop - rows[0].offsetTop
74
- ) / rows.length)
74
+ const result = elements.rows.scrollHeight / elements.rows.childNodes.length
75
75
  _heightPerItem = result
76
76
  return result
77
77
  })
@@ -80,17 +80,17 @@
80
80
  let spacing = untrack(() => (renderItemLength/3)) * heightPerItem
81
81
  let scroll = scrollTop - spacing
82
82
  let virtualTop = Math.max(scroll, 0)
83
- virtualTop -= virtualTop % untrack(() => heightPerItem)
83
+ virtualTop -= virtualTop % heightPerItem
84
84
  return virtualTop
85
85
  })
86
86
  let virtualBottom = $derived.by(() => {
87
- const virtualBottom = (untrack(() => heightPerItem) * data.length) - virtualTop
87
+ const virtualBottom = (heightPerItem * data.length) - virtualTop
88
88
  return virtualBottom
89
89
  })
90
90
 
91
91
  /** The area of data that is rendered */
92
92
  const area = $derived.by(() => {
93
- const index = (virtualTop / untrack(() => heightPerItem)) || 0
93
+ const index = (virtualTop / heightPerItem) || 0
94
94
  return data.slice(
95
95
  index,
96
96
  index + untrack(() => renderItemLength)
@@ -142,7 +142,7 @@
142
142
 
143
143
  // * --- *
144
144
 
145
- const panelTween = new PanelTween(() => panel)
145
+ const panelTween = new PanelTween(() => panel, 24)
146
146
 
147
147
  /** Order of columns */
148
148
  const columns = $derived([...table.positions.sticky, ...table.positions.scroll].filter(key => !table.positions.hidden.includes(key)))
@@ -187,7 +187,7 @@
187
187
  </svelte:head>
188
188
 
189
189
  {#snippet columnsSnippet(
190
- renderable: (column: string) => Snippet<[arg0?: any, arg1?: any, arg2?: any, arg3?: any]> | undefined,
190
+ renderable: (column: string) => Snippet<[arg0?: any, arg1?: any]> | undefined,
191
191
  arg: null | ((column: string) => any[]) = null,
192
192
  isHeader = false
193
193
  )}
@@ -196,7 +196,7 @@
196
196
  {@const args = arg ? arg(column) : []}
197
197
  {@const props = isHeader ? { 'data-column': column } : {}}
198
198
  <div class='column sticky' {...props} use:observe={isHeader} class:border={i == table.positions.sticky.length - 1}>
199
- {@render renderable(column)?.(args[0], args[1], args[2], args[3])}
199
+ {@render renderable(column)?.(args[0], args[1])}
200
200
  </div>
201
201
  {/if}
202
202
  {/each}
@@ -205,22 +205,22 @@
205
205
  {@const args = arg ? arg(column) : []}
206
206
  {@const props = isHeader ? { 'data-column': column } : {}}
207
207
  <div class='column' {...props} use:observe={isHeader}>
208
- {@render renderable(column)?.(args[0], args[1], args[2], args[3])}
208
+ {@render renderable(column)?.(args[0], args[1])}
209
209
  </div>
210
210
  {/if}
211
211
  {/each}
212
212
  {/snippet}
213
213
 
214
- <div id={id} class='table'>
214
+ <div id={id} class='table svelte-tably'>
215
215
 
216
216
  <div class='headers' bind:this={elements.headers}>
217
217
  {@render columnsSnippet((column) => table.columns[column]?.header, null, true)}
218
218
  </div>
219
219
 
220
- <div class='content' {onscroll} bind:clientHeight={viewportHeight} bind:this={elements.content}>
220
+ <div class='content' {onscroll} bind:clientHeight={viewportHeight}>
221
221
  <div class='virtual top' style='height: {virtualTop}px'></div>
222
222
 
223
- <div class="rows">
223
+ <div class='rows' bind:this={elements.rows}>
224
224
  {#each area as item, i (item)}
225
225
  <div class='row'>
226
226
  {@render columnsSnippet(
@@ -239,25 +239,32 @@
239
239
  </div>
240
240
 
241
241
  <div class='statusbar' bind:this={elements.statusbar}>
242
- {@render columnsSnippet((column) => table.columns[column]?.statusbar, () => [data])}
242
+ {@render columnsSnippet((column) => table.columns[column]?.statusbar)}
243
243
  </div>
244
244
 
245
- <div class='panel' style='width: {panelTween.current + 30}px;' style:overflow={panelTween.transitioning ? 'hidden' : 'auto'}>
245
+ <div class='panel' style='width: {(panelTween.current)}px;' style:overflow={panelTween.transitioning ? 'hidden' : 'auto'}>
246
246
  {#if panel && panel in table.panels}
247
247
  <div
248
- class="panel-content"
248
+ class='panel-content'
249
249
  bind:clientWidth={panelTween.width}
250
250
  in:fly={{ x: 100, easing: sineInOut, duration:300 }}
251
251
  out:fly={{ x:100, duration:200, easing: sineInOut }}
252
252
  >
253
- {@render table.panels[panel].content(table as TableState)}
253
+ {@render table.panels[panel].content()}
254
254
  </div>
255
255
  {/if}
256
256
  </div>
257
+ <button
258
+ class='backdrop'
259
+ aria-label='Panel backdrop'
260
+ tabindex='-1'
261
+ aria-hidden={panel && table.panels[panel]?.backdrop ? false : true}
262
+ onclick={() => panel = undefined}
263
+ ></button>
257
264
  </div>
258
265
 
259
266
 
260
- {@render children?.()}
267
+ {@render content?.({ Column, Panel, get state() { return table }, get data() { return data } })}
261
268
 
262
269
 
263
270
 
@@ -266,13 +273,47 @@
266
273
 
267
274
  .table, .table * {
268
275
  box-sizing: border-box;
276
+ background-color: inherit;
277
+ }
278
+
279
+ .backdrop {
280
+ position: absolute;
281
+ left: 0px;
282
+ top: 0px;
283
+ bottom: 0px;
284
+ right: 0px;
285
+ background-color: hsla(0, 0%, 0%, .3);
286
+ z-index: 3;
287
+ opacity: 1;
288
+ transition: .15s ease;
289
+ border: none;
290
+ outline: none;
291
+ cursor: pointer;
292
+
293
+ &[aria-hidden='true'] {
294
+ opacity: 0;
295
+ pointer-events: none;
296
+ }
297
+ }
298
+
299
+ .headers, .statusbar {
300
+ /* So that the scrollbar doesn't cause the headers/statusbar to shift */
301
+ padding-right: 11px;
302
+ }
303
+
304
+ .table {
305
+ color: var(--tably-color, hsl(0, 0%, 0%));
306
+ background-color: var(--tably-bg, hsl(0, 0%, 100%));
307
+
308
+ --tably-padding-x: 1rem;
309
+ --tably-padding-y: .5rem;
310
+ --tably-radius: .25rem;
269
311
  }
270
312
 
271
313
  .sticky {
272
314
  position: sticky;
273
315
  left: 0px;
274
316
  /* right: 100px; */
275
- background-color: var(--tably-bg, hsl(0, 0%, 100%));
276
317
  z-index: 1;
277
318
  }
278
319
 
@@ -284,30 +325,25 @@
284
325
  border-right: 1px solid var(--tably-border, hsl(0, 0%, 90%));
285
326
  resize: horizontal;
286
327
  overflow: hidden;
287
- padding: var(--padding-y) 0;
328
+ padding: var(--tably-padding-y) 0;
288
329
  }
289
330
 
290
331
  .table {
291
- --panel: 250px;
292
- --padding-x: 1rem;
293
- --padding-y: .5rem;
294
- --gap: .25rem;
295
- --header-height: 2.5rem;
296
-
297
332
  display: grid;
298
333
  height: 100%;
334
+ position: relative;
299
335
 
300
336
  grid-template-areas:
301
- "headers panel"
302
- "rows panel"
303
- "statusbar panel"
337
+ 'headers panel'
338
+ 'rows panel'
339
+ 'statusbar panel'
304
340
  ;
305
341
 
306
342
  grid-template-columns: auto min-content;
307
343
  grid-template-rows: auto 1fr auto;
308
344
 
309
345
  border: 1px solid var(--tably-border, hsl(0, 0%, 90%));
310
- border-radius: .25rem;
346
+ border-radius: var(--tably-radius, .25rem);
311
347
 
312
348
  max-height: 100%;
313
349
  }
@@ -320,7 +356,6 @@
320
356
 
321
357
  .headers > .column {
322
358
  width: auto !important;
323
- background-color: var(--tably-bg, hsl(0, 0%, 100%));
324
359
  border-bottom: 1px solid var(--tably-border, hsl(0, 0%, 90%));
325
360
  }
326
361
 
@@ -346,9 +381,8 @@
346
381
  }
347
382
 
348
383
  .statusbar > .column {
349
- background-color: var(--tably-bg-statusbar, hsl(0, 0%, 99%));
350
384
  border-top: 1px solid var(--tably-border, hsl(0, 0%, 90%));
351
- padding: calc(var(--padding-y) / 2) 0;
385
+ padding: calc(var(--tably-padding-y) / 2) 0;
352
386
  }
353
387
 
354
388
  .headers, .row, .statusbar {
@@ -358,36 +392,36 @@
358
392
 
359
393
  & > .column {
360
394
  display: flex;
361
- padding-left: var(--padding-x);
395
+ padding-left: var(--tably-padding-x);
362
396
  overflow: hidden;
363
397
  }
364
398
 
365
399
  & > *:last-child {
366
400
  width: 100%;
367
- padding-right: var(--padding-x);
401
+ padding-right: var(--tably-padding-x);
368
402
  }
369
403
  }
370
404
 
371
- /* .row:nth-child(1) > * {
372
- padding-top: calc(var(--padding-y) + var(--gap));
405
+ .row:first-child > * {
406
+ padding-top: calc(var(--tably-padding-y) + calc(var(--tably-padding-y) / 2));
407
+ }
408
+ .row:last-child > * {
409
+ padding-bottom: calc(var(--tably-padding-y) + calc(var(--tably-padding-y) / 2));
373
410
  }
374
- .row:nth-last-child(1) > * {
375
- padding-bottom: calc(var(--padding-y) + var(--gap));
376
- } */
377
411
 
378
412
  .row > * {
379
- padding: var(--gap) 0;
413
+ padding: calc(var(--tably-padding-y) / 2) 0;
380
414
  }
381
415
 
382
416
  .panel {
383
417
  position: relative;
384
418
  grid-area: panel;
385
419
  height: 100%;
386
- background-color: var(--tably-bg, hsl(0, 0%, 100%));
387
420
 
388
421
  border-left: 1px solid var(--tably-border, hsl(0, 0%, 90%));
389
422
  scrollbar-gutter: stable both-edges;
390
423
  scrollbar-width: thin;
424
+ z-index: 4;
391
425
 
392
426
  > .panel-content {
393
427
  position: absolute;
@@ -395,7 +429,7 @@
395
429
  right: 0;
396
430
  width: min-content;
397
431
  overflow: auto;
398
- padding: var(--padding-y) 0;
432
+ padding: var(--tably-padding-y) 0;
399
433
  }
400
434
  }
401
435
 
@@ -1,6 +1,7 @@
1
+ import { SvelteComponent } from "svelte";
1
2
  export interface TableState<T extends Record<PropertyKey, any> = Record<PropertyKey, any>> {
2
- columns: Record<string, Column<T, unknown>>;
3
- panels: Record<string, Panel>;
3
+ columns: Record<string, TColumn<T, unknown>>;
4
+ panels: Record<string, TPanel>;
4
5
  sortby?: string;
5
6
  positions: {
6
7
  sticky: string[];
@@ -9,23 +10,64 @@ export interface TableState<T extends Record<PropertyKey, any> = Record<Property
9
10
  toggle(key: string): void;
10
11
  };
11
12
  readonly data: T[];
12
- addColumn(key: string, options: Column<T, unknown>): void;
13
+ addColumn(key: string, options: TColumn<T, unknown>): void;
13
14
  removeColumn(key: string): void;
14
15
  }
15
16
  export declare function getTableState<T extends Record<PropertyKey, any> = Record<PropertyKey, any>>(): TableState<T>;
16
17
  import { type Snippet } from 'svelte';
17
- import { type Column } from './Column.svelte';
18
- import { type Panel } from './Panel.svelte';
18
+ import Column, { type Column as TColumn } from './Column.svelte';
19
+ import Panel, { type Panel as TPanel } from './Panel.svelte';
19
20
  declare class __sveltets_Render<T extends Record<PropertyKey, unknown>> {
20
21
  props(): {
21
- children?: Snippet;
22
+ content: Snippet<[context: {
23
+ Column: {
24
+ (internal: unknown, props: {
25
+ header: Column<T_1, V>["header"];
26
+ row: Column<T_1, V>["row"];
27
+ statusbar?: Column<T_1, V>["statusbar"];
28
+ id: string;
29
+ sticky?: boolean;
30
+ sort?: boolean;
31
+ show?: boolean;
32
+ value?: Column<T_1, V>["options"]["value"];
33
+ sorting?: Column<T_1, V>["options"]["sorting"];
34
+ }): {};
35
+ new (options: import("svelte").ComponentConstructorOptions<{
36
+ header: Column<T_1, V>["header"];
37
+ row: Column<T_1, V>["row"];
38
+ statusbar?: Column<T_1, V>["statusbar"];
39
+ id: string;
40
+ sticky?: boolean;
41
+ sort?: boolean;
42
+ show?: boolean;
43
+ value?: Column<T_1, V>["options"]["value"];
44
+ sorting?: Column<T_1, V>["options"]["sorting"];
45
+ }>): SvelteComponent<{
46
+ header: Column<T_1, V>["header"];
47
+ row: Column<T_1, V>["row"];
48
+ statusbar?: Column<T_1, V>["statusbar"];
49
+ id: string;
50
+ sticky?: boolean;
51
+ sort?: boolean;
52
+ show?: boolean;
53
+ value?: Column<T_1, V>["options"]["value"];
54
+ sorting?: Column<T_1, V>["options"]["sorting"];
55
+ }, {}, {}> & {
56
+ $$bindings?: ReturnType<() => "">;
57
+ };
58
+ z_$$bindings?: ReturnType<() => "">;
59
+ };
60
+ Panel: typeof Panel;
61
+ readonly state: TableState<T>;
62
+ readonly data: T[];
63
+ }]>;
22
64
  panel?: string;
23
65
  data?: T[] | undefined;
24
66
  id?: string;
25
67
  };
26
68
  events(): {};
27
69
  slots(): {};
28
- bindings(): "";
70
+ bindings(): "panel";
29
71
  exports(): {};
30
72
  }
31
73
  interface $$IsomorphicComponent {
@@ -1,12 +1 @@
1
- import { default as _Table } from './Table.svelte';
2
- import Column from './Column.svelte';
3
- import { default as _Panel } from './Panel.svelte';
4
- declare const LATIN: readonly ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
5
- type Capital = typeof LATIN[number];
6
- declare const Table: typeof _Table & {
7
- [key: `${Capital}${string}`]: typeof Column;
8
- };
9
- declare const Panel: {
10
- [key: `${Capital}${string}`]: typeof _Panel;
11
- };
12
- export { Table, Panel };
1
+ export { default as Table } from './Table.svelte';
@@ -1,31 +1 @@
1
- import { default as _Table } from './Table.svelte';
2
- import Column from './Column.svelte';
3
- import { default as _Panel } from './Panel.svelte';
4
- const LATIN = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
5
- const Table = new Proxy(_Table, {
6
- get(target, p, receiver) {
7
- if (typeof p !== 'string' || !LATIN.includes(p[0])) {
8
- return Reflect.get(target, p, receiver);
9
- }
10
- return new Proxy(Column, {
11
- apply(_, __, [anchor, props]) {
12
- Object.assign(props, { __key: p });
13
- return Column(anchor, props);
14
- },
15
- });
16
- }
17
- });
18
- const Panel = new Proxy(_Panel, {
19
- get(target, p, receiver) {
20
- if (typeof p !== 'string' || !LATIN.includes(p[0])) {
21
- return Reflect.get(target, p, receiver);
22
- }
23
- return new Proxy(_Panel, {
24
- apply(_, __, [anchor, props]) {
25
- Object.assign(props, { __key: p });
26
- return _Panel(anchor, props);
27
- },
28
- });
29
- },
30
- });
31
- export { Table, Panel };
1
+ export { default as Table } from './Table.svelte';
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export * from './Table/index.js';
1
+ import { Table } from './Table/index.js';
2
+ export default Table;
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
- export * from './Table/index.js';
1
+ import { Table } from './Table/index.js';
2
+ export default Table;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-tably",
3
- "version": "1.0.0-next.3",
3
+ "version": "1.0.0-next.5",
4
4
  "repository": "github:refzlund/svelte-tably",
5
5
  "homepage": "https://github.com/Refzlund/svelte-tably",
6
6
  "bugs": {