UNPKG

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
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; }