import { SvelteComponentTyped } from "svelte"; import type { SvelteHTMLElements } from "svelte/elements"; export type DataTableValue = any; export interface DataTableRow { id: Id; [key: string]: DataTableValue; } export type DataTableKey = [ keyof import("./data-table-utils.d.ts").KeysWithoutIndexSignature, ] extends [never] ? import("./data-table-utils.d.ts").PropertyPath : keyof import("./data-table-utils.d.ts").KeysWithoutIndexSignature extends "id" ? import("./data-table-utils.d.ts").PropertyPath : Row extends DataTableRow ? import("./data-table-utils.d.ts").PropertyPathIgnoringIndexSignatures : import("./data-table-utils.d.ts").PropertyPath; /** * Path keys for sort, headers, and cells; mirrors PropertyPath / PropertyPathIgnoringIndexSignatures in ./data-table-utils.d.ts. */ export type DataTableSortValue = import("./data-table-utils.d.ts").DataTableSortValue; export type DataTableEmptyHeader = { key: DataTableKey | (string & {}); /** Whether the header is empty */ empty: true; display?: (item: DataTableValue, row: Row) => DataTableValue; sort?: | false | ((a: DataTableSortValue, b: DataTableSortValue) => number); /** Override table-level sortAlways for this column */ sortAlways?: boolean; /** Whether the column menu is enabled */ columnMenu?: boolean; width?: string; minWidth?: string; }; export type DataTableNonEmptyHeader = { key: DataTableKey; empty?: false; value: DataTableValue; display?: (item: DataTableValue, row: Row) => DataTableValue; sort?: | false | ((a: DataTableSortValue, b: DataTableSortValue) => number); /** Override table-level sortAlways for this column */ sortAlways?: boolean; /** Whether the column menu is enabled */ columnMenu?: boolean; width?: string; minWidth?: string; }; export type DataTableHeader = | DataTableNonEmptyHeader | DataTableEmptyHeader; export type DataTableCell = { key: DataTableKey | (string & {}); value: DataTableValue; display?: (item: DataTableValue, row: DataTableRow) => DataTableValue; }; export interface DataTableRowClassArgs { row: Row; rowIndex: number; selected: boolean; expanded: boolean; } export type DataTableRowClass = | string | ((row: DataTableRowClassArgs) => string | undefined); export type CarbonDataTableContext = { batchSelectedIds: import("svelte/store").Writable>; tableRows: import("svelte/store").Writable>; /** Exposes the table size to slotted content (e.g. `Toolbar`) so it can derive a matching size unless explicitly overridden. */ tableSize: import("svelte/store").Writable< "compact" | "short" | "medium" | "tall" | undefined >; resetSelectedRowIds: () => void; filterRows: ( searchValue: string, customFilter?: (row: Row, value: string) => boolean, ) => ReadonlyArray; /** Rebuild cells for a single row after an in-place edit to `rows`. */ refreshRow: (id: Row["id"]) => void; /** Rebuild cells for every row after batch in-place edits to `rows`. */ refreshCells: () => void; }; type $RestProps = SvelteHTMLElements["div"]; type $Props = { /** * Specify the data table headers. * @default [] */ headers?: ReadonlyArray>; /** * Specify the rows the data table should render. * Keys defined in `headers` are used for the row ids. * @default [] */ rows?: ReadonlyArray; /** * Set the size of the data table. * @default undefined */ size?: "compact" | "short" | "medium" | "tall"; /** * Specify the title of the data table * @default "" */ title?: string; /** * Specify the description of the data table * @default "" */ description?: string; /** * Specify a custom class name for each row. * Provide a function to return a class name based * on row properties, allowing conditional classes * based on selected/expanded state. * @example * ```svelte * { * return `row-${rowIndex} ${selected ? 'selected' : ''} ${expanded ? 'expanded' : ''}`; * }} /> * ``` * @default undefined */ rowClass?: DataTableRowClass; /** * Specify a name attribute for the input elements * in a selectable data table (radio or checkbox). * When the table is inside a form, this name will * be included in the form data on submit. * @default `ccs-${Math.random().toString(36)}` */ inputName?: string; /** * Set to `true` to use zebra styles * @default false */ zebra?: boolean; /** * Set to `true` for the sortable variant * @default false */ sortable?: boolean; /** * Specify the header key to sort by. * @default null */ sortKey?: DataTableKey; /** * Specify the sort direction. * @default "none" */ sortDirection?: "none" | "ascending" | "descending"; /** * Set to `true` to only toggle between "ascending" and * "descending" sort directions, skipping "none". * @default false */ sortAlways?: boolean; /** * Specify a default sort comparator for all sortable columns. * Per-header `sort` functions take precedence over this prop. * * With a typed row generic, `a` and `b` are {@link DataTableSortValue} (the union of cell value types over every {@link DataTableKey} on `Row`). Narrow using `context.key` (typed as {@link DataTableKey}) or runtime checks. * @example * ```svelte * { * switch (key) { * case "expireDate": * return new Date(a) - new Date(b); * case "port": * return a - b; * default: * return String(a).localeCompare(String(b)); * } * }} * /> * ``` * @default undefined */ sort?: ( a: DataTableSortValue, b: DataTableSortValue, context: { key: DataTableKey; ascending: boolean; row_a: Row; row_b: Row; }, ) => number; /** * Set to `true` for the expandable variant. * Automatically set to `true` if `batchExpansion` is `true`. * @default false */ expandable?: boolean; /** * Set to `true` to enable batch expansion. * @default false */ batchExpansion?: boolean; /** * Specify the row ids to be expanded. * @default [] */ expandedRowIds?: ReadonlyArray; /** * Specify the ids for rows that should not be expandable. * @default [] */ nonExpandableRowIds?: ReadonlyArray; /** * Set to `true` for the radio selection variant * @default false */ radio?: boolean; /** * Set to `true` for the selectable variant. * Automatically set to `true` if `radio` or `batchSelection` are `true`. * @default false */ selectable?: boolean; /** * Set to `true` to enable batch selection * @default false */ batchSelection?: boolean; /** * Specify the row ids to be selected. * @default [] */ selectedRowIds?: ReadonlyArray; /** * Specify the ids of rows that should not be selectable. * @default [] */ nonSelectableRowIds?: ReadonlyArray; /** * Specify the row ids to highlight. * Adds `bx--data-table--highlighted-row`. The highlighted row class is themed by default. * @default [] */ highlightedRowIds?: ReadonlyArray; /** * Set to `true` to enable a sticky header * @default false */ stickyHeader?: boolean; /** * Override the maximum height of the sticky header table, replacing the * default `300px`. Only applies when `stickyHeader` is `true`. Pass a number * (interpreted as `px`) or a CSS length string (e.g. `"100%"`, `"24rem"`). * @default undefined */ stickyHeaderMaxHeight?: number | string; /** * Set to `true` to use static width * @default false */ useStaticWidth?: boolean; /** * Set the filtering strategy used by `ToolbarSearch`. * - `"remove"`: remove non-matching rows from the DOM and recreate them when the * filter clears. * - `"hide"`: keep all rows mounted and hide non-matching rows with the `hidden` * attribute, preserving focus, inputs, and open menus. * * `"hide"` falls back to `"remove"` when `pageSize` is set or `virtualize` is enabled. * @default "remove" */ filterMode?: "remove" | "hide"; /** * Specify the number of items to display in a page * @default 0 */ pageSize?: number; /** * Set to `number` to set current page * @default 0 */ page?: number; /** * Enable virtualization for large row lists. Virtualization renders only the rows currently visible in the viewport, improving performance for large datasets. * * Virtualization is opt-in. Set `virtualize={true}` to enable with default settings, or pass a configuration object to customize. * Virtualized tables are intended for use with `stickyHeader={true}` so the header stays visible while scrolling. Pagination is ignored when virtualization is enabled. * Virtualization assumes a uniform row height; combining it with `expandable` rows is not supported and may cause incorrect scroll-spacer sizing when rows are expanded mid-list. * * Provide an object to customize virtualization behavior: * - `itemHeight` (default: 48 for medium size, adjusted for size variant): The height in pixels of each row. Specify a custom value when using custom slots with multi-line content or different heights. * - `maxVisibleRows` (default: 10): The maximum number of rows to display in the viewport. The container height will be calculated as `itemHeight * maxVisibleRows`. Overridden by `containerHeight` if explicitly provided. * - `containerHeight` (default: calculated from maxVisibleRows): The maximum height in pixels of the table body container. If not provided, calculated from `itemHeight * maxVisibleRows`. * - `overscan` (default: 3): The number of extra rows to render above and below the viewport for smoother scrolling. Higher values may cause more flickering during very fast scrolling. * - `threshold` (default: 100): The minimum number of rows required before virtualization activates. Tables with fewer rows will render all rows normally without virtualization. * - `maxItems` (default: undefined): The maximum number of rows to render. When undefined, all visible rows are rendered. * @default undefined */ virtualize?: | undefined | boolean | { itemHeight?: number; maxVisibleRows?: number; containerHeight?: number; overscan?: number; threshold?: number; maxItems?: number; }; /** * Obtain a reference to the table wrapper element. When virtualization is enabled and `stickyHeader` is false, this element is the scroll container—use `bind:scrollContainerRef` to programmatically control scroll position (e.g. `scrollContainerRef.scrollTop = 0`). * @default null */ scrollContainerRef?: null | HTMLDivElement; /** * Override the default table header translation ids. * @default undefined */ tableHeaderTranslateWithId?: ( id: import("./TableHeader.svelte").TableHeaderTranslationId, ) => string; cell?: ( this: void, ...args: [ { row: Row; cell: DataTableCell; rowIndex: number; cellIndex: number; rowSelected: boolean; rowExpanded: boolean; }, ] ) => void; cellHeader?: ( this: void, ...args: [{ header: DataTableNonEmptyHeader }] ) => void; descriptionChildren?: ( this: void, ...args: [{ props: { class: "bx--data-table-header__description" } }] ) => void; expandIcon?: ( this: void, ...args: [ { expanded: boolean; row: Row | undefined; props: { "aria-hidden": "true" | "false"; class: string }; }, ] ) => void; expandedRow?: ( this: void, ...args: [{ row: Row; rowSelected: boolean }] ) => void; titleChildren?: ( this: void, ...args: [{ props: { class: "bx--data-table-header__title" } }] ) => void; children?: (this: void) => void; [key: `data-${string}`]: unknown; }; export type DataTableProps = Omit< $RestProps, keyof $Props > & $Props; export default class DataTable< Row extends DataTableRow = DataTableRow, > extends SvelteComponentTyped< DataTableProps, { click: CustomEvent<{ header?: DataTableHeader; row?: Row; cell?: DataTableCell; }>; "click:cell": CustomEvent<{ cell: DataTableCell; target: EventTarget; currentTarget: EventTarget; rowClass?: DataTableRowClass; }>; "click:header": CustomEvent<{ header: DataTableHeader; /** The intended next sort direction for this click, reported regardless of whether the `sort` event was cancelled. */ sortDirection?: "ascending" | "descending" | "none"; target: EventTarget; currentTarget: EventTarget; }>; "click:header--expand": CustomEvent<{ expanded: boolean; }>; "click:header--select": CustomEvent<{ indeterminate: boolean; selected: boolean; }>; "click:row": CustomEvent<{ row: Row; target: EventTarget; currentTarget: EventTarget; }>; "click:row--expand": CustomEvent<{ expanded: boolean; row: Row; }>; "click:row--select": CustomEvent<{ selected: boolean; row: Row; }>; "mouseenter:row": CustomEvent; "mouseleave:row": CustomEvent; /** Dispatched when a sortable column header would change the active sort. The event is cancelable: call `preventDefault()` to skip updating `sortKey` / `sortDirection` and skip client side sorting for that click (for example full server side sorting while still reading `detail.key` / `detail.direction` for your API). If not cancelled, the table applies the new sort and sorts the current `rows` client side. Typical uses: server side sorting, URL or query string sync, analytics, and persisting sort preferences. */ sort: CustomEvent< | { key: null; direction: "none" } | { key: DataTableKey; direction: "ascending" | "descending" } >; }, { default: Record; cell: { row: Row; cell: DataTableCell; rowIndex: number; cellIndex: number; rowSelected: boolean; rowExpanded: boolean; }; cellHeader: { header: DataTableNonEmptyHeader }; descriptionChildren: { props: { class: "bx--data-table-header__description" }; }; expandIcon: { expanded: boolean; row: Row | undefined; props: { "aria-hidden": "true" | "false"; class: string }; }; expandedRow: { row: Row; rowSelected: boolean }; titleChildren: { props: { class: "bx--data-table-header__title" } }; } > { /** * Rebuild cells for a single row after an in-place edit to `rows`. * @example * ```svelte * * dataTable.refreshRow(row.id)} /> * ``` */ refreshRow: (id: Row["id"]) => void; /** * Rebuild cells for every row after batch in-place edits to `rows`. * @example * ```svelte * * * ``` */ refreshCells: () => void; }