UNPKG

@tiller-ds/data-display

Version:

Data display module of Tiller Design System

322 lines (321 loc) 14.1 kB
import * as React from "react"; import { Cell, Row } from "react-table"; import { CardHeaderProps } from "@tiller-ds/core"; import { ComponentTokens, TokenProps } from "@tiller-ds/theme"; declare type DataTableChild<T extends object> = React.ReactElement<DataTableColumnProps<T> | DataTableExpanderProps<T>> | React.ReactElement<DataTableColumnProps<T> | DataTableExpanderProps<T>>[] | boolean | undefined; export declare type DataTableProps<T extends object> = { /** * Aligns the headers of the data table to a specific position. */ alignHeader?: "left" | "right" | "center" | "justify"; /** * Children wrapped in the data table. Most often DataTable.Column, DataTable.Selector, * DataTable.CardHeader, etc. */ children: DataTableChild<T> | DataTableChild<T>[]; /** * Data array of any type to be shown in the data table. */ data: T[]; /** * Receives an object array of type SortInfo (column, sortDirection) and sorts * the data table accordingly. Column attribute represents a string which corresponds * to a certain column name, while sortDirection is either ASCENDING or DESCENDING. */ defaultSortBy?: SortInfo[]; /** * Controls table sorting behavior when clicking a column header by returning to a default sorted state defined by `defaultSortBy` prop when sort resets. * * By default, clicking a column header cycles through sorting states, and a sort reset returns the table to an unsorted state. * Setting this prop to `true` prevents this default behavior. * * With this prop enabled, clicking the header of a column defined in `defaultSortBy` will toggle between ascending and descending order **even after a sort reset**. * This allows you to maintain the initial sort order throughout user interaction. * * @defaultValue false */ retainDefaultSortBy?: boolean; /** * For getting each item's unique identifier on DataTable initialization. * Ex. (item: Item) => item.id */ getItemId?: (item: T, index: number) => string | number; /** * Useful for styling each row conditionally. For example, if item's id % 2 === 0 * set the row class name to pink (return pink), otherwise return purple. */ getRowClassName?: (values: T, index: number) => string; /** * Hook for connecting the data table to a variable which uses the 'useDataTable()' hook. * The hook manages selection of items in the data table, sorting, etc. */ hook?: DataTableHook; /** * Makes the rows clickable and executes a custom function when a single click is executed. * The function takes the entity of a clicked row as a parameter. * * @note If a button is placed within a row, ensure to call `e.stopPropagation()` within its * `onClick` event handler to prevent event bubbling and unintended triggering of the * row's `onClick` handler. This isolates button actions and prevents conflicts. */ onClick?: (rowValue: T) => void; /** * Makes the rows double clickable and executes a custom function when a double click is executed. * The function takes the entity of a clicked row as a parameter. * * @note If a button is placed within a row, ensure to call `e.stopPropagation()` within its * `onDoubleClick` event handler to prevent event bubbling and unintended triggering of the * row's `onDoubleClick` handler. This isolates button actions and prevents conflicts. */ onDoubleClick?: (rowValue: T) => void; /** * Identifies the row which can be edited. */ rowEditingIndex?: number; /** * Determines whether the row can be saved according to its value. * Useful if, for example, a validation fails, and you want to disable the save button accordingly. */ saveEnabled?: boolean; /** * Enables the display of a footer below the data table. */ showFooter?: boolean; /** * Enables the display of a header above the data table. */ showHeader?: boolean; /** * Enables fixed first column in horizontal scroll data table. */ firstColumnFixed?: boolean; /** * Enables fixed last column in horizontal scroll data table. */ lastColumnFixed?: boolean; /** * Custom classes for the container. * Overrides conflicting default styles, if any. * * The provided `className` is processed using `tailwind-merge` to eliminate redundant or conflicting Tailwind classes. */ className?: string; /** * Content to be displayed when the dataset is empty. */ emptyState?: React.ReactNode; /** * Enable or disable multi-column sorting. * When set to true, users can sort by multiple columns simultaneously. */ multiSort?: boolean; /** * A unique identifier for testing purposes. * This identifier can be used in testing frameworks like Jest or Cypress to locate specific elements for testing. * It helps ensure that UI components are behaving as expected across different scenarios. * @type {string} * @example * // Usage: * <MyComponent data-testid="my-component" /> * // In tests: * getByTestId('my-component'); */ "data-testid"?: string; } & DataTableTokensProps; declare type DataTableTokensProps = { tokens?: ComponentTokens<"DataTable">; }; declare type Meta = { isEditMode: boolean; }; declare type DataTableColumnProps<T extends object> = { /** * Represents the column label in the header (not exclusively text). */ header?: React.ReactNode; /** * Represents the column label in the footer (not exclusively text). * Note that the default value of the showFooter DataTable prop is false, so it needs to be set to true. */ footer?: React.ReactNode; /** * The title prop adds a tooltip with title text to the table header/footer cell. * Hovering the mouse over the header/footer cell will display the tooltip. */ title?: string; /** * Custom classes for the container. * Overrides conflicting default styles, if any. * * The provided `className` is processed using `tailwind-merge` to eliminate redundant or conflicting Tailwind classes. */ className?: string; /** * Determines whether this column is sortable when clicking on its header. */ canSort?: boolean; /** * Defines the number of columns a cell should span. */ colSpan?: number; /** * Aligns the column data to a specific position. */ align?: "left" | "right" | "center" | "justify"; } & ({ /** * Accessor is the key in the data (used for mapping column to the matching data). * (check here for details: https://react-table-v7.tanstack.com/docs/api/useTable#column-options). */ accessor: string; } | { /** * Additional options to pass onto as children of the column. * item: describes current item shown in the cell. * index: represents the index of the item (starting at 0). * row: check https://react-table-v7.tanstack.com/docs/api/useTable#row-properties. * isEditMode: returns true if the column is currently in edit mode. * saveEnabled: returns false if there is no value present in the selected column (useful for disabling save buttons when editing). */ children: (item: T, index: number, row: Row<T>, isEditMode: Meta, saveEnabled: boolean) => React.ReactNode; /** * Unique ID for the column. It is used by reference in things like sorting, grouping, filtering etc. * If a string accessor is used, it defaults as the column ID, but can be overridden if necessary. */ id: string; }) & TokenProps<"DataTable">; declare type DataTableExpanderProps<T extends object> = { /** * Defines whether a given row should be expandable. * * @param {T} item - The data item for the row. * @param {number} index - The index of the row. * @returns {boolean} - Returns true if the row is expandable, otherwise false. */ predicate?: (item: T, index: number) => boolean; /** * The component rendered when the predicate prop is not satisfied. * * @param {T} item - The data item for the row. * @param {number} index - The index of the row. * @returns {React.ReactNode} - The custom component to render. */ predicateFallback?: (item: T, index: number) => React.ReactNode; /** * Expander content displayed when the expander is clicked. * * @param {T} item - The data item for the row. * @param {number} index - The index of the row. * @returns {React.ReactNode} - The content to display in the expanded row. */ children: (item: T, index: number) => React.ReactNode; /** * Custom classes for the container. * Overrides conflicting default styles, if any. * * The provided `className` is processed using `tailwind-merge` to eliminate redundant or conflicting Tailwind classes. */ className?: string; }; declare type DataTableSelectorProps<T extends object> = { /** * Defines whether a given row should be selectable. */ predicate?: (item: T, index: number) => boolean; children?: (item: T, index: number, row: Row<T>, predicate: boolean) => React.ReactNode; }; declare type DataTableCardHeaderProps = { /** * Content wrapped in the data table card header. Most often DataTable.CardHeader.Title and DataTable.CardHeader.Actions. */ children?: React.ReactNode; /** * Selects the desired number of rows and shows message in header that this number of rows are selected. */ selectedCount: number; /** * Selects all rows in DataTable and shows message in header that all rows are selected. */ isAllRowsSelected: boolean; /** * Changes the number of total elements in the message when selecting rows (e.g. 5 selected out of {totalElements} items). */ totalElements: number; } & CardHeaderProps & TokenProps<"DataTable">; declare type DataTableHook = { setSelected: (selection: Record<string, boolean>, isAllRowsSelected: boolean) => void; setSortBy: (sort: SortInfo[]) => void; selected: Record<string, boolean>; isAllRowsSelected: boolean; toggleSelectAll: () => void; }; export declare type SortInfo = { column: string; sortDirection: "ASCENDING" | "DESCENDING"; }; declare type DataTablePrimaryRowProps = { children: React.ReactNode; }; declare type DataTableSecondaryRowProps = { children: React.ReactNode; }; declare type UseDataTable = [{ selected: Record<string, boolean>; selectedCount: number; isAllRowsSelected: boolean; sortBy: SortInfo[]; defaultSortBy: SortInfo[]; }, DataTableHook]; declare type DataTableCardHeaderSelectorProps = { children?: (selectorInfo: SelectorInfo) => React.ReactNode; }; declare type SelectorInfo = { selectedCount: React.ReactNode; totalElements: React.ReactNode; }; declare type DataTableContext<T> = { data: T[]; totalNumberOfElements: number; hook?: DataTableHook; getItemId: (item: T, index: number) => string | number; predicate: (item: T, index: number) => boolean; }; declare const DataTableContext: React.Context<DataTableContext<any> | undefined>; export declare function useDataTableContext<T = unknown>(): DataTableContext<T>; declare type UseDataTableProps = { defaultSortBy?: SortInfo[]; }; export declare function useDataTable({ defaultSortBy }?: UseDataTableProps): UseDataTable; declare type Operation = "sum" | "average"; declare type DataTableSummary<T> = { key: keyof T; operation: Operation; }; export declare function useLocalSummary<T>(data: T[], summaryList: DataTableSummary<T>[]): Record<keyof T, Record<Operation, number>>; declare function DataTable<T extends object>({ data, hook, showHeader, alignHeader, showFooter, children, defaultSortBy, getItemId, onClick, onDoubleClick, getRowClassName, rowEditingIndex, saveEnabled, firstColumnFixed, lastColumnFixed, className, multiSort, retainDefaultSortBy, ...props }: DataTableProps<T>): JSX.Element; declare function DataTablePrimaryRow({ children }: DataTablePrimaryRowProps): JSX.Element; declare function DataTableSecondaryRow({ children }: DataTableSecondaryRowProps): JSX.Element; declare function DataTableCardHeader({ totalElements, selectedCount, isAllRowsSelected, children, ...props }: DataTableCardHeaderProps): JSX.Element; declare namespace DataTableCardHeader { var Title: typeof import("../../../dist/libs/core/Card").CardHeaderTitle; var Actions: typeof import("../../../dist/libs/core/Card").CardHeaderActions; var Selector: typeof DataTableCardHeaderSelector; } declare function DataTableCardHeaderSelector({ children }: DataTableCardHeaderSelectorProps): JSX.Element | null; declare function SelectorCell<T extends object>({ row, ...props }: Pick<Cell<T>, "row"> & { "data-testid"?: string; }): JSX.Element; declare function DataTableColumn<T extends object>(_: DataTableColumnProps<T>): JSX.Element; declare function DataTableExpander<T extends object>(_: DataTableExpanderProps<T>): JSX.Element; declare function DataTableSelector<T extends object>(_: DataTableSelectorProps<T>): JSX.Element; declare type DataTable = typeof DataTable & { Column: typeof DataTableColumn; Expander: typeof DataTableExpander; Selector: typeof DataTableSelector; SelectorCell: typeof SelectorCell; CardHeader: typeof DataTableCardHeader; PrimaryRow: typeof DataTablePrimaryRow; SecondaryRow: typeof DataTableSecondaryRow; }; declare const MemoDataTable: DataTable; export default MemoDataTable;