its-just-ui
Version:
ITS Just UI - The easiest and best React UI component library. Modern, accessible, and customizable components built with TypeScript and Tailwind CSS. Simple to use, production-ready components for building beautiful user interfaces with ease.
368 lines (366 loc) • 13.5 kB
TypeScript
import { ReactNode, CSSProperties, HTMLAttributes, TdHTMLAttributes, ThHTMLAttributes } from 'react';
export type TableVariant = 'default' | 'striped' | 'bordered' | 'minimal' | 'card-style' | 'compact';
export type TableSize = 'sm' | 'md' | 'lg';
export type TableStatus = 'default' | 'success' | 'warning' | 'error' | 'info';
export type SortDirection = 'asc' | 'desc' | null;
export type SelectionMode = 'none' | 'single' | 'multiple';
export type EditMode = 'none' | 'cell' | 'row' | 'inline';
export type FilterMatchMode = 'contains' | 'startsWith' | 'endsWith' | 'equals' | 'notEquals' | 'custom';
export type PaginationMode = 'client' | 'server';
export type AnimationType = 'fade' | 'slide' | 'scale' | 'none';
export interface ColumnDef<TData = RowData> {
id: string;
accessorKey?: keyof TData | string;
accessorFn?: (row: TData) => unknown;
header?: string | ((props: {
column: ColumnDef<TData>;
}) => ReactNode);
cell?: (props: {
value: unknown;
row: TData;
column: ColumnDef<TData>;
rowIndex: number;
}) => ReactNode;
footer?: string | ((props: {
column: ColumnDef<TData>;
}) => ReactNode);
width?: number | string;
minWidth?: number;
maxWidth?: number;
sortable?: boolean;
sortingFn?: (rowA: TData, rowB: TData, columnId: string) => number;
filterable?: boolean;
filterFn?: (row: TData, columnId: string, filterValue: unknown) => boolean;
editable?: boolean;
editComponent?: (props: {
value: unknown;
row: TData;
column: ColumnDef<TData>;
onSave: (value: unknown) => void;
onCancel: () => void;
}) => ReactNode;
align?: 'left' | 'center' | 'right';
className?: string;
headerClassName?: string;
cellClassName?: string | ((props: {
row: TData;
value: unknown;
}) => string);
footerClassName?: string;
sticky?: 'left' | 'right';
hidden?: boolean;
group?: string;
meta?: Record<string, unknown>;
}
export interface SortDescriptor {
columnId: string;
direction: SortDirection;
}
export interface FilterDescriptor {
columnId: string;
value: unknown;
matchMode?: FilterMatchMode;
}
export type SelectionModel = Set<string | number>;
export interface PaginationState {
pageIndex: number;
pageSize: number;
}
export type ExpandedState = Set<string | number>;
export interface EditingState {
rowId: string | number;
columnId: string;
value: unknown;
}
export interface GroupDef<TData = RowData> {
columnId: string;
aggregationFn?: (rows: TData[]) => unknown;
header?: (props: {
group: GroupDef<TData>;
rows: TData[];
value: unknown;
}) => ReactNode;
}
export interface RowData {
id: string | number;
[key: string]: unknown;
}
export interface TableBaseProps<TData extends RowData = RowData> {
data: TData[];
columns: ColumnDef<TData>[];
getRowId?: (row: TData, index: number) => string | number;
variant?: TableVariant;
size?: TableSize;
loading?: boolean;
loadingComponent?: ReactNode;
empty?: boolean;
emptyComponent?: ReactNode;
disabled?: boolean;
selectionMode?: SelectionMode;
selectedRows?: SelectionModel;
defaultSelectedRows?: SelectionModel;
onSelectionChange?: (selection: SelectionModel) => void;
isRowSelectable?: (row: TData) => boolean;
enableSorting?: boolean;
sort?: SortDescriptor[];
defaultSort?: SortDescriptor[];
onSortChange?: (sort: SortDescriptor[]) => void;
enableMultiSort?: boolean;
maxMultiSortColCount?: number;
enableFiltering?: boolean;
filters?: FilterDescriptor[];
defaultFilters?: FilterDescriptor[];
onFiltersChange?: (filters: FilterDescriptor[]) => void;
globalFilter?: string;
onGlobalFilterChange?: (value: string) => void;
enablePagination?: boolean;
paginationMode?: PaginationMode;
pagination?: PaginationState;
defaultPagination?: PaginationState;
onPaginationChange?: (pagination: PaginationState) => void;
totalCount?: number;
pageSizeOptions?: number[];
enableExpanding?: boolean;
expandedRows?: ExpandedState;
defaultExpandedRows?: ExpandedState;
onExpandedChange?: (expanded: ExpandedState) => void;
expandedContent?: (props: {
row: TData;
rowIndex: number;
}) => ReactNode;
editMode?: EditMode;
editingCell?: EditingState | null;
onEditingCellChange?: (editing: EditingState | null) => void;
onEditCommit?: (rowId: string | number, columnId: string, value: unknown, row: TData) => void | Promise<void>;
onEditCancel?: (rowId: string | number, columnId: string) => void;
enableGrouping?: boolean;
groupBy?: string[];
groups?: GroupDef<TData>[];
enableVirtualization?: boolean;
virtualizer?: unknown;
enableColumnResizing?: boolean;
enableColumnReordering?: boolean;
enableRowReordering?: boolean;
stickyHeader?: boolean;
stickyColumns?: boolean;
onRowClick?: (row: TData, rowIndex: number, event: React.MouseEvent) => void;
onRowDoubleClick?: (row: TData, rowIndex: number, event: React.MouseEvent) => void;
onCellClick?: (row: TData, column: ColumnDef<TData>, rowIndex: number, event: React.MouseEvent) => void;
onCellDoubleClick?: (row: TData, column: ColumnDef<TData>, rowIndex: number, event: React.MouseEvent) => void;
rowRenderer?: (props: {
row: TData;
rowIndex: number;
children: ReactNode;
}) => ReactNode;
noDataRenderer?: () => ReactNode;
loadingRenderer?: () => ReactNode;
animationType?: AnimationType;
animationDuration?: number;
borderWidth?: string;
borderColor?: string;
borderStyle?: string;
borderRadius?: string;
fontSize?: string;
fontWeight?: string;
fontFamily?: string;
textColor?: string;
headerTextColor?: string;
backgroundColor?: string;
headerBackgroundColor?: string;
footerBackgroundColor?: string;
rowHoverBackground?: string;
rowSelectedBackground?: string;
alternateRowBackground?: string;
focusRingColor?: string;
focusRingWidth?: string;
focusRingOffset?: string;
focusBorderColor?: string;
focusBackgroundColor?: string;
boxShadow?: string;
focusBoxShadow?: string;
padding?: string;
paddingX?: string;
paddingY?: string;
headerPadding?: string;
cellPadding?: string;
footerPadding?: string;
headerStyle?: CSSProperties;
headerClassName?: string;
bodyStyle?: CSSProperties;
bodyClassName?: string;
footerStyle?: CSSProperties;
footerClassName?: string;
rowStyle?: CSSProperties | ((row: TData, rowIndex: number) => CSSProperties);
rowClassName?: string | ((row: TData, rowIndex: number) => string);
cellStyle?: CSSProperties | ((row: TData, column: ColumnDef<TData>) => CSSProperties);
cellClassName?: string | ((row: TData, column: ColumnDef<TData>) => string);
sortAscIcon?: ReactNode;
sortDescIcon?: ReactNode;
sortNeutralIcon?: ReactNode;
expandIcon?: ReactNode;
collapseIcon?: ReactNode;
selectIcon?: ReactNode;
selectAllIcon?: ReactNode;
filterIcon?: ReactNode;
clearFilterIcon?: ReactNode;
'aria-label'?: string;
'aria-labelledby'?: string;
'aria-describedby'?: string;
captionComponent?: ReactNode;
}
export interface TableContextValue<TData extends RowData = RowData> {
data: TData[];
columns: ColumnDef<TData>[];
getRowId: (row: TData, index: number) => string | number;
variant: TableVariant;
size: TableSize;
loading: boolean;
empty: boolean;
disabled: boolean;
selectionMode: SelectionMode;
selectedRows: SelectionModel;
setSelectedRows: (selection: SelectionModel | ((prev: SelectionModel) => SelectionModel)) => void;
isRowSelectable?: (row: TData) => boolean;
toggleRowSelection: (rowId: string | number) => void;
toggleAllRowsSelection: () => void;
enableSorting: boolean;
sort: SortDescriptor[];
setSort: (sort: SortDescriptor[] | ((prev: SortDescriptor[]) => SortDescriptor[])) => void;
toggleSort: (columnId: string, multiSort?: boolean) => void;
enableFiltering: boolean;
filters: FilterDescriptor[];
setFilters: (filters: FilterDescriptor[] | ((prev: FilterDescriptor[]) => FilterDescriptor[])) => void;
globalFilter: string;
setGlobalFilter: (value: string) => void;
enablePagination: boolean;
paginationMode: PaginationMode;
pagination: PaginationState;
setPagination: (pagination: PaginationState | ((prev: PaginationState) => PaginationState)) => void;
totalCount: number;
pageSizeOptions: number[];
pageCount: number;
canPreviousPage: boolean;
canNextPage: boolean;
enableExpanding: boolean;
expandedRows: ExpandedState;
setExpandedRows: (expanded: ExpandedState | ((prev: ExpandedState) => ExpandedState)) => void;
toggleRowExpansion: (rowId: string | number) => void;
expandedContent?: (props: {
row: TData;
rowIndex: number;
}) => ReactNode;
editMode: EditMode;
editingCell: EditingState | null;
setEditingCell: (editing: EditingState | null) => void;
startEditing: (rowId: string | number, columnId: string) => void;
commitEdit: (value: unknown) => void;
cancelEdit: () => void;
enableGrouping: boolean;
groupBy: string[];
groups: GroupDef<TData>[];
processedData: TData[];
paginatedData: TData[];
animationType: AnimationType;
animationDuration: number;
styles: Record<string, unknown>;
icons: {
sortAsc?: ReactNode;
sortDesc?: ReactNode;
sortNeutral?: ReactNode;
expand?: ReactNode;
collapse?: ReactNode;
select?: ReactNode;
selectAll?: ReactNode;
filter?: ReactNode;
clearFilter?: ReactNode;
};
headerStyle?: CSSProperties;
bodyStyle?: CSSProperties;
footerStyle?: CSSProperties;
rowStyle?: CSSProperties | ((row: TData, rowIndex: number) => CSSProperties);
rowClassName?: string | ((row: TData, rowIndex: number) => string);
cellStyle?: CSSProperties | ((row: TData, column: ColumnDef<TData>) => CSSProperties);
cellClassName?: string | ((row: TData, column: ColumnDef<TData>) => string);
stickyHeader?: boolean;
rowRenderer?: (props: {
row: TData;
rowIndex: number;
children: ReactNode;
}) => ReactNode;
onRowClick?: (row: TData, rowIndex: number, event: React.MouseEvent) => void;
onRowDoubleClick?: (row: TData, rowIndex: number, event: React.MouseEvent) => void;
onCellClick?: (row: TData, column: ColumnDef<TData>, rowIndex: number, event: React.MouseEvent) => void;
onCellDoubleClick?: (row: TData, column: ColumnDef<TData>, rowIndex: number, event: React.MouseEvent) => void;
}
export interface TableProps<TData extends RowData = RowData> extends Omit<HTMLAttributes<HTMLTableElement>, 'onSelect' | 'onChange'>, TableBaseProps<TData> {
}
export type TableHeaderProps = ThHTMLAttributes<HTMLTableSectionElement>;
export type TableBodyProps = HTMLAttributes<HTMLTableSectionElement>;
export type TableFooterProps = HTMLAttributes<HTMLTableSectionElement>;
export interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {
status?: TableStatus;
selected?: boolean;
expanded?: boolean;
disabled?: boolean;
}
export interface TableCellProps extends TdHTMLAttributes<HTMLTableCellElement> {
status?: TableStatus;
}
export interface TableHeaderCellProps extends ThHTMLAttributes<HTMLTableCellElement> {
sorted?: SortDirection;
sortable?: boolean;
resizable?: boolean;
reorderable?: boolean;
}
export interface TablePaginationProps extends HTMLAttributes<HTMLDivElement> {
showPageSizeSelector?: boolean;
showPageNumbers?: boolean;
showTotalCount?: boolean;
compact?: boolean;
}
export interface TableFilterProps extends HTMLAttributes<HTMLDivElement> {
column: ColumnDef<RowData>;
value: unknown;
onChange: (value: unknown) => void;
matchMode?: FilterMatchMode;
placeholder?: string;
}
export interface TableGlobalFilterProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
value: string;
onChange: (value: string) => void;
placeholder?: string;
debounceMs?: number;
}
export interface TableSortIconProps extends HTMLAttributes<HTMLSpanElement> {
direction: SortDirection;
}
export interface TableExpandButtonProps extends HTMLAttributes<HTMLButtonElement> {
expanded: boolean;
onToggle: () => void;
}
export interface TableSelectCheckboxProps extends Omit<HTMLAttributes<HTMLInputElement>, 'onChange'> {
checked: boolean;
indeterminate?: boolean;
onChange: () => void;
disabled?: boolean;
}
export interface TableEditCellProps<TData = RowData> {
value: unknown;
row: TData;
column: ColumnDef<TData>;
onSave: (value: unknown) => void;
onCancel: () => void;
}
export interface TableEmptyProps extends HTMLAttributes<HTMLDivElement> {
message?: string;
action?: ReactNode;
illustration?: ReactNode;
}
export interface TableLoadingProps extends HTMLAttributes<HTMLDivElement> {
message?: string;
showSkeleton?: boolean;
skeletonRows?: number;
}
export interface TableExpandedPanelProps extends HTMLAttributes<HTMLTableRowElement> {
colSpan: number;
}