@shotleybuilder/svelte-table-kit
v0.14.0
Published
A comprehensive, AI-configurable data table component for Svelte and SvelteKit, built on TanStack Table v8
Maintainers
Readme
🎯 Svelte Table Kit
A comprehensive, AI-configurable data table component for Svelte and SvelteKit, built on TanStack Table v8.
Svelte Table Kit brings Airtable-like functionality to your Svelte applications with a headless, fully customizable table component. Perfect for dashboards, data grids, and complex data visualization needs.
✨ Features
Core Table Features:
- 🎯 Column visibility picker with show/hide controls
- 📏 Column resizing with drag handles (62px-1000px range)
- 🔄 Column reordering via native HTML5 drag & drop
- 📐 Row height control - 4 sizes: short, medium, tall, extra tall
- ↔️ Column spacing control - 3 sizes: narrow, normal, wide
- 🔍 Advanced filtering - 12 operators with AND/OR logic
- 📊 Multi-level grouping - Up to 3 nested levels (like Airtable)
- ⬆️ Flexible sorting - Column header or Airtable-style sort control
- 📄 Pagination with customizable page sizes
- 💾 LocalStorage persistence for all user preferences
- ✂️ Text truncation with ellipsis for long content
- 📋 Column context menu - Quick access to sort, filter, group, and hide actions
Advanced Filtering:
- 14 filter operators: equals, contains, starts with, greater than, is_before, is_after, etc.
- AND/OR logic between conditions
- Collapsible FilterBar UI (space-efficient)
- Active filter count badge
- Real-time filtering as you type
- Column order modes - Cycle between Default, Table Order, and A-Z sorting in field picker (v0.7.0+)
- Fuzzy search - Type to quickly find columns in large tables with highlighted matches (v0.8.0+)
- Value suggestions - Autocomplete dropdown shows existing column values as you type (v0.10.0+)
- Numeric range hints - Numeric columns display min/max range in the value input (v0.10.0+)
- Data type awareness - Operators and value inputs adapt based on column data type (v0.11.0+)
Sorting Options:
- Column header mode (default) - Click headers to sort with ↑↓↕ indicators
- Airtable-style control - Dedicated sort dropdown with multi-level sorting
- Choose column and direction (A → Z or Z → A)
- Multiple sort levels applied top to bottom
- Collapsible SortBar UI
Grouping & Hierarchy:
- Group by up to 3 columns simultaneously
- Expand/collapse groups with chevron buttons
- Visual indentation based on nesting level
- Item count per group
- Collapsible GroupBar UI
Column Context Menu:
- Hover over column headers to reveal menu trigger (chevron icon)
- Sort A → Z / Sort Z → A - Quick sort with active state indication
- Filter by this field - Creates pre-filled filter condition
- Group by this field - Adds column to grouping configuration
- Hide field - Remove column from view
- Actions conditionally shown based on feature flags
- Seamlessly integrates with existing controls
Cell Context Menu (v0.9.0+):
- Right-click any cell to open context menu
- Filter by value - Instantly filter to show rows matching cell value
- Exclude value - Filter to hide rows with this value
- Greater/Less than - Numeric columns get comparison options
- Auto-expands FilterBar when filter is created
Developer Experience:
- 🎨 Headless design - style it your way
- 📦 Built on TanStack Table v8 (battle-tested, powerful)
- 🔒 Full TypeScript support
- 🎛️ Feature flags for granular control
- 🔌 Toolbar slot - Add custom controls to the toolbar (v0.6.0+)
- 🚀 Zero external dependencies (except TanStack Table)
- ♿ Accessible and keyboard-friendly
AI-Ready:
- 🤖 JSON-schema driven configuration
- 🧠 AI agents can generate table configs from natural language
- ⚡ Reactive config prop - Update table state dynamically without remounting (v0.5.0+)
- 📋 Preset configurations for common use cases
- 🔧 Programmatic table setup and state management
📅 View Development Roadmap - See what's coming next!
📦 Installation
npm install @shotleybuilder/svelte-table-kitOr using pnpm:
pnpm add @shotleybuilder/svelte-table-kit🚀 Quick Start
<script>
import { TableKit } from '@shotleybuilder/svelte-table-kit';
const data = [
{ id: 1, name: 'Alice', role: 'Developer', age: 28 },
{ id: 2, name: 'Bob', role: 'Designer', age: 32 },
{ id: 3, name: 'Charlie', role: 'Manager', age: 45 }
];
const columns = [
{ accessorKey: 'id', header: 'ID' },
{ accessorKey: 'name', header: 'Name' },
{ accessorKey: 'role', header: 'Role' },
{ accessorKey: 'age', header: 'Age' }
];
</script>
<TableKit {data} {columns} storageKey="my-table" />📚 Documentation
Basic Usage
The simplest way to use TableKit:
<TableKit {data} {columns} />With Configuration
Customize initial table state programmatically:
<script>
import { TableKit } from '@shotleybuilder/svelte-table-kit';
</script>
<TableKit
{data}
{columns}
config={{
id: 'my-view-v1',
version: '1.0',
defaultColumnOrder: ['name', 'role', 'age', 'id'],
defaultColumnSizing: { name: 200, role: 150 },
defaultVisibleColumns: ['name', 'role', 'age'],
defaultFilters: [
{ id: 'f1', field: 'role', operator: 'equals', value: 'Developer' }
],
defaultSorting: [
{ columnId: 'name', direction: 'asc' }
],
defaultGrouping: ['role'],
defaultExpanded: true,
filterLogic: 'and'
}}
features={{
columnVisibility: true,
filtering: true,
sorting: true,
pagination: true
}}
/>Reactive Configuration (v0.5.0+)
The config prop is fully reactive - update it dynamically to change table state without remounting:
<script>
import { TableKit } from '@shotleybuilder/svelte-table-kit';
let tableConfig = $state({
id: 'query-1',
version: '1.0',
defaultFilters: [
{ id: 'f1', field: 'status', operator: 'equals', value: 'active' }
]
});
// Update config - table reacts automatically
function showPendingItems() {
tableConfig = {
id: 'query-2', // New ID triggers update
version: '1.0',
defaultFilters: [
{ id: 'f1', field: 'status', operator: 'equals', value: 'pending' }
]
};
}
</script>
<button on:click={showPendingItems}>Show Pending</button>
<TableKit {data} {columns} config={tableConfig} persistState={false} />Perfect for AI-driven tables:
<script>
let aiConfig = $state(undefined);
async function askAI(question) {
const response = await fetch('/api/nl-query', {
method: 'POST',
body: JSON.stringify({ question })
});
aiConfig = await response.json(); // Table updates automatically
}
</script>
<input
placeholder="Ask a question about the data..."
on:submit={(e) => askAI(e.target.value)}
/>
<TableKit {data} {columns} config={aiConfig} persistState={false} />Key Points:
- Config changes detected by comparing
config.id - Set
persistState={false}to prevent localStorage conflicts - When config is active, localStorage is automatically ignored
- No
{#key}blocks needed - updates are smooth and instant
Feature Flags
Control which features are enabled:
<TableKit
{data}
{columns}
features={{
columnVisibility: true,
columnResizing: true,
columnReordering: true,
filtering: true,
sorting: true,
sortingMode: 'control', // 'header' (default) or 'control' (Airtable-style)
pagination: true,
rowSelection: false,
grouping: false
}}
/>Sorting Modes:
sortingMode: 'header'- Click column headers to sort (default behavior)sortingMode: 'control'- Use Airtable-style sort dropdown with multi-level support
Event Handlers
Listen to table events:
<TableKit
{data}
{columns}
onRowClick={(row) => console.log('Clicked:', row)}
onRowSelect={(rows) => console.log('Selected:', rows)}
onStateChange={(state) => console.log('State:', state)}
/>Custom Toolbar Controls (v0.6.0+)
Add custom controls to the left side of the toolbar using the toolbar-left slot:
<script>
import { TableKit } from '@shotleybuilder/svelte-table-kit';
import ViewSelector from './ViewSelector.svelte';
</script>
<TableKit {data} {columns}>
<!-- Add custom controls to the toolbar -->
<svelte:fragment slot="toolbar-left">
<ViewSelector on:viewSelected={handleViewSelected} />
<button on:click={saveView} class="btn-primary">
Save View
</button>
</svelte:fragment>
</TableKit>Use Cases:
- View management controls (save/load table configurations)
- Custom filter presets
- Quick action buttons
- Export/import controls
- Any custom toolbar buttons that should appear alongside table controls
The toolbar-left slot is positioned on the left side of the toolbar, while the built-in table controls (Filter, Sort, Group, Columns) automatically align to the right. All controls appear on the same row, creating a unified control bar.
🎨 Styling
TableKit is headless by default. You can:
- Use default styles (coming soon)
- Customize with classNames:
<TableKit
{data}
{columns}
classNames={{
container: 'my-container',
table: 'my-table',
th: 'my-header'
}}
/>- Theme support:
<TableKit {data} {columns} theme="dark" />🧬 API Reference
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | T[] | [] | Table data array |
| columns | ColumnDef<T>[] | [] | Column definitions |
| config | TableConfig | undefined | Reactive table configuration (requires id and version) |
| features | TableFeatures | All enabled | Feature flags |
| storageKey | string | undefined | LocalStorage key for persistence |
| persistState | boolean | true | Enable state persistence (auto-disabled when config is active) |
| theme | 'light' \| 'dark' \| 'auto' | 'light' | Theme mode |
| align | 'left' \| 'center' \| 'right' | 'left' | Column text alignment |
| rowHeight | 'short' \| 'medium' \| 'tall' \| 'extra_tall' | 'medium' | Row height preset |
| columnSpacing | 'narrow' \| 'normal' \| 'wide' | 'normal' | Column horizontal spacing |
| onRowClick | (row: T) => void | undefined | Row click handler |
| onRowSelect | (rows: T[]) => void | undefined | Row selection handler |
| onStateChange | (state: TableState) => void | undefined | State change handler |
TableConfig Type
interface TableConfig {
id: string; // Required: Unique identifier for change detection
version: string; // Required: Config version
defaultColumnOrder?: string[]; // Column IDs in display order
defaultColumnSizing?: Record<string, number>; // Column widths in pixels
defaultVisibleColumns?: string[]; // Visible column IDs (others hidden)
defaultFilters?: FilterCondition[]; // Initial filter conditions
defaultSorting?: SortConfig[]; // Initial sort configuration
defaultGrouping?: string[]; // Initial grouping column IDs (up to 3)
defaultExpanded?: boolean; // Initial expanded state for groups (default: true)
filterLogic?: 'and' | 'or'; // Filter combination logic
pagination?: {
pageSize: number;
pageSizeOptions?: number[];
};
}🎯 Use Cases
- Enterprise dashboards and data visualization
- Admin panels and back-office tools
- Analytics interfaces with complex filtering
- Data exploration and reporting tools
- Any application needing Airtable/Baserow-like table UX
🤝 Contributing
Contributions are welcome! Please read our Contributing Guide (coming soon).
📄 License
MIT © Sertantai
🔗 Links
🙏 Acknowledgments
Built with:
- TanStack Table - Headless table library
- Svelte - Cybernetically enhanced web apps
- SvelteKit - The fastest way to build Svelte apps
