vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
479 lines (478 loc) • 16.4 kB
TypeScript
import { InjectionKey, Slots } from 'vue';
import { ClassType, ComponentSize, LocaleConfig, StyleType } from '@vexip-ui/config';
import { BITree } from '@vexip-ui/utils';
import { TooltipTheme } from '../tooltip';
import { TableStore } from './store';
export type Key = string | number | symbol;
export type Data = any;
export type MouseEventType = 'Enter' | 'Leave' | 'Click' | 'Dblclick' | 'Contextmenu';
export type MoveEventType = 'Start' | 'Move' | 'End';
export type TableIconName = 'filter' | 'asc' | 'desc' | 'dragger' | 'expand' | 'plus' | 'minus';
export type TableRowPropFn<P = any> = (data: Data, index: number) => P;
export type TableRowDropType = 'before' | 'after' | 'inner';
export type TableTextAlign = 'left' | 'center' | 'right';
export type TableColumnType = 'order' | 'selection' | 'expand' | 'drag';
export type TableColResizeType = 'lazy' | 'responsive';
export type TableIcons = Partial<Record<TableIconName, Record<string, any> | (() => any)>>;
export declare const enum DropType {
BEFORE = "before",
INNER = "inner",
AFTER = "after"
}
export interface CellSpanResult {
colSpan?: number;
rowSpan?: number;
}
export interface TableKeyConfig {
id?: string;
children?: string;
checked?: string;
height?: string;
expanded?: string;
treeExpanded?: string;
}
export interface TableSlots {
/**
* @internal
*/
default?: () => any;
empty?: (params: {
isFixed: boolean;
}) => any;
}
export type Accessor<D = Data, Val extends string | number = string | number> = (data: D, index: number) => Val;
export type ExpandRenderFn<D = Data> = (data: {
/** @deprecated */
leftFixed: number;
/** @deprecated */
rightFixed: number;
row: D;
rowIndex: number;
}) => any;
export type ColumnCellSpanFn<D = Data> = (data: {
row: D;
index: number;
fixed?: 'left' | 'right';
}) => CellSpanResult | void;
export type SummaryCellSpanFn<D = Data, Val extends string | number = string | number> = (data: {
column: TableColumnOptions<D, Val>;
index: number;
fixed?: 'left' | 'right';
}) => CellSpanResult | void;
export type TableFilterOptions<D = Data, Val extends string | number = string | number> = {
able?: boolean;
custom?: false;
options?: (string | {
value: Val;
label?: string;
active?: boolean;
})[];
multiple?: false;
active?: null | Val;
method?: null | ((active: Val, data: D) => boolean);
meta?: any;
} | {
able?: boolean;
custom?: false;
options?: (string | {
value: Val;
label?: string;
active?: boolean;
})[];
multiple: true;
active?: null | Val[];
method?: null | ((active: Val[], data: D) => boolean);
meta?: any;
} | {
able?: boolean;
custom: true;
options?: never;
multiple?: false;
active?: null | Val | Val[];
method?: null | ((active: any, data: D) => boolean);
meta?: any;
};
export interface ParsedFilterOptions extends Omit<Required<TableFilterOptions>, 'options'> {
options: {
value: string | number;
label: string;
active: boolean;
}[];
}
export interface TableSorterOptions<D = Data> {
able?: boolean;
type?: null | 'asc' | 'desc';
order?: number;
method?: null | ((prev: D, next: D) => number);
}
export type ParsedTableSorterOptions = Required<TableSorterOptions>;
export interface TableSummaryData {
sum: number;
min: number;
max: number;
}
export type SummaryRenderFn<D = Data, Val extends string | number = string | number> = (data: {
column: TableColumnOptions<D, Val>;
index: number;
rows: D[];
meta: TableSummaryData;
}) => any;
export type ColumnSummaryRenderFn<D = Data, Val extends string | number = string | number> = (data: {
column: TableColumnOptions<D, Val>;
index: number;
rows: D[];
meta: TableSummaryData;
summary: TableSummaryOptions<D, Val>;
}) => any;
export interface TableBaseColumn<D = Data, Val extends string | number = string | number> {
key: keyof D;
name?: string;
type?: never;
meta?: any;
fixed?: boolean | 'left' | 'right';
class?: ClassType;
style?: StyleType;
attrs?: Record<string, any>;
width?: number | `${number}%`;
minWidth?: number;
maxWidth?: number;
filter?: TableFilterOptions<D, Val>;
sorter?: boolean | TableSorterOptions<D>;
order?: number;
ellipsis?: boolean | null;
textAlign?: TableTextAlign;
headSpan?: number;
noSummary?: boolean;
indented?: boolean;
accessor?: Accessor<D, Val>;
formatter?: (value: Val) => unknown;
cellSpan?: ColumnCellSpanFn<D>;
renderer?: ColumnRenderFn<D, Val>;
headRenderer?: HeadRenderFn;
filterRenderer?: FilterRenderFn;
summaryRenderer?: ColumnSummaryRenderFn<D, Val>;
}
export interface TableOrderColumn<D = Data, Val extends string | number = string | number> extends Omit<TableBaseColumn<D, Val>, 'key' | 'type' | 'renderer'> {
key?: keyof D;
type: 'order';
truthIndex?: boolean;
orderLabel?: (index: number) => string | number;
}
export interface TableSelectionColumn<D = Data, Val extends string | number = string | number> extends Omit<TableBaseColumn<D, Val>, 'key' | 'type' | 'renderer' | 'headRenderer'> {
key?: keyof D;
type: 'selection';
/**
* @deprecated Use `selectionSize` instead.
*/
checkboxSize?: ComponentSize;
selectionSize?: ComponentSize;
singleSelect?: boolean;
disableRow?: (data: Data) => boolean;
}
export interface TableExpandColumn<D = Data, Val extends string | number = string | number> extends Omit<TableBaseColumn<D, Val>, 'key' | 'type' | 'renderer'> {
key?: keyof D;
type: 'expand';
disableRow?: (data: Data) => boolean;
renderer?: ExpandRenderFn<D>;
}
export interface TableDragColumn<D = Data, Val extends string | number = string | number> extends Omit<TableBaseColumn<D, Val>, 'key' | 'type' | 'renderer'> {
key?: keyof D;
type: 'drag';
disableRow?: (data: Data) => boolean;
}
export type TableTypeColumn<D = Data, Val extends string | number = string | number> = TableOrderColumn<D, Val> | TableSelectionColumn<D, Val> | TableExpandColumn<D, Val> | TableDragColumn<D, Val>;
export type TableColumnOptions<D = Data, Val extends string | number = string | number> = TableBaseColumn<D, Val> | TableTypeColumn<D, Val>;
export type ColumnWithKey<D = Data, Val extends string | number = string | number> = TableColumnOptions<D, Val> & {
key: Key;
rowSpan: number;
/** @internal */
index: number;
/** @internal */
colIndex: number;
/** @internal */
first?: boolean;
/** @internal */
last?: boolean;
};
export interface TableColumnGroupOptions {
name?: string;
fixed?: boolean | 'left' | 'right';
order?: number;
ellipsis?: boolean;
textAlign?: TableTextAlign;
renderer?: () => any;
children: TableColumnOptions<any, any>[];
}
export interface ColumnGroupWithKey extends TableColumnGroupOptions {
key: Key;
headSpan: number;
rowSpan: number;
/** @internal */
colIndex: number;
/** @internal */
last?: boolean;
}
export type ColumnRenderFn<D = Data, Val extends string | number = string | number> = (data: {
row: D;
rowIndex: number;
column: TableBaseColumn<D, Val>;
columnIndex: number;
}) => any;
export type HeadRenderFn<D = Data, Val extends string | number = string | number> = (data: {
column: TableColumnOptions<D, Val>;
index: number;
}) => any;
export type FilterRenderFn<D = Data, Val extends string | number = string | number> = (data: {
column: TableColumnOptions<D, Val>;
index: number;
filter: Required<TableFilterOptions<D, Val>>;
handleFilter: (active: any) => void;
}) => any;
export type TableCellSpanFn<D = Data, Val extends string | number = string | number> = (data: {
row: D;
rowIndex: number;
column: TableColumnOptions<D, Val>;
columnIndex: number;
fixed?: 'left' | 'right';
}) => CellSpanResult | undefined;
export type TableCellPropFn<D = Data, P = any> = (data: {
row: D;
rowIndex: number;
column: ColumnWithKey;
columnIndex: number;
}) => P;
export type TableHeadPropFn<P = any> = (data: {
column: ColumnWithKey;
index: number;
rowIndex: number;
}) => P;
export type TableFootPropFn<P = any> = (data: {
column: ColumnWithKey;
columnIndex: number;
summary: SummaryWithKey;
summaryIndex: number;
}) => P;
export type ColumnProfile<D = Data, Val extends string | number = string | number> = Pick<ColumnWithKey<D, Val>, 'name' | 'key' | 'meta'>;
export type TableFilterProfile<D = Data, Val extends string | number = string | number> = ColumnProfile<D, Val> & {
active: Val | Val[];
};
export type TableSorterProfile<D = Data, Val extends string | number = string | number> = ColumnProfile<D, Val> & {
type: 'asc' | 'desc';
order: number;
};
export interface TableSummaryOptions<D = Data, Val extends string | number = string | number> {
name: string;
key: keyof D;
class?: ClassType;
style?: StyleType;
attrs?: Record<string, any>;
order?: number;
above?: boolean;
meta?: Record<any, any>;
cellSpan?: SummaryCellSpanFn<D, Val>;
renderer?: SummaryRenderFn<D, Val>;
}
export type SummaryWithKey<D = Data, Val extends string | number = string | number> = TableSummaryOptions<D, Val> & {
key: Key;
};
/** @internal */
export interface TableRowState {
key: Key;
index: number;
hidden: boolean;
hover: boolean;
checked: boolean;
height: number;
expanded: boolean;
expandHeight: number;
parent?: Key;
children: TableRowState[];
depth: number;
treeExpanded: boolean;
partial: boolean;
dragging: boolean;
listIndex: number;
cellHeights: Record<Key, number>;
last: boolean;
expandAnimate: boolean;
data: Data;
}
export interface StoreOptions {
columns: TableColumnRawOptions[];
summaries: TableSummaryOptions[];
data: Data[];
dataKey: string;
rowClass: ClassType | TableRowPropFn<ClassType>;
rowStyle: StyleType | TableRowPropFn<StyleType>;
rowAttrs: Record<string, any> | TableRowPropFn<Record<string, any>>;
cellClass: ClassType | TableCellPropFn<ClassType>;
cellStyle: StyleType | TableCellPropFn<StyleType>;
cellAttrs: Record<string, any> | TableCellPropFn<Record<string, any>>;
headClass: ClassType | TableHeadPropFn<ClassType>;
headStyle: StyleType | TableHeadPropFn<StyleType>;
headAttrs: Record<string, any> | TableHeadPropFn<Record<string, any>>;
footClass: ClassType | TableFootPropFn<ClassType>;
footStyle: StyleType | TableFootPropFn<StyleType>;
footAttrs: Record<string, any> | TableFootPropFn<Record<string, any>>;
border: boolean;
stripe: boolean;
highlight: boolean;
currentPage: number;
pageSize: number;
rowHeight: number;
rowMinHeight: number;
virtual: boolean;
rowDraggable: boolean;
locale: LocaleConfig['table'];
tooltipTheme: TooltipTheme;
tooltipWidth: number | string;
singleSorter: boolean;
singleFilter: boolean;
customSorter: boolean;
customFilter: boolean;
keyConfig: Required<TableKeyConfig>;
disabledTree: boolean;
noCascaded: boolean;
colResizable: false | TableColResizeType;
expandRenderer: ExpandRenderFn | null;
cellSpan: TableCellSpanFn | null;
sidePadding: number[];
borderWidth: number;
dataFilter: (data: Data) => boolean;
ellipsis: boolean;
}
export type TableColumnRawOptions = TableColumnOptions<any, any> | TableColumnGroupOptions;
export type ColumnRawWithKey = ColumnGroupWithKey | ColumnWithKey;
export interface StoreState extends StoreOptions {
columns: ColumnWithKey[];
normalColumns: ColumnWithKey[];
allColumns: ColumnRawWithKey[][];
summaries: SummaryWithKey[];
rowData: TableRowState[];
treeRowData: TableRowState[];
width: number;
rightFixedColumns: ColumnWithKey[];
leftFixedColumns: ColumnWithKey[];
aboveSummaries: SummaryWithKey[];
belowSummaries: SummaryWithKey[];
columnMap: Map<Key, ColumnRawWithKey>;
rowMap: Map<Key, TableRowState>;
summaryMap: Map<Key, SummaryWithKey>;
idMaps: WeakMap<Data, Key>;
checkedAll: boolean;
partial: boolean;
widths: Map<Key, number>;
sorters: Map<Key, ParsedTableSorterOptions>;
filters: Map<Key, ParsedFilterOptions>;
resized: Set<Key>;
bodyYScroll: number;
bodyXScroll: number;
padTop: number;
startRow: number;
endRow: number;
dragging: boolean;
heightBITree: BITree;
virtualData: TableRowState[];
totalHeight: number;
colResizing: boolean;
resizeLeft: number;
cellSpanMap: Map<'left' | 'default' | 'right', Map<string, Required<CellSpanResult>>>;
collapseMap: Map<'left' | 'default' | 'right', Map<string, Set<string>>>;
locked: boolean;
barScrolling: boolean;
heightTrigger: number;
hoveredRowKey: Key | null;
}
export interface TableRowInstance {
el?: HTMLElement | null;
row: TableRowState;
}
export interface TableRowPayload {
row: Data;
key: Key;
index: number;
event: Event;
checked?: boolean;
expanded?: boolean;
}
export interface TableCellPayload {
row: Data;
key: Key;
rowIndex: number;
column: TableColumnOptions;
columnIndex: number;
event: Event;
}
export interface TableHeadPayload {
column: TableColumnOptions;
index: number;
event: Event;
}
export interface TableColResizePayload extends TableHeadPayload {
width: number;
}
export interface TableFootPayload {
column: TableColumnOptions;
columnIndex: number;
summary: TableSummaryOptions;
summaryIndex: number;
event: Event;
}
export interface TableActions {
increaseColumn(column: TableColumnRawOptions): void;
decreaseColumn(column: TableColumnRawOptions): void;
increaseSummary(column: TableSummaryOptions): void;
decreaseSummary(column: TableSummaryOptions): void;
getTableElement(): HTMLElement | undefined;
refreshXScroll(): void;
emitRowCheck(payload: TableRowPayload & {
checked: boolean;
}): void;
emitAllRowCheck(checked: boolean, partial: boolean): void;
emitRowExpand(payload: TableRowPayload & {
expanded: boolean;
}): void;
emitRowTreeExpand(payload: TableRowPayload & {
expanded: boolean;
}): void;
emitRowFilter(): void;
emitRowSort(): void;
handleRowDragStart(rowInstance: TableRowInstance, event: DragEvent): void;
handleRowDragOver(rowInstance: TableRowInstance, event: DragEvent): void;
handleRowDrop(rowInstance: TableRowInstance, event: DragEvent): void;
handleRowDragEnd(event: DragEvent): void;
emitRowEvent(type: MouseEventType, payload: TableRowPayload): void;
emitCellEvent(type: MouseEventType, payload: TableCellPayload): void;
emitHeadEvent(type: MouseEventType, payload: TableHeadPayload): void;
emitFootEvent(type: MouseEventType, payload: TableFootPayload): void;
emitColResize(type: MoveEventType, payload: TableColResizePayload): void;
hasIcon(name: TableIconName): boolean;
getIcon(name: TableIconName): TableIcons[TableIconName];
renderTableSlot(payload: {
name: string;
}): any;
runInLocked(handler?: (...args: any[]) => any, delay?: number): Promise<void>;
updateColumns(): void;
setColumnProp(key: Key, prop: string, value: any): void;
updateSummaries(): void;
setSummaryProp(key: Key, prop: string, value: any): void;
}
export interface ColumnGroupActions {
increaseColumn(column: TableColumnRawOptions): void;
decreaseColumn(column: TableColumnRawOptions): void;
}
export declare const DEFAULT_KEY_FIELD = "id";
/**
* 表格状态管理
*/
export declare const TABLE_STORE: InjectionKey<TableStore>;
/**
* 表格组件的顶层 Api
*/
export declare const TABLE_ACTIONS: InjectionKey<TableActions>;
export declare const TABLE_SLOTS: InjectionKey<Slots>;
export declare const TABLE_HEAD_PREFIX = "__vxp-table-head-";
export declare const TABLE_FOOT_PREFIX = "__vxp-table-foot-";
export declare const COLUMN_GROUP_ACTIONS: InjectionKey<ColumnGroupActions>;
export declare const columnTypes: TableColumnType[];
export declare const noopFormatter: (v: any) => any;