UNPKG

@papernote/ui

Version:

A modern React component library with a paper notebook aesthetic - minimal, professional, and expressive

278 lines 11.5 kB
import React from 'react'; import { CardViewConfig } from './DataTableCardView'; /** * Base data item interface - all data items must have an id * * All data passed to DataTable must implement this interface to ensure * proper row identification and selection handling. */ export interface BaseDataItem { /** Unique identifier for the data item */ id: string | number; } /** * Column configuration for DataTable * * Defines how each column should be displayed, including width constraints, * custom rendering, sorting behavior, and alignment. */ export interface DataTableColumn<T> { /** Property key from data item to display in this column */ key: keyof T | string; /** Column header text */ header: string; /** Fixed width - supports CSS values ('120px', '15%', '1fr') or numbers (120) */ width?: string | number; /** Minimum width constraint */ minWidth?: string | number; /** Maximum width constraint */ maxWidth?: string | number; /** Flex-grow value for flexible width columns */ flex?: number; /** Custom render function for cell content */ render?: (item: T, value: any) => React.ReactNode; /** Secondary line content (smaller, muted text below primary) */ renderSecondary?: (item: T, value: any) => React.ReactNode; /** Enable sorting for this column */ sortable?: boolean; /** Additional CSS classes for column cells */ className?: string; /** Text alignment in column */ align?: 'left' | 'center' | 'right'; } /** * Sort configuration * * Describes the current sort state for the table. */ export interface SortConfig { /** Column key being sorted */ key: string; /** Sort direction */ direction: 'asc' | 'desc'; /** Optional display label for sort indicator */ label?: string; } /** * Row action configuration for DataTable * Defines buttons that appear in the sticky actions column */ export interface DataTableAction<T> { /** Button label text */ label: string; /** Optional icon - can be component reference or JSX element */ icon?: React.ComponentType<any> | React.ReactNode; /** Click handler receives the row item */ onClick: (item: T) => void; /** Button styling variant */ variant?: 'primary' | 'secondary' | 'ghost' | 'danger'; /** Optional conditional visibility */ show?: (item: T) => boolean; /** Optional tooltip text */ tooltip?: string; } /** * Expansion mode types */ export type ExpansionMode = 'edit' | 'details' | string; /** * Configuration for different expansion modes */ export interface ExpandedRowConfig<T> { /** Edit mode - inline editing of the record */ edit?: { render: (item: T, onSave: (updated: T) => Promise<void>, onCancel: () => void) => React.ReactNode; triggerOnDoubleClick?: boolean; menuLabel?: string; menuIcon?: React.ComponentType<any>; }; /** View details mode - read-only expanded view */ details?: { render: (item: T) => React.ReactNode; triggerOnExpand?: boolean; triggerOnDoubleClick?: boolean; menuLabel?: string; menuIcon?: React.ComponentType<any>; }; /** Add related modes - creating related records */ addRelated?: Array<{ key: string; label: string; icon?: React.ComponentType<any>; render: (parentItem: T, onSave: (newItem: any) => Promise<void>, onCancel: () => void) => React.ReactNode; showInMenu?: boolean; }>; /** Manage related modes - viewing/editing related records */ manageRelated?: Array<{ key: string; label: string; icon?: React.ComponentType<any>; render: (parentItem: T, onClose: () => void) => React.ReactNode; showInMenu?: boolean; }>; } /** * DataTable component props * * Feature-rich data table with sorting, filtering, selection, expansion, * row actions, and virtual scrolling support. */ interface DataTableProps<T extends BaseDataItem = BaseDataItem> { /** Array of data items to display */ data: T[]; /** Column definitions */ columns: DataTableColumn<T>[]; /** Show loading skeleton */ loading?: boolean; /** Error message to display */ error?: string | null; /** Message shown when data array is empty */ emptyMessage?: string; /** Number of skeleton rows to show while loading */ loadingRows?: number; /** Additional CSS classes */ className?: string; /** Callback when sort changes */ onSortChange?: (sort: SortConfig | null) => void; /** Current sort configuration */ currentSort?: SortConfig | null; /** Built-in edit handler - adds Edit action to menu */ onEdit?: (item: T) => void | Promise<void>; /** Built-in delete handler - adds Delete action to menu */ onDelete?: (item: T) => void | Promise<void>; /** Optional custom row actions (in addition to edit/delete) */ actions?: DataTableAction<T>[]; /** Enable context menu (right-click) for row actions (default: true when actions exist) */ enableContextMenu?: boolean; /** Optional click handler for rows */ onRowClick?: (item: T) => void; /** Optional double-click handler for rows */ onRowDoubleClick?: (item: T) => void; /** Enable row selection with checkboxes */ selectable?: boolean; /** Controlled selected rows (set of row keys) */ selectedRows?: Set<string>; /** Selection change callback */ onRowSelect?: (selectedRows: string[]) => void; /** Function to extract unique key from row (defaults to row.id) */ keyExtractor?: (row: T) => string; /** Enable row expansion (legacy - use expandedRowConfig instead) */ expandable?: boolean; /** Controlled expanded rows (legacy - set of row keys) */ expandedRows?: Set<string>; /** Render function for expanded row content (legacy - use expandedRowConfig instead) */ renderExpandedRow?: (row: T) => React.ReactNode; /** NEW: Enhanced expansion configuration with multiple modes */ expandedRowConfig?: ExpandedRowConfig<T>; /** Show the expand chevron column - hidden by default when using expandedRowConfig with double-click or menu */ showExpandChevron?: boolean; /** Enable zebra striping - true for default, 'odd' or 'even' for specific rows */ striped?: boolean | 'odd' | 'even'; /** Custom color for striped rows (Tailwind class like 'bg-primary-50' or 'bg-accent-50') */ stripedColor?: string; /** Row density - affects padding and text size */ density?: 'compact' | 'normal' | 'comfortable'; /** Custom class name for rows - static string or function returning class per row */ rowClassName?: string | ((item: T, index: number) => string); /** Conditional row highlighting - returns color class (e.g., 'bg-warning-50') */ rowHighlight?: (item: T) => string | undefined; /** ID of a single row to highlight */ highlightedRowId?: string | number; /** Enable cell borders */ bordered?: boolean; /** Custom border color (Tailwind class like 'border-paper-200') */ borderColor?: string; /** Disable hover effect on rows */ disableHover?: boolean; /** Array of column keys to hide */ hiddenColumns?: string[]; /** Custom header class name */ headerClassName?: string; /** Custom empty state render function */ renderEmptyState?: () => React.ReactNode; /** Enable column resizing */ resizable?: boolean; /** Callback when column widths change */ onColumnResize?: (columnKey: string, width: number) => void; /** Enable column reordering */ reorderable?: boolean; /** Callback when column order changes */ onColumnReorder?: (newOrder: string[]) => void; /** Enable virtual scrolling for large datasets */ virtualized?: boolean; /** Container height for virtual scrolling (default: '600px') */ virtualHeight?: string; /** Row height for virtual scrolling (default: 60) */ virtualRowHeight?: number; /** Enable built-in pagination (renders Pagination component above table) */ paginated?: boolean; /** Current page number (1-indexed) */ currentPage?: number; /** Number of items per page */ pageSize?: number; /** Total number of items (for server-side pagination) */ totalItems?: number; /** Callback when page changes */ onPageChange?: (page: number) => void; /** Available page size options (default: [10, 25, 50, 100]) */ pageSizeOptions?: number[]; /** Callback when page size changes */ onPageSizeChange?: (pageSize: number) => void; /** Show page size selector (default: true when paginated) */ showPageSizeSelector?: boolean; /** Mobile view mode: 'auto' (detect viewport), 'card' (always cards), 'table' (always table) */ mobileView?: 'auto' | 'card' | 'table'; /** Configuration for card view layout */ cardConfig?: CardViewConfig<T>; /** Gap between cards in card view */ cardGap?: 'sm' | 'md' | 'lg'; /** Custom class name for cards */ cardClassName?: string; } /** * DataTable - Feature-rich data table component * * Features: * - Column sorting with visual indicators (3-state: asc → desc → none) * - Loading states (skeleton + overlay) * - Empty and error states * - Row actions with sticky column * - Row selection with checkboxes (individual + select all) * - Row expansion with custom content * - Click and double-click handlers * - Sticky header and action columns * - Fixed layout for stability * - Custom cell rendering * - Controlled or uncontrolled selection and expansion * - Column width configuration (width, minWidth, maxWidth, flex) * * @example * ```tsx * const columns: DataTableColumn<User>[] = [ * { key: 'name', header: 'Name', sortable: true, width: '200px', minWidth: '150px' }, * { key: 'email', header: 'Email', sortable: true, width: '250px' }, * { key: 'role', header: 'Role', width: '120px' }, * ]; * * const actions: DataTableAction<User>[] = [ * { label: 'Edit', icon: Edit, onClick: handleEdit }, * { label: 'Delete', icon: Trash, onClick: handleDelete, variant: 'danger' }, * ]; * * <DataTable * data={users} * columns={columns} * loading={loading} * actions={actions} * onSortChange={setSort} * onRowDoubleClick={handleRowDoubleClick} * selectable * onRowSelect={handleSelection} * expandable * renderExpandedRow={(user) => <UserDetails user={user} />} * /> * ``` */ export default function DataTable<T extends BaseDataItem = BaseDataItem>({ data, columns, loading, error, emptyMessage, loadingRows, className, onSortChange, currentSort, onEdit, onDelete, actions, enableContextMenu, onRowClick, onRowDoubleClick, selectable, selectedRows: externalSelectedRows, onRowSelect, keyExtractor, expandable, expandedRows: externalExpandedRows, renderExpandedRow, expandedRowConfig, showExpandChevron, striped, stripedColor, density, rowClassName, rowHighlight, highlightedRowId, bordered, borderColor, disableHover, hiddenColumns, headerClassName, renderEmptyState: customRenderEmptyState, resizable, onColumnResize, reorderable, onColumnReorder, virtualized, virtualHeight, virtualRowHeight, paginated, currentPage, pageSize, totalItems, onPageChange, pageSizeOptions, onPageSizeChange, showPageSizeSelector, mobileView, cardConfig, cardGap, cardClassName, }: DataTableProps<T>): import("react/jsx-runtime").JSX.Element; export {}; //# sourceMappingURL=DataTable.d.ts.map