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;
