UNPKG

@humanspeak/svelte-headless-table

Version:

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

129 lines (128 loc) 4.32 kB
import { DataColumn, DisplayColumn, getFlatColumnIds, GroupColumn } from './columns.js'; import { createViewModel } from './createViewModel.js'; import { getDuplicates } from './utils/array.js'; /** * Core table class that provides methods for defining columns and creating view models. * Use the `createTable` factory function to instantiate. * * @template Item - The type of data items in the table. * @template Plugins - The plugins configuration type. * @example * ```typescript * const table = createTable(data, { sort: addSortBy(), filter: addTableFilter() }) * const columns = table.createColumns([ * table.column({ accessor: 'name', header: 'Name' }), * table.column({ accessor: 'age', header: 'Age' }) * ]) * const viewModel = table.createViewModel(columns) * ``` */ export class Table { /** The data source, either a Readable or Writable Svelte store. */ data; /** The plugins configuration object. */ plugins; /** * Creates a new Table instance. * * @param data - A Svelte store containing the table data. * @param plugins - The plugins to use with this table. */ constructor(data, plugins) { this.data = data; this.plugins = plugins; } /** * Validates and returns the column definitions. * Throws an error if duplicate column IDs are detected. * * @param columns - Array of column definitions. * @returns The same columns array if validation passes. * @throws Error if duplicate column IDs are found. */ createColumns(columns) { const ids = getFlatColumnIds(columns); const duplicateIds = getDuplicates(ids); if (duplicateIds.length !== 0) { throw new Error(`Duplicate column ids not allowed: "${duplicateIds.join('", "')}"`); } return columns; } column(def) { return new DataColumn(def); } /** * Creates a group column that contains other columns. * Used for creating hierarchical column headers. * * @param def - The group column definition. * @returns A new GroupColumn instance. * @example * ```typescript * table.group({ * header: 'Personal Info', * columns: [ * table.column({ accessor: 'firstName', header: 'First Name' }), * table.column({ accessor: 'lastName', header: 'Last Name' }) * ] * }) * ``` */ group(def) { return new GroupColumn(def); } /** * Creates a display column for non-data content like actions or selection checkboxes. * * @param def - The display column definition. * @returns A new DisplayColumn instance. * @example * ```typescript * table.display({ * id: 'actions', * header: '', * cell: ({ row }) => createRender(ActionButtons, { row }) * }) * ``` */ display(def) { return new DisplayColumn(def); } /** * Creates a reactive view model from the table and columns. * The view model provides all the data needed to render the table. * * @param columns - The column definitions. * @param options - Optional configuration for the view model. * @returns A TableViewModel with reactive stores for rendering. */ createViewModel(columns, options) { return createViewModel(this, columns, options); } } /** * Factory function to create a new Table instance. * This is the main entry point for using svelte-headless-table. * * @template Item - The type of data items in the table. * @template Plugins - The plugins configuration type. * @param data - A Svelte store containing the table data. * @param plugins - Optional plugins configuration object. * @returns A new Table instance. * @example * ```typescript * import { createTable } from 'svelte-headless-table' * import { addSortBy, addPagination } from 'svelte-headless-table/plugins' * * const data = writable([{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }]) * const table = createTable(data, { * sort: addSortBy(), * page: addPagination({ initialPageSize: 10 }) * }) * ``` */ export const createTable = (data, // eslint-disable-next-line @typescript-eslint/no-explicit-any plugins = {}) => { return new Table(data, plugins); };