diff --git a/README.md b/README.md index 94f9a1e..8f2879d 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ Hooks for building **lightweight, fast and extendable datagrids** for React + + + @@ -30,7 +33,7 @@ Hooks for building **lightweight, fast and extendable datagrids** for React ## Features -- Lightweight (4kb - 11kb depending on features and tree-shaking) +- Lightweight (4kb - 9kb depending on features and tree-shaking) - Headless (100% customizable, Bring-your-own-UI) - Auto out of the box, fully controllable API - Sorting (Multi and Stable) diff --git a/index.d.ts b/index.d.ts index 69f3551..6eb5524 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,184 +1,288 @@ -import { Dispatch, SetStateAction, ReactNode } from 'react'; - declare module 'react-table' { - export interface Cell { - render: (type: string) => any; - getCellProps: () => any; - column: Column; - row: Row; - state: any; - value: any; + import { ReactNode, useState } from 'react' + + type StringKey = Extract + type IdType = StringKey | string + + type SortingRule = { + id: IdType + desc: boolean + } + + export type SortingRules = SortingRule[] + + export type SortByFn = (a: any, b: any, desc: boolean) => 0 | 1 | -1 + + export type Filters = Record, string> + + export interface Cell extends TableInstance { + cell: { value: any } + column: Column + row: Row + render: (type: 'Cell' | 'Aggregated', userProps?: any) => any + isGrouped?: boolean + isAggregated?: boolean + isRepeatedValue?: boolean + getCellProps: () => any + } + + export interface Row { + index: number + cells: Cell[] + getRowProps: (userProps?: any) => any + original: D + path: any[] + values: any[] + depth: number + } + + export interface UseExpandedRow { + subRows?: D[] + groupByID?: string | number + toggleExpanded?: () => any + isExpanded?: boolean + isAggregated?: boolean + } + + export type AccessorFn = ( + originalRow: D, + index: number, + sub: { + subRows: [D] + depth: number + data: [D] } + ) => unknown - export interface Row { - index: number; - cells: Cell[]; - getRowProps: () => any; - original: any; + export interface HeaderColumn { + /** + * This string/function is used to build the data model for your column. + */ + accessor: IdType | AccessorFn + Header?: ReactNode | ((props: TableInstance) => ReactNode) + Filter?: ReactNode | ((props: TableInstance) => ReactNode) + Cell?: ReactNode | ((cell: Cell) => ReactNode) + /** + * This is the unique ID for the column. It is used by reference in things like sorting, grouping, filtering etc. + */ + id?: IdType + minWidth?: string | number + maxWidth?: string | number + width?: string | number + disableSorting?: boolean + canSortBy?: boolean + sortByFn?: SortByFn + defaultSortDesc?: boolean + isAggregated?: any + } + + export interface Column extends HeaderColumn { + show?: boolean | ((instance: TableInstance) => boolean) + columns?: Column[] + } + + export type Page = Row[] + + export interface EnhancedColumn + extends Omit, 'columns'>, + TableInstance { + id: IdType + column: Column + render: (type: 'Header' | 'Filter', userProps?: any) => any + getHeaderProps: (userProps?: any) => any + getSortByToggleProps: (userProps?: any) => any + isSorted: boolean + isSortedDesc: boolean + sortedIndex: number + isVisible: boolean + canSort?: boolean + } + + export interface HeaderGroup { + headers: EnhancedColumn[] + getHeaderGroupProps: (userProps?: any) => any + } + + export interface Hooks { + columnsBeforeHeaderGroups: any[] + columnsBeforeHeaderGroupsDeps: any[] + useMain: any[] + useColumns: any[] + useHeaders: any[] + useHeaderGroups: any[] + useRows: any[] + prepareRow: any[] + getTableProps: any[] + getRowProps: any[] + getHeaderGroupProps: any[] + getHeaderProps: any[] + getCellProps: any[] + } + + export interface RowsProps { + subRowsKey: string + } + + export interface FiltersProps { + filterFn: () => void + manualFilters: boolean + disableFilters: boolean + setFilter: () => any + setAllFilters: () => any + } + + export interface UsePaginationState { + pageIndex: number + pageSize: number + pageCount: number + rowCount: number + } + + export interface UsePaginationValues { + page: Page + pageIndex: number // yes, this is on instance and state + pageSize: number // yes, this is on instance and state + canPreviousPage: boolean + canNextPage: boolean + nextPage: () => any + previousPage: () => any + setPageSize: (size: number) => any + pageOptions: any[] + manualPagination: boolean + paginateExpandedRows: boolean + disablePageResetOnDataChange: boolean + pageCount: number + gotoPage: (page: number) => any + } + + export interface UseFiltersState { + filters?: Filters + } + + export interface UseFiltersValues { + setFilter: (columnID: keyof D, value: string) => void + setAllFilters: (values: Filters) => void + disableFilters: boolean + } + + export interface UseGroupByValues { + groupByFn: any + manualGroupBy: boolean + disableGrouping: boolean + aggregations: any + } + + export interface UseGroupByState { + groupBy: string[] + isAggregated?: boolean + } + + export interface UseExpandedValues { + toggleExpanded?: () => any + } + + export interface UseSortbyOptions { + sortByFn?: SortByFn + manualSorting?: boolean + disableSorting?: boolean + defaultSortDesc?: boolean + disableMultiSort?: boolean + } + + export interface UseSortbyState { + sortBy?: SortingRules + } + + export interface TableInstance extends TableOptions { + hooks: Hooks + rows: Row[] + columns: EnhancedColumn[] + headerGroups: HeaderGroup[] + headers: HeaderGroup[] + getTableProps: (userProps?: any) => any + getRowProps: (userProps?: any) => any + prepareRow: (row: Row) => any + } + + export interface TableOptions { + data: D[] + columns: HeaderColumn[] + state: State + debug?: boolean + loading: boolean + defaultColumn?: Partial> + } + + // The empty definition of TableState is not an error. It provides a definition + // for the state, that can then be extended in the users code. + // + // e.g. + // + // export interface TableState + // extends UsePaginationState, + // UseGroupByState, + // UseSortbyState, + // UseFiltersState {} + + // eslint-disable-next-line @typescript-eslint/no-empty-interface + export interface TableState {} + + export type SetState = ( + updater: (old: TableState) => TableState, + actions: any + ) => void + + export type State = [TableState, SetState] + + export function useTable( + props: TableOptions, + ...plugins: any[] + ): TableInstance + + export function useFilters( + props: TableOptions + ): TableOptions & { + rows: Row[] + } + + export function useSortBy( + props: TableOptions + ): TableOptions & { + rows: Row[] + } + + export function useGroupBy( + props: TableOptions + ): TableOptions & { rows: Row[] } + + export function usePagination( + props: TableOptions + ): UsePaginationValues + + export function useExpanded( + props: TableOptions + ): TableOptions & { + toggleExpandedByPath: () => any + expandedDepth: [] + rows: Row[] + } + + export function useTableState( + initialState?: Partial>, + overriddenState?: Partial>, + options?: { + reducer?: ( + oldState: TableState, + newState: TableState, + type: string + ) => any + useState?: typeof useState } + ): State - export interface HeaderColumn { - /** - * This string/function is used to build the data model for your column. - */ - accessor: A | ((originalRow: D) => string); - Header?: string | ((props: TableInstance) => ReactNode); - Filter?: string | ((props: TableInstance) => ReactNode); - Cell?: string | ((cell: Cell) => ReactNode); + export const actions: Record - /** - * This is the unique ID for the column. It is used by reference in things like sorting, grouping, filtering etc. - */ - id?: string | number; - minWidth?: string | number; - maxWidth?: string | number; - width?: string | number; - canSortBy?: boolean; - sortByFn?: (a: any, b: any, desc: boolean) => 0 | 1 | -1; - defaultSortDesc?: boolean; - } + export function addActions(...actions: string[]): void - export interface Column extends HeaderColumn { - id: string | number; - } - - export type Page = Row[]; - - export interface EnhancedColumn extends Column { - render: (type: string) => any; - getHeaderProps: (userProps?: any) => any; - getSortByToggleProps: (userProps?: any) => any; - sorted: boolean; - sortedDesc: boolean; - sortedIndex: number; - } - - export type HeaderGroup = { - headers: EnhancedColumn[]; - getRowProps: (userProps?: any) => any; - }; - - export interface Hooks { - beforeRender: []; - columns: []; - headerGroups: []; - headers: []; - rows: Row[]; - row: []; - renderableRows: []; - getTableProps: []; - getRowProps: []; - getHeaderRowProps: []; - getHeaderProps: []; - getCellProps: []; - } - - export interface TableInstance - extends TableOptions, - UseRowsValues, - UseFiltersValues, - UsePaginationValues, - UseColumnsValues { - hooks: Hooks; - rows: Row[]; - columns: EnhancedColumn[]; - getTableProps: (userProps?: any) => any; - getRowProps: (userProps?: any) => any; - prepareRow: (row: Row) => any; - getSelectRowToggleProps: (userProps?: any) => any; - toggleSelectAll: (forcedState: boolean) => any; - } - - export interface TableOptions { - data: D[]; - columns: HeaderColumn[]; - state?: [any, Dispatch>]; - debug?: boolean; - sortByFn?: (a: any, b: any, desc: boolean) => 0 | 1 | -1; - manualSorting?: boolean; - disableSorting?: boolean; - defaultSortDesc?: boolean; - disableMultiSort?: boolean; - } - - export interface RowsProps { - subRowsKey: string; - } - - export interface FiltersProps { - filterFn: () => void; - manualFilters: boolean; - disableFilters: boolean; - setFilter: () => any; - setAllFilters: () => any; - } - - export interface UsePaginationValues { - nextPage: () => any; - previousPage: () => any; - setPageSize: (size: number) => any; - gotoPage: (page: number) => any; - canPreviousPage: boolean; - canNextPage: boolean; - page: Page; - pageOptions: []; - } - - export interface UseRowsValues { - rows: Row[]; - } - - export interface UseColumnsValues { - columns: EnhancedColumn[]; - headerGroups: HeaderGroup[]; - headers: EnhancedColumn[]; - } - - export interface UseFiltersValues { - setFilter: () => any; - setAllFilters: () => any; - } - - export function useTable(props: TableOptions, ...plugins: any[]): TableInstance; - - export function useColumns(props: TableOptions): TableOptions & UseColumnsValues; - - export function useRows(props: TableOptions): TableOptions & UseRowsValues; - - export function useFilters( - props: TableOptions, - ): TableOptions & { - rows: Row[]; - }; - - export function useSortBy( - props: TableOptions, - ): TableOptions & { - rows: Row[]; - }; - - export function useGroupBy(props: TableOptions): TableOptions & { rows: Row[] }; - - export function usePagination(props: TableOptions): UsePaginationValues; - - export function useFlexLayout(props: TableOptions): TableOptions; - - export function useExpanded( - props: TableOptions, - ): TableOptions & { - toggleExpandedByPath: () => any; - expandedDepth: []; - rows: []; - }; - - export function useTableState( - initialState?: any, - overriddenState?: any, - options?: { - reducer?: (oldState: any, newState: any, type: string) => any; - useState?: [any, Dispatch>]; - }, - ): any; - - export const actions: any; -} \ No newline at end of file + export const defaultState: Record +}