mithril-materialized
Version:
A materialize library for mithril.
292 lines (291 loc) • 10.9 kB
TypeScript
import { Attributes, Component, Vnode, type FactoryComponent } from 'mithril';
/**
* Attributes for custom cell renderer components in DataTable
* @template T The type of the data object for each row
*/
export interface CellRendererAttrs<T = Record<string, any>> {
/** The processed value from the data object for this cell */
value: any;
/** The complete row data object */
row: T;
/** The row index in the processed data */
index: number;
/** The column configuration object */
column: DataTableColumn<T>;
}
/**
* Configuration for a DataTable column
* @template T The type of the data object for each row
*/
export interface DataTableColumn<T = Record<string, any>> {
/** Unique identifier for the column (required for sorting/filtering) */
key: string;
/** Display title shown in the column header */
title: string;
/** Property name in the data object to display. If not provided, the entire row object is passed to the renderer */
field?: keyof T;
/** Custom cell renderer component for advanced cell content */
cellRenderer?: FactoryComponent<CellRendererAttrs<T>>;
/** @deprecated Use cellRenderer instead - Legacy render function for cell content */
render?: (value: any, row: T, index: number) => string | number | Vnode | Vnode[];
/** Enable sorting for this column */
sortable?: boolean;
/** Enable global search filtering for this column */
filterable?: boolean;
/** CSS width value (e.g., '100px', '20%', '10rem') */
width?: string;
/** Text alignment within cells */
align?: 'left' | 'center' | 'right';
/** CSS class applied to all cells in this column */
className?: string;
/** CSS class applied to the column header */
headerClassName?: string;
}
/**
* Configuration for DataTable sorting state
*/
export interface DataTableSort {
/** Key of the column to sort by (must match a column's key) */
column: string;
/** Sort direction - ascending or descending */
direction: 'asc' | 'desc';
}
/**
* Configuration for DataTable pagination
*/
export interface DataTablePagination {
/** Current page number (0-based indexing) */
page: number;
/** Number of items to display per page */
pageSize: number;
/** Total number of items in the dataset */
total: number;
/** Array of available page size options for user selection */
pageSizes?: number[];
}
/**
* Configuration for DataTable row selection functionality
* @template T The type of the data object for each row
*/
export interface DataTableSelection<T = Record<string, any>> {
/** Selection mode - controls how many rows can be selected */
mode: 'single' | 'multiple' | 'none';
/** Array of currently selected row keys */
selectedKeys: string[];
/** Function to generate a unique key for each row */
getRowKey: (row: T, index: number) => string;
/** Callback invoked when row selection changes */
onSelectionChange?: (selectedKeys: string[], selectedRows: T[]) => void;
}
/**
* Configuration for DataTable filtering functionality
*/
export interface DataTableFilter {
/** Global search term applied across all filterable columns */
searchTerm?: string;
/** Column-specific filter values keyed by column key */
columnFilters?: Record<string, any>;
}
/**
* Main DataTable component attributes
* @template T The type of the data object for each row
*
* @example Basic usage
* ```typescript
* m(DataTable, {
* data: users,
* columns: [
* { key: 'name', title: 'Name', field: 'name', sortable: true },
* { key: 'email', title: 'Email', field: 'email', filterable: true }
* ]
* })
* ```
*
* @example With pagination and selection
* ```typescript
* m(DataTable, {
* data: users,
* columns,
* pagination: { page: 0, pageSize: 10, total: users.length },
* selection: {
* mode: 'multiple',
* selectedKeys: [],
* getRowKey: (user) => user.id,
* onSelectionChange: (keys, users) => console.log('Selected:', users)
* }
* })
* ```
*/
export interface DataTableAttrs<T = Record<string, any>> extends Attributes {
/** Array of data objects to display in the table */
data: T[];
/** Column configuration array defining how data should be displayed */
columns: DataTableColumn<T>[];
/** Optional title displayed above the table */
title?: string;
/** Show loading spinner and disable interactions */
loading?: boolean;
/** Message to display when data array is empty */
emptyMessage?: string;
/** Apply alternating row background colors */
striped?: boolean;
/** Enable row highlighting on hover */
hoverable?: boolean;
/** Make table responsive with horizontal scrolling on small screens */
responsive?: boolean;
/** Center-align all table content */
centered?: boolean;
/** Fixed table height in pixels (enables scrolling) */
height?: number;
/** Additional CSS classes to apply to the table */
className?: string;
/** Custom HTML id attribute for the table container */
id?: string;
/** Current sort configuration. If provided, sorting is controlled externally */
sort?: DataTableSort;
/** Callback invoked when user changes sort order */
onSortChange?: (sort: DataTableSort) => void;
/** Pagination configuration. If provided, pagination is controlled externally */
pagination?: DataTablePagination;
/** Callback invoked when user changes page or page size */
onPaginationChange?: (pagination: DataTablePagination) => void;
/** Row selection configuration */
selection?: DataTableSelection<T>;
/** Current filter state. If provided, filtering is controlled externally */
filter?: DataTableFilter;
/** Callback invoked when filter values change */
onFilterChange?: (filter: DataTableFilter) => void;
/** Show global search input above the table */
enableGlobalSearch?: boolean;
/** Placeholder text for the global search input */
searchPlaceholder?: string;
/** Callback invoked when a row is clicked */
onRowClick?: (row: T, index: number, event: Event) => void;
/** Callback invoked when a row is double-clicked */
onRowDoubleClick?: (row: T, index: number, event: Event) => void;
/** Function to generate custom CSS classes for each row */
getRowClassName?: (row: T, index: number) => string;
/** Internationalization configuration for UI text */
i18n?: DataTableI18n;
}
/**
* Internationalization configuration for DataTable UI text
* Allows customization of all user-facing text strings
*/
export interface DataTableI18n {
/** Label for the search input */
search?: string;
/** Placeholder text for the search input */
searchPlaceholder?: string;
/** "Showing" text in pagination display */
showing?: string;
/** "to" text in pagination display (e.g., "Showing 1 to 10 of 100") */
to?: string;
/** "of" text in pagination display */
of?: string;
/** "entries" text in pagination display */
entries?: string;
/** "Page" text in pagination controls */
page?: string;
/** Message displayed when no data is available */
noDataAvailable?: string;
/** Loading message displayed during data fetch */
loading?: string;
}
/**
* Attributes for the PaginationControls component
*/
export interface PaginationControlsAttrs {
/** Pagination configuration object */
pagination?: DataTablePagination;
/** Callback function invoked when pagination state changes */
onPaginationChange: (pagination: DataTablePagination) => void;
/** Internationalization strings for pagination text */
i18n?: DataTableI18n;
}
/**
* Standalone Pagination Controls component
*
* Provides navigation controls for paginated data with customizable text labels.
* Includes first page, previous page, next page, last page buttons and page info display.
* Can be used independently of DataTable for any paginated content.
*
* @example
* ```typescript
* m(PaginationControls, {
* pagination: { page: 0, pageSize: 10, total: 100 },
* onPaginationChange: (newPagination) => console.log('Page changed:', newPagination),
* i18n: { showing: 'Showing', to: 'to', of: 'of', entries: 'entries', page: 'Page' }
* })
* ```
*/
export declare const PaginationControls: FactoryComponent<PaginationControlsAttrs>;
/**
* A comprehensive data table component with sorting, filtering, pagination, and selection capabilities.
*
* @template T The type of data objects displayed in each row
*
* @description
* The DataTable component provides a feature-rich interface for displaying and interacting with tabular data.
* It supports both controlled and uncontrolled modes for all interactive features.
*
* **Key Features:**
* - Sorting: Click column headers to sort data ascending/descending
* - Filtering: Global search across filterable columns
* - Pagination: Navigate through large datasets with customizable page sizes
* - Selection: Single or multiple row selection with callbacks
* - Custom rendering: Use cellRenderer for complex cell content
* - Responsive: Adapts to different screen sizes
* - Internationalization: Customize all UI text
* - Accessibility: Proper ARIA attributes and keyboard navigation
*
* @example Basic usage
* ```typescript
* interface User { id: number; name: string; email: string; }
* const users: User[] = [...];
* const columns: DataTableColumn<User>[] = [
* { key: 'name', title: 'Name', field: 'name', sortable: true, filterable: true },
* { key: 'email', title: 'Email', field: 'email', sortable: true, filterable: true }
* ];
*
* return m(DataTable<User>, { data: users, columns });
* ```
*
* @example Advanced usage with all features
* ```typescript
* return m(DataTable<User>, {
* data: users,
* columns,
* title: 'User Management',
* striped: true,
* hoverable: true,
* height: 400,
*
* // Pagination
* pagination: { page: 0, pageSize: 10, total: users.length },
* onPaginationChange: (pagination) => console.log('Page changed:', pagination),
*
* // Selection
* selection: {
* mode: 'multiple',
* selectedKeys: [],
* getRowKey: (user) => String(user.id),
* onSelectionChange: (keys, selectedUsers) => console.log('Selection:', selectedUsers)
* },
*
* // Search
* enableGlobalSearch: true,
* searchPlaceholder: 'Search users...',
*
* // Events
* onRowClick: (user, index, event) => console.log('Clicked:', user),
* onRowDoubleClick: (user) => editUser(user),
*
* // Styling
* getRowClassName: (user) => user.active ? '' : 'inactive-row'
* });
* ```
*
* @returns A Mithril component that renders the data table
*/
export declare const DataTable: <T = Record<string, any>>() => Component<DataTableAttrs<T>>;