UNPKG

@vlsergey/react-bootstrap-pagetable

Version:

Complex solution to work with pageable data, including sorting, filtering, actions, changing displayed columns, etc.

80 lines (63 loc) 2.61 kB
import {ReactNode} from 'react'; import ItemModel from './ItemModel'; export type ValueGetter<I, V, F> = ((item: I, fieldModel: FieldModel<I, V, F>, itemType: ItemModel<I>) => V); export interface FilterCellRendererProps<I, V, F> { field: FieldModel<I, V, F>; filterBy: F | undefined; onFilterByChange: (filterBy: F | undefined) => unknown; } export interface FilterValueConverter<F> { fromStrings: (str: string[]) => F | undefined; toStrings: (filterBy: F) => string[]; } export interface ValueRendererProps<ItemType, ValueType> { value: ValueType; item: ItemType; } interface FieldModel<ItemType, ValueType, FilterValueType> { key: string; title: string; description?: ReactNode; hiddenByDefault?: boolean; sortable?: boolean; renderFilterCell?: React.ComponentType<FilterCellRendererProps<ItemType, ValueType, FilterValueType>>; filterValueConverter?: FilterValueConverter<FilterValueType>; getter?: ValueGetter<ItemType, ValueType, FilterValueType>; render?: React.ComponentType<ValueRendererProps<ItemType, ValueType>>; headerCellContent?: React.ComponentType<{field: FieldModel<ItemType, ValueType, FilterValueType>}>; headerCellProps?: React.ComponentProps<'th'>; valueCellProps?: (value: ValueType, item: ItemType, fieldModel: FieldModel<ItemType, ValueType, FilterValueType>) => Record<string, unknown>; } export const defaultGetter = <I, V, F>(item: I, fieldModel: FieldModel<I, V, F>): V => (item as Record<string, unknown>)[fieldModel.key] as V; export function defaultFilterValueConverter<F> (): FilterValueConverter<F> { return { fromStrings: (src: string[]) => { const firstValue = src?.[0]; if (!firstValue) return undefined; return JSON.parse(firstValue) as F; }, toStrings: (value: F) => [JSON.stringify(value)], }; } const EMPTY_PROPS = Object.freeze({}) as Record<string, unknown>; export function defaultHeaderCellProps<I, V, F> (): ((fieldModel: FieldModel<I, V, F>) => Record<string, unknown>) { return () => EMPTY_PROPS; } export function defaultValueCellProps<I, V, F> (): ((value: V, item: I, fieldModel: FieldModel<I, V, F>) => Record<string, unknown>) { return () => EMPTY_PROPS; } export function defaultRender<ValueType> ( {value}: ValueRendererProps<ValueType, unknown> ): ReactNode { if (value === null || value === undefined) { return null; } if (typeof value === 'string' || typeof value === 'number') { return value; } return JSON.stringify(value); } export default FieldModel;