@humanspeak/svelte-headless-table
v7.1.0
Published
A powerful, headless table library for Svelte that provides complete control over table UI while handling complex data operations like sorting, filtering, pagination, grouping, and row expansion. Build custom, accessible data tables with zero styling opin
Maintainers
Readme
Svelte Headless Table
Unopinionated and extensible data tables for Svelte
Build and design powerful datagrid experiences while retaining 100% control over styles and markup.
Visit the documentation for code examples and API reference, and get started with the quick start guide!
Why Svelte Headless Table?
Svelte Headless Table is designed to work seamlessly with Svelte. If you love Svelte, you will love Svelte Headless Table.
- Full TypeScript support
- Compatible with SvelteKit and SSR
- Runes-native: plain reactive values, no stores
- Headless and fully customizable
- Intuitive column-first declarative model
- Highly performant
- Feature-rich
All the features you could ever need
Svelte Headless Table comes with an extensive suite of plugins.
Easily extend Svelte Headless Table with complex sorting, filtering, grouping, pagination, and much more.
Plugin roadmap
- [x] addSortBy
- [x] addColumnFilters
- [x] addTableFilter
- [x] addColumnOrder
- [x] addHiddenColumns
- [x] addPagination
- [x] addSubRows
- [x] addGroupBy
- [x] addExpandedRows
- [x] addSelectedRows
- [x] addResizedColumns
- [x] addGridLayout
- [x] addVirtualScroll
Installation
npm install @humanspeak/svelte-headless-tableRequires Svelte 5.30 or later. Upgrading from 6.x? Follow the migration guide.
Examples
<script>
import { createTable, Render } from '@humanspeak/svelte-headless-table';
const data = [
{ name: 'Ada Lovelace', age: 21 },
{ name: 'Barbara Liskov', age: 52 },
{ name: 'Richard Hamming', age: 38 },
];
const table = createTable(data);
const columns = table.createColumns([
table.column({
header: 'Name',
accessor: 'name',
}),
table.column({
header: 'Age',
accessor: 'age',
}),
]);
const vm = table.createViewModel(columns);
</script>
<table {...vm.current.tableAttrs}>
<thead>
{#each vm.current.headerRows as headerRow (headerRow.id)}
<tr {...headerRow.current.attrs}>
{#each headerRow.cells as cell (cell.id)}
<th {...cell.current.attrs}>
<Render of={cell.render()} />
</th>
{/each}
</tr>
{/each}
</thead>
<tbody {...vm.current.tableBodyAttrs}>
{#each vm.current.pageRows as row (row.id)}
<tr {...row.current.attrs}>
{#each row.cells as cell (cell.id)}
<td {...cell.current.attrs}>
<Render of={cell.render()} />
</td>
{/each}
</tr>
{/each}
</tbody>
</table>Every row, cell and the view model itself expose a current object whose values are plain and reactive: read them in the template and they update as plugins change state, with no stores, $ syntax or wrapper components. For data that changes, keep it in $state and pass a getter: createTable(() => items).
Coming from 6.x, where tables were built on Svelte stores? See Migrating to v7.
Custom cells with snippets
Use createSnippetRender to render a cell (or header) with a snippet declared in the same component. Top-level snippets are hoisted, so they can be referenced from <script>.
<script>
import { createSnippetRender } from '@humanspeak/svelte-headless-table';
const columns = table.createColumns([
table.column({
accessor: 'name',
header: 'Name',
cell: ({ value }) => createSnippetRender(nameCell, value),
}),
]);
</script>
{#snippet nameCell(name)}
<strong>{name}</strong>
{/snippet}For more complex examples with advanced features, visit the documentation site.
Svelte 5 ecosystem
Part of the Humanspeak family of runes-native Svelte 5 packages:
| Package | Description | | --- | --- | | @humanspeak/svelte-markdown | Runtime markdown renderer for Svelte | | @humanspeak/svelte-virtual-list | Virtual scrolling for Svelte | | @humanspeak/svelte-motion | Framer Motion for Svelte 5 | | @humanspeak/svelte-headless-table — this package | Headless data tables for Svelte | | @humanspeak/svelte-virtual-chat | Virtual chat viewport for Svelte 5 | | @humanspeak/svelte-diff | Diff comparison for Svelte | | @humanspeak/svelte-purify | HTML sanitisation for Svelte | | @humanspeak/memory-cache | In-memory cache for TypeScript | | @humanspeak/svelte-json-view-lite | JSON tree viewer for Svelte 5 | | @humanspeak/svelte-scoped-props | Scoped class props for Svelte |
License
MIT © Humanspeak, Inc.
Credits
Made with ❤️ by Humanspeak
