/** * @bhplugin/vue3-datatable — Type Definitions * * This module exports all public types and interfaces for the Vue3 Datatable component. * All interfaces are prefixed with `I` following TypeScript naming conventions. */ /** Supported data types for column filtering and sorting behavior. */ export type IColumnType = 'string' | 'date' | 'number' | 'bool'; /** * Available filter conditions for column-level filtering. * * - **String filters:** `contain`, `not_contain`, `equal`, `not_equal`, `start_with`, `end_with` * - **Number filters:** `equal`, `not_equal`, `greater_than`, `greater_than_equal`, `less_than`, `less_than_equal` * - **Date filters:** `equal`, `not_equal`, `greater_than`, `less_than` * - **Shared:** `is_null`, `is_not_null` * - **Empty string (`''`):** Clears the active filter condition */ export type IFilterCondition = 'contain' | 'not_contain' | 'equal' | 'not_equal' | 'start_with' | 'end_with' | 'greater_than' | 'greater_than_equal' | 'less_than' | 'less_than_equal' | 'is_null' | 'is_not_null' | ''; /** * Column definition object that describes each column in the datatable. * * @example * ```ts * const columns: IColumnDefinition[] = [ * { field: 'id', title: 'ID', isUnique: true, type: 'number' }, * { field: 'name', title: 'Full Name', sort: true, filter: true }, * { field: 'email', title: 'Email', cellRenderer: (row) => `${row.email}` }, * { field: 'dob', title: 'Date of Birth', type: 'date' }, * { field: 'isActive', title: 'Active', type: 'bool' }, * ]; * ``` */ export interface IColumnDefinition { /** * Mark this column as the unique row identifier. * Used for row selection tracking, `:key` binding, and checkbox values. * Only one column should have `isUnique: true` per datatable. * @default false */ isUnique?: boolean; /** * The property path to access this column's data from each row object. * Supports nested paths with dot notation (e.g., `'address.city'`). */ field?: string; /** Display title shown in the column header. */ title?: string; /** * Current filter value for this column. * Automatically managed by the datatable when column filtering is enabled. * Can be pre-set to apply an initial filter on mount. */ value?: string | number | boolean; /** * Active filter condition for this column. * Available conditions depend on the column `type`. * @see {@link IFilterCondition} */ condition?: IFilterCondition; /** * Data type of the column. Determines which filter conditions are available * and how sorting/comparison is performed. * @default 'string' */ type?: IColumnType; /** Fixed width for this column (e.g., `'200px'`, `'15%'`). */ width?: string; /** Minimum width for this column (e.g., `'100px'`). */ minWidth?: string; /** Maximum width for this column (e.g., `'400px'`). */ maxWidth?: string; /** * Hide this column from the table. Hidden columns are excluded from rendering * but their data remains accessible. * @default false */ hide?: boolean; /** * Enable per-column filtering for this column. * Only applies when the datatable's `columnFilter` prop is `true`. * @default true */ filter?: boolean; /** * Include this column in global search matching. * When the user types in the search input, this column's values are checked. * @default true */ search?: boolean; /** * Enable sorting for this column. * Only applies when the datatable's `sortable` prop is `true`. * @default true */ sort?: boolean; /** * Whether the column content contains raw HTML. * @default false */ html?: boolean; /** * Custom cell renderer function or HTML string. * When a function is provided, it receives the full row object and should return an HTML string. * The rendered HTML is injected via `v-html`. * * @example * ```ts * cellRenderer: (row) => `${row.name}` * ``` * * **Note:** For complex rendering, prefer using named slots instead: * ```html * * * * ``` */ cellRenderer?: ((row: Record) => string) | string; /** CSS class(es) applied to the `` header cell's inner `
`. */ headerClass?: string; /** CSS class(es) applied to each `` body cell in this column. */ cellClass?: string; } /** * Payload emitted by the `@change` event in server mode. * Contains the full current state of the datatable for making server-side API requests. * * @example * ```ts * const onServerChange = (payload: IServerChangeResponse) => { * fetch('/api/data', { * method: 'POST', * body: JSON.stringify({ * page: payload.current_page, * limit: payload.pagesize, * sort: payload.sort_column, * order: payload.sort_direction, * search: payload.search, * filters: payload.column_filters, * }), * }); * }; * ``` */ export interface IServerChangeResponse { /** Current page number (1-based). */ current_page: number; /** Number of rows per page. */ pagesize: number; /** Zero-based row offset: `(current_page - 1) * pagesize`. */ offset: number; /** Column field name currently being sorted. */ sort_column: string; /** Sort direction. */ sort_direction: 'asc' | 'desc'; /** Current global search string. */ search: string; /** Array of column definitions with their current filter values and conditions. */ column_filters: IColumnDefinition[]; /** * Type of change that triggered this event. * Possible values: `'page'`, `'pagesize'`, `'sort'`, `'filter'`, `'search'`, `'reset'`. */ change_type: string; } /** * Payload emitted by the `@sortChange` event when a column sort is applied. * * @example * ```ts * const onSort = (payload: ISortChangeResponse) => { * console.log(`Sorted by ${payload.field} ${payload.direction}`); * }; * ``` */ export interface ISortChangeResponse { /** Zero-based row offset at the time of sort. */ offset: number; /** Current page size (rows per page). */ limit: number; /** Column field name that was sorted. */ field: string; /** Sort direction: `'asc'` or `'desc'`. */ direction: 'asc' | 'desc'; } /** * Props interface for the Vue3 Datatable component. * * @example * ```html * * ``` */ export interface IDataTableProps { /** * Show a loading overlay on the table. * When `true`, a spinner is displayed over the table body and pagination is disabled. * @default false */ loading?: boolean; /** * Enable server-side mode. * When `true`, the datatable does not perform client-side sorting, filtering, or pagination. * Instead, it emits events and expects the parent to provide pre-processed data. * @default false */ isServerMode?: boolean; /** * CSS class(es) applied to the `` element for visual styling. * Built-in skins: `'bh-table-striped'`, `'bh-table-hover'`, `'bh-table-bordered'`, `'bh-table-compact'`. * @default 'bh-table-striped bh-table-hover' */ skin?: string; /** * Total number of rows across all pages. * **Required in server mode** for correct pagination calculation. * Ignored in client mode (computed automatically from `rows.length`). * @default 0 */ totalRows?: number; /** * Array of row data objects to display. * Each object's keys should correspond to the `field` values defined in `columns`. * @default [] */ rows?: Array>; /** * Array of column definitions that describe the table structure. * @see {@link IColumnDefinition} * @default [] */ columns?: Array; /** * Show a checkbox column as the first column for row selection. * Selected rows can be retrieved via the `getSelectedRows()` exposed method. * @default false */ hasCheckbox?: boolean; /** * Global search string. When non-empty, rows are filtered to those containing * the search string in any searchable column (columns with `search: true`). * In server mode, the value is passed in the `@change` payload for server-side filtering. * @default '' */ search?: string; /** * Current page number (1-based). * In server mode, used to sync the datatable's page with the parent's state. * @default 1 */ page?: number; /** * Number of rows displayed per page. * @default 10 */ pageSize?: number; /** * Options shown in the "rows per page" dropdown selector. * @default [10, 20, 30, 50, 100] */ pageSizeOptions?: Array; /** * Show the page size dropdown selector in the pagination area. * @default true */ showPageSize?: boolean; /** * CSS class(es) applied to each `` row element. * Can be a static string, array of strings, or a function that receives the row data * and returns a class string. * * @example * ```ts * // Static * rowClass: 'my-row' * * // Dynamic * rowClass: (row) => row.isActive ? 'active-row' : 'inactive-row' * ``` * @default '' */ rowClass?: string | string[] | ((row: Record) => string); /** * CSS class(es) applied to each `
` cell element. * Accepts the same types as `rowClass`. * @default '' */ cellClass?: string | string[] | ((row: Record) => string); /** * Enable column sorting. When `true`, clicking a column header sorts the data. * Individual columns can opt out via `sort: false` in their column definition. * @default false */ sortable?: boolean; /** * Initial sort column field name. * @default '' */ sortColumn?: string; /** * Initial sort direction. * @default 'asc' */ sortDirection?: 'asc' | 'desc'; /** * Enable per-column filter inputs below each column header. * Each column can opt out via `filter: false` in its column definition. * @default false */ columnFilter?: boolean; /** * Custom labels for column filter condition dropdown menu items. * Pass a Record mapping condition keys to display strings for i18n support. * * @example * ```ts * columnFilterLang: { * no_filter: 'Kein Filter', * contain: 'Enthält', * equal: 'Gleich', * all: 'Alle', * true: 'Wahr', * false: 'Falsch', * // ... * } * ``` * @default null */ columnFilterLang?: Record | null; /** * Show the pagination area below the table. * @default true */ pagination?: boolean; /** * Show numbered page buttons in the pagination area. * @default true */ showNumbers?: boolean; /** * Maximum number of page number buttons visible at once. * Additional pages are accessible via prev/next buttons. * @default 5 */ showNumbersCount?: number; /** * Show the "first page" navigation button. * @default true */ showFirstPage?: boolean; /** * Show the "last page" navigation button. * @default true */ showLastPage?: boolean; /** * Template string for pagination info text. * Placeholders: `{0}` = start row, `{1}` = end row, `{2}` = total rows. * @default 'Showing {0} to {1} of {2} entries' */ paginationInfo?: string; /** * Text displayed when the table has no data and is not loading. * @default 'No data available' */ noDataContent?: string; /** * Number of skeleton rows rendered while loading. * @default 10 */ skeletonRowCount?: number; /** * Make the table header sticky so it remains visible when scrolling vertically. * Requires `height` to be set for the scrollable container. * @default false */ stickyHeader?: boolean; /** * Height of the scrollable table container. Only takes effect when `stickyHeader` is `true`. * @default '500px' */ height?: string; /** * Make the first data column sticky (fixed to the left) when scrolling horizontally. * @default false */ stickyFirstColumn?: boolean; /** * Clone the table header as a footer row at the bottom of the table. * @default false */ cloneHeaderInFooter?: boolean; /** * Toggle row selection when clicking anywhere on the row (not just the checkbox). * @default false */ selectRowOnClick?: boolean; }