@pivot-blitz/svelte
v0.1.0
Published
Modern pivot table components for Svelte 5 with full TypeScript support.
Downloads
50
Readme
@pivotblitz/svelte
Modern pivot table components for Svelte 5 with full TypeScript support.
Installation
pnpm add @pivotblitz/svelteFeatures
- Svelte 5 Runes - Fine-grained reactivity with
$stateand$derived - Drag & Drop - Field chooser with intuitive drag-and-drop
- Dark Mode - Full theming with light/dark/system modes
- RTL Support - Right-to-left layouts for Arabic and Hebrew
- Charts - Bar, Line, Pie, Heatmap, Scatter (SVG-based)
- Export - Excel, PDF, CSV, JSON, HTML, PNG
- TypeScript - Full type definitions
Quick Start
<script>
import { createPivotStore, PivotTable } from '@pivotblitz/svelte';
const data = [
{ region: 'North', product: 'Widget', sales: 100 },
{ region: 'North', product: 'Gadget', sales: 150 },
{ region: 'South', product: 'Widget', sales: 200 },
];
const store = createPivotStore(data, {
rows: ['region'],
cols: ['product'],
vals: ['sales'],
aggregatorName: 'Sum'
});
</script>
<PivotTable {store} />Components
PivotTable
The main pivot table component.
<script>
import { PivotTable } from '@pivotblitz/svelte';
</script>
<PivotTable
{store}
layout="compact"
showRowTotals={true}
showColTotals={true}
showGrandTotal={true}
enableHover={true}
enableResize={true}
zebra={true}
stickyHeaders={true}
locale="en"
onCellClick={(rowKey, colKey, value) => {
console.log('Clicked:', { rowKey, colKey, value });
}}
onCellRightClick={(rowKey, colKey, value, event) => {
// Show context menu
}}
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| store | PivotStore | required | Pivot store instance |
| layout | 'compact' \| 'tabular' \| 'flat' | 'compact' | Table layout style |
| showRowTotals | boolean | true | Show row totals |
| showColTotals | boolean | true | Show column totals |
| showGrandTotal | boolean | true | Show grand total |
| enableHover | boolean | true | Enable cell hover effect |
| enableResize | boolean | true | Enable column resizing |
| zebra | boolean | true | Alternating row colors |
| stickyHeaders | boolean | true | Sticky row/column headers |
| locale | string | 'en' | Locale for formatting |
| formattingRules | ConditionalRule[] | [] | Conditional formatting rules |
Events
| Event | Payload | Description |
|-------|---------|-------------|
| onCellClick | (rowKey, colKey, value) | Cell click handler |
| onCellRightClick | (rowKey, colKey, value, event) | Cell right-click handler |
| onHeaderClick | (field, type) | Header click handler |
| onExpand | (rowKey, expanded) | Row expand/collapse |
PivotTableAdvanced
Extended pivot table with built-in toolbar, field chooser, and drill-down.
<script>
import { PivotTableAdvanced } from '@pivotblitz/svelte';
</script>
<PivotTableAdvanced
{store}
showToolbar={true}
showFieldChooser={true}
enableDrillDown={true}
enableExport={true}
theme="light"
/>FieldChooser
Drag-and-drop field configuration panel.
<script>
import { FieldChooser } from '@pivotblitz/svelte';
let showFieldChooser = $state(false);
</script>
<button onclick={() => showFieldChooser = !showFieldChooser}>
Toggle Fields
</button>
{#if showFieldChooser}
<FieldChooser
{store}
position="left"
collapsible={true}
showSearch={true}
/>
{/if}PivotToolbar
Toolbar with export, layout switcher, and view options.
<script>
import { PivotToolbar } from '@pivotblitz/svelte';
let layout = $state('compact');
</script>
<PivotToolbar
{store}
bind:layout
showLayoutSwitcher={true}
showExportMenu={true}
showAggregatorSelector={true}
onExport={(format) => handleExport(format)}
onToggleFieldChooser={() => showFields = !showFields}
/>ThemeProvider
Dark mode and theming support.
<script>
import { ThemeProvider, PivotTable } from '@pivotblitz/svelte';
</script>
<ThemeProvider mode="dark">
<PivotTable {store} />
</ThemeProvider>
<!-- Or system preference -->
<ThemeProvider mode="system">
<PivotTable {store} />
</ThemeProvider>Charts
PivotChart
Bar, Line, Pie, Area, Doughnut charts (requires Chart.js).
<script>
import { PivotChart } from '@pivotblitz/svelte';
</script>
<PivotChart
{store}
type="bar"
stacked={false}
showLegend={true}
showGrid={true}
height={400}
/>Chart types: bar, line, pie, area, doughnut, stacked-bar, stacked-area
HeatmapChart
SVG-based heatmap (no dependencies).
<script>
import { HeatmapChart } from '@pivotblitz/svelte';
</script>
<HeatmapChart
{store}
colorScale="blues"
showValues={true}
showLegend={true}
cellSize={40}
borderRadius={4}
/>Color scales: blues, greens, reds, purples, oranges, viridis, plasma
ScatterChart
SVG-based scatter plot (no dependencies).
<script>
import { ScatterChart } from '@pivotblitz/svelte';
</script>
<ScatterChart
{store}
xField="quantity"
yField="revenue"
sizeField="profit"
colorField="region"
showTrendline={true}
showGrid={true}
showLabels={false}
pointSize={8}
/>DrillDownModal
Modal for viewing underlying records.
<script>
import { DrillDownModal } from '@pivotblitz/svelte';
let drillDownData = $state(null);
let showModal = $state(false);
function handleCellClick(rowKey, colKey, value) {
drillDownData = store.getDrillDownData(rowKey, colKey);
showModal = true;
}
</script>
<PivotTable {store} onCellClick={handleCellClick} />
{#if showModal}
<DrillDownModal
data={drillDownData}
title="Detail View"
onClose={() => showModal = false}
/>
{/if}SlicerPanel
Filter panel with visual slicers.
<script>
import { SlicerPanel } from '@pivotblitz/svelte';
</script>
<SlicerPanel
{store}
fields={['region', 'product', 'year']}
layout="vertical"
showSearch={true}
showSelectAll={true}
/>ConfigManager
Save/load pivot configurations.
<script>
import { ConfigManager } from '@pivotblitz/svelte';
</script>
<ConfigManager
{store}
storageKey="my-pivot-config"
showSaveButton={true}
showLoadButton={true}
showResetButton={true}
onSave={(config) => console.log('Saved:', config)}
onLoad={(config) => console.log('Loaded:', config)}
/>Store API
createPivotStore
Create a reactive pivot store.
import { createPivotStore } from '@pivotblitz/svelte';
const store = createPivotStore(data, {
rows: ['region', 'country'],
cols: ['product'],
vals: ['sales', 'quantity'],
aggregatorName: 'Sum',
filters: {
region: ['North', 'South']
},
sorters: {
region: 'asc'
}
});
// Reactive access
const pivotData = $derived(store.pivotData);
const fields = $derived(store.fields);
// Update configuration
store.setRows(['country']);
store.setCols(['product', 'year']);
store.setAggregator('Average');
store.setFilter('region', ['North']);
store.clearFilters();
// Get drill-down data
const records = store.getDrillDownData(['North'], ['Widget']);Store Properties
| Property | Type | Description |
|----------|------|-------------|
| data | any[] | Original data array |
| pivotData | PivotResult | Computed pivot result |
| fields | string[] | Available field names |
| rows | string[] | Current row fields |
| cols | string[] | Current column fields |
| vals | string[] | Current value fields |
| aggregatorName | string | Current aggregator |
| filters | Record<string, any[]> | Active filters |
Store Methods
| Method | Description |
|--------|-------------|
| setRows(fields) | Set row fields |
| setCols(fields) | Set column fields |
| setVals(fields) | Set value fields |
| setAggregator(name) | Set aggregator |
| setFilter(field, values) | Set filter for field |
| clearFilter(field) | Clear filter for field |
| clearFilters() | Clear all filters |
| setSorter(field, direction) | Set sort for field |
| getConfig() | Get current configuration |
| setConfig(config) | Apply configuration |
| getDrillDownData(rowKey, colKey) | Get underlying records |
Export Functions
import {
exportToExcel,
exportToPDF,
exportToCSV,
exportToJSON,
exportToHTML,
exportToImage
} from '@pivotblitz/svelte';
// All export functions
await exportToExcel(store.pivotData, { filename: 'report' });
await exportToPDF(store.pivotData, { filename: 'report', title: 'Sales' });
exportToCSV(store.pivotData, { filename: 'data' });
exportToJSON(store.pivotData, { filename: 'data' });
exportToHTML(store.pivotData, { filename: 'report', theme: 'dark' });
await exportToImage(element, { format: 'png', filename: 'chart' });Internationalization
<script>
import { setLocale, t, isRTL } from '@pivotblitz/svelte';
setLocale('ar'); // Arabic
const rtl = isRTL(); // true
</script>
<div dir={rtl ? 'rtl' : 'ltr'}>
<PivotTable {store} locale="ar" />
</div>Supported locales: en, it, de, fr, es, pt, ja, zh, ar, he
Conditional Formatting
<script>
import { PivotTable, presetRules } from '@pivotblitz/svelte';
const rules = [
presetRules.highlightTop10,
presetRules.highlightNegative,
{
type: 'heatmap',
minColor: '#fee2e2',
maxColor: '#dc2626'
}
];
</script>
<PivotTable {store} formattingRules={rules} />CSS Customization
/* Override CSS variables */
:root {
--pivot-header-bg: #1e293b;
--pivot-header-color: #f8fafc;
--pivot-cell-bg: #ffffff;
--pivot-cell-hover: #f1f5f9;
--pivot-border-color: #e2e8f0;
--pivot-total-bg: #f8fafc;
--pivot-font-family: system-ui, sans-serif;
--pivot-font-size: 14px;
}
/* Dark mode */
[data-theme="dark"] {
--pivot-header-bg: #0f172a;
--pivot-cell-bg: #1e293b;
--pivot-cell-hover: #334155;
--pivot-border-color: #475569;
}TypeScript
Full TypeScript support:
import type {
PivotStore,
PivotConfig,
PivotResult,
AggregatorName,
ConditionalRule
} from '@pivotblitz/svelte';
const config: PivotConfig = {
rows: ['region'],
cols: ['product'],
vals: ['sales'],
aggregatorName: 'Sum' as AggregatorName
};License
MIT
