https://github.com/refzlund/svelte-tably
A high performant dynamic table for Svelte 5
https://github.com/refzlund/svelte-tably
Last synced: about 2 months ago
JSON representation
A high performant dynamic table for Svelte 5
- Host: GitHub
- URL: https://github.com/refzlund/svelte-tably
- Owner: Refzlund
- License: mit
- Created: 2024-12-13T23:32:48.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-01-18T18:55:21.000Z (5 months ago)
- Last Synced: 2025-04-17T03:53:47.711Z (2 months ago)
- Language: Svelte
- Homepage: https://www.npmjs.com/package/svelte-tably
- Size: 97.7 KB
- Stars: 10
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Svelte Tably
Via the amazing capabilities braught to us by Svelte 5 — a performant, dynamic, flexible, feature rich table. It's as simple, or as flexible as you need it to be.
Simple example on [Svelte 5 Playground](https://svelte.dev/playground/f79124e8473546d29433a95a68440d6d?version=5.16.0)
Fledged out example on [Svelte 5 Playground](https://svelte.dev/playground/a16d71c97445455e80a55b77ec1cf915?version=5)- [x] Columns
- [x] Sticky
- [x] Show/hide
- [x] Re-order
- [x] Resize
- [x] Data manipulation
- [x] "Virtual" data
- [x] Sorting
- [x] Select
- [x] Filtering
- [x] Reorderable
- [x] Statusbar
- [x] Panels
- [x] Row context
- [x] Expandable rows
- [x] Virtual rendering
- [x] To CSV
- [x] Auto: Create columns based on dataOn top of that, the library API is extensive, so the table can meet your needs.
## Usage Notes
`bun add -D svelte-tably`
> [!NOTE]
> If you do SSR, set Node version to [20 or higher](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted#browser_compatibility)```html
import Table from 'svelte-tably'
const data = $state([
{ name: 'Giraffe', age: 26, email: '[email protected]' },
{ name: 'Shiboo', age: 21, email: '[email protected]' }
])let activePanel = $state('columns') as string | undefined
let selected = $state([]) as typeof data{#snippet content({ Column, Panel, Expandable, Row, state, table })}
r.name} filter={v => v.includes('Giraffe')}>
{#snippet header(ctx)}
Name
{/snippet}
{#snippet row(row, ctx)}
{row.name}
{/snippet}
{#snippet statusbar(ctx)}
{table.data.length}
{/snippet}
r.age} sort={(a,b) => a - b} />
{#snippet content(item, ctx)}
...
{/snippet}
{#snippet contextHeader()}
{/snippet}
{#snippet context(item, ctx)}
{/snippet}
...
{/snippet}```
### Styling
For quick styling
| CSS Variable | Description | Default |
| - | - | - |
| --tably-bg | Background color | `hsl(0, 0%, 100%)` |
| --tably-color | Text color | `hsl(0, 0%, 0%)` |
| --tably-border | Border for sticky columns and header | `hsl(0, 0%, 90%)` |
| --tably-border-grid | Border for the table-grid | `hsl(0, 0%, 98%)` |
| --tably-statusbar | background-color for the statusbar | `hsl(0, 0%, 98%)` |
| --tably-padding-y | Padding above/below each column | `.5rem` |
| --tably-padding-x | Padding left of each column | `1rem` |
| --tably-radius | Table radius | `.25rem` |> [!TIP]
> For the CSS variables, apply them to `:global(:root) { ... }`> [!NOTE]
> Advanced styling can be done via `:global(.svelte-tably)`
> `table > thead > tr > th, table > tbody > tr > td, table > tfoot > tr > td`
## Components
All components except Table are meant to be children of the `Table` component.
However, you can safely create a `Component.svelte` and use these components,
and then provide `` as a child to ``.```ts
import Table from 'svelte-tably'
```### Table
The table component.
```html
{#snippet content?({ Column, Row, Expandable, Panel, table })}
...
{/snippet}```
Where `table` is `TableState` and the rest are typed; `Component`.
| Attribute | Description | Type |
| - | - | - |
| content? | The contents of the table | `Snippet<[ctx: ContentCtx]>?` |
| | | |
| id? | The `#id` for the table | `string` |
| data | An array of objects for the table | `T[]` |
| bind:selected? | The currently selected items | `T[]` |
| bind:panel? | The currently open panel | `string` |
| filters? | An array of filters applied to the table | `((item: T) => boolean)[]` |
| reorderable? | Whether the rows can be re-ordered (via [runic-reorder](https://github.com/Refzlund/runic-reorder)) | `boolean` |
| resizeable? | Whether or not the columns can be resized | `boolean` |
| select? | Whether ot not the rows items can be selected | `boolean \| SelectOptions` |
| auto? | Create missing columns automatically? | `boolean` |#### SelectOptions
| Properties | Description | Type |
| - | - | - |
| show? | When to show the row-select when not selected | `'hover' \| 'always' \| 'never'` |
| headerSnippet? | Custom snippet for the header select-input | `Snippet<[context: HeaderSelectCtx]>` |
| rowSnippet? | Custom snippet for the row select-input | `Snippet<[context: RowSelectCtx]>` |
### Column
```ts
import { Column } from 'svelte-tably'
```This component designates a column where options like sorting, filtering etc. are provided.
```html
row.value} />{#snippet header?(ctx: HeaderCtx)}
...
{/snippet}
{#snippet row?(item: T, ctx: RowColumnCtx)}
...
{/snippet}
{#snippet statusbar?(ctx: StatusbarCtx)}
...
{/snippet}```
| Attribute | Description | Type |
| - | - | - |
| header? | The header element/contents | `string \| Snippet<[ctx: HeaderCtx]>` |
| row? | The row element. If not provided, `value: V` will be used. | `Snippet<[item: T, ctx: RowColumnCtx]>` |
| statusbar? | The statusbar element | `Snippet<[ctx: StatusbarCtx]>` |
| | | |
| sticky? | Should be sticky by default | `boolean` |
| show? | Should be visible by default | `boolean` |
| sortby? | Should sort by this by default | `boolean` |
| width? | Default width | `number` |
| value? | The value this column contains | `(item: T) => V` |
| sort? | A boolean (`localeCompare`) or sorting function | `boolean \| ((a: V, b: V) => number)` |
| resizeable? | Whether this column is resizeable | `boolean` |
| filter? | A filter for this columns value | `(item: V) => boolean` |
| style? | Styling the `td` (row-column) element | `string` |
| pad? | Apply padding to the child-element of `td`/`th` instead of the column element itself | `'row' \| 'header' \| 'both'` |
| onclick? | When the column is clicked | `(event: MouseEvent, ctx: RowColumnCtx) => void` |
### Row
```ts
import { Row } from 'svelte-tably'
```This component can add a context-menu on the side of each row, as well as provide event handlers to the row element.
```html
{#snippet context?(item: T, ctx: RowCtx)}
...
{/snippet}
{#snippet contextHeader?()}
...
{/snippet}```
| Attribute | Description | Type |
| - | - | - |
| context? | A sticky column on the right for each row | `Snippet<[item: T, ctx: RowCtx]>` |
| contextHeader? | A sticky column on the right for the header | `Snippet<[item: T, ctx: RowCtx]>` |
| | | |
| contextOptions? | Options for the Context-column | `ContextOptions` |
| onclick? | When row is clicked | `(event: MouseEvent, ctx: RowCtx) => void` |
| oncontextmenu? | When row is right-clicked | `(event: MouseEvent, ctx: RowCtx) => void` |#### ContextOptions
| Properties | Description | Type |
| - | - | - |
| hover? | Only show when hovering? | `boolean` |
| width? | The width for the context-column | `string` |
### Expandable
```ts
import { Expandable } from 'svelte-tably'
```This component gives your rows the ability to be expanded.
```html
{#snippet content(item: T, ctx: RowCtx)}
...
{/snippet}```
| Attribute | Description | Type |
| - | - | - |
| content | The contents of the expanded row. | `Snippet<[item: T, ctx: RowCtx]>` |
| | | |
| slide? | Options for sliding the expanding part | `{ duration?: number, easing?: EasingFunction }` |
| click? | Whether you can click on a row to expand/collapse it | `boolean` |
| chevron? | Whether to show the chevron on the left fixed column | `'always' \| 'hover' \| 'never'` |
| multiple? | Can multiple rows be open at the same time? | `boolean` |
### Panel
```ts
import { Panel } from 'svelte-tably'
```This component creates a panel that can be opened on the side of the table.
```html
{#snippet children(ctx: PanelCtx)}
...
{/snippet}```
| Attribute | Description | Type |
| - | - | - |
| children | The contents of the panel | `Snippet<[ctx: PanelCtx]>` |
| | | |
| id | The id for the panel that determines whether it's open or closed, from the Table attribute | `string` |
| backdrop? | Whether there should be a backdrop or not | `boolean` |