@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
73 lines (72 loc) • 2.29 kB
JavaScript
import { finalizeAttributes, mergeAttributes } from './utils/attributes.js';
import { derivedKeys } from '@humanspeak/svelte-subscribe';
import { derived } from 'svelte/store';
/**
* Abstract base class for all table components (rows, cells, etc.).
* Provides common functionality for state injection, hook application, and attribute merging.
*
* @template Item - The type of data items in the table.
* @template Plugins - The plugins used by the table.
* @template Key - The component key type (e.g., 'tbody.tr', 'tbody.tr.td').
*/
export class TableComponent {
/** Unique identifier for the component. */
id;
/**
* Creates a new TableComponent.
*
* @param init - Initialization options.
*/
constructor({ id }) {
this.id = id;
}
attrsForName = {};
/**
* Gets the merged HTML attributes from all applied plugins.
*
* @returns A readable store of merged attributes.
*/
attrs() {
return derived(Object.values(this.attrsForName), ($attrsArray) => {
let $mergedAttrs = {};
$attrsArray.forEach(($attrs) => {
$mergedAttrs = mergeAttributes($mergedAttrs, $attrs);
});
return finalizeAttributes($mergedAttrs);
});
}
propsForName = {};
/**
* Gets the merged props from all applied plugins.
*
* @returns A readable store of plugin props keyed by plugin name.
*/
props() {
return derivedKeys(this.propsForName);
}
/** Reference to the table state, injected after creation. */
state;
/**
* Injects the table state reference into this component.
*
* @param state - The table state to inject.
*/
injectState(state) {
this.state = state;
}
/**
* Applies a plugin hook to this component.
* Hooks can provide both props and attributes.
*
* @param pluginName - The name of the plugin.
* @param hook - The element hook containing props and/or attrs.
*/
applyHook(pluginName, hook) {
if (hook.props !== undefined) {
this.propsForName[pluginName] = hook.props;
}
if (hook.attrs !== undefined) {
this.attrsForName[pluginName] = hook.attrs;
}
}
}