npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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/svelte

Features

  • Svelte 5 Runes - Fine-grained reactivity with $state and $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