interface.ts 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. import React, { ReactNode, MutableRefObject } from 'react';
  2. import type { BaseProps } from '../_base/baseComponent';
  3. import type { PaginationProps } from '../pagination';
  4. import type { CheckboxProps } from '../checkbox';
  5. import type { Locale } from '../locale/interface';
  6. import type { ArrayElement } from '../_base/base';
  7. import { strings } from '@douyinfe/semi-foundation/table/constants';
  8. import type {
  9. BaseRowKeyType,
  10. BaseSortOrder,
  11. BaseGroupBy,
  12. BaseGroupByFn,
  13. BaseFixed,
  14. BaseAlign,
  15. BaseChangeInfoSorter,
  16. BaseSorter,
  17. BaseFilter,
  18. BaseChangeInfoFilter,
  19. BaseIncludeGroupRecord,
  20. BaseEllipsis,
  21. OnChangeExtra
  22. } from '@douyinfe/semi-foundation/table/foundation';
  23. import type { ColumnFilterProps } from './ColumnFilter';
  24. import { TableCellProps } from './TableCell';
  25. export interface TableProps<RecordType extends Record<string, any> = any> extends BaseProps {
  26. bordered?: boolean;
  27. children?: ReactNode;
  28. childrenRecordName?: string;
  29. className?: string;
  30. clickGroupedRowToExpand?: boolean;
  31. columns?: ColumnProps<RecordType>[];
  32. components?: TableComponents;
  33. dataSource?: RecordType[];
  34. defaultExpandAllGroupRows?: boolean;
  35. defaultExpandAllRows?: boolean;
  36. defaultExpandedRowKeys?: (string | number)[];
  37. empty?: ReactNode;
  38. expandAllGroupRows?: boolean;
  39. expandAllRows?: boolean;
  40. expandCellFixed?: Fixed;
  41. expandIcon?: ExpandIcon;
  42. expandedRowKeys?: (string | number)[];
  43. expandedRowRender?: ExpandedRowRender<RecordType>;
  44. expandRowByClick?: boolean;
  45. footer?: Footer<RecordType>;
  46. getVirtualizedListRef?: GetVirtualizedListRef;
  47. groupBy?: GroupBy<RecordType>;
  48. hideExpandedColumn?: boolean;
  49. id?: string;
  50. indentSize?: number;
  51. keepDOM?: boolean;
  52. loading?: boolean;
  53. pagination?: TablePagination;
  54. prefixCls?: string;
  55. renderGroupSection?: RenderGroupSection;
  56. renderPagination?: RenderPagination;
  57. resizable?: Resizable<RecordType>;
  58. rowExpandable?: RowExpandable<RecordType>;
  59. rowKey?: RowKey<RecordType>;
  60. rowSelection?: RowSelection<RecordType>;
  61. scroll?: Scroll;
  62. showHeader?: boolean;
  63. size?: Size;
  64. style?: React.CSSProperties;
  65. title?: Title<RecordType>;
  66. virtualized?: Virtualized;
  67. onChange?: OnChange<RecordType>;
  68. onExpand?: OnExpand<RecordType>;
  69. onExpandedRowsChange?: OnExpandedRowsChange<RecordType>;
  70. onGroupedRow?: OnGroupedRow<RecordType>;
  71. onHeaderRow?: OnHeaderRow<RecordType>;
  72. onRow?: OnRow<RecordType>;
  73. sticky?: Sticky;
  74. direction?: Direction
  75. }
  76. export interface ColumnProps<RecordType extends Record<string, any> = any> {
  77. [x: string]: any;
  78. align?: Align;
  79. children?: Array<ColumnProps<RecordType>>;
  80. className?: string;
  81. colSpan?: number;
  82. /** use `dataIndex` to get current column data item from record. If you use `sorter` or `onFilter`, a unique `dataIndex` is required */
  83. dataIndex?: string;
  84. defaultFilteredValue?: any[];
  85. defaultSortOrder?: SortOrder;
  86. filterChildrenRecord?: boolean;
  87. filterDropdown?: ColumnFilterProps['filterDropdown'];
  88. /** render filter Dropdown panel content */
  89. renderFilterDropdown?: ColumnFilterProps['renderFilterDropdown'];
  90. /** filter Dropdown props */
  91. filterDropdownProps?: ColumnFilterProps['filterDropdownProps'];
  92. filterDropdownVisible?: boolean;
  93. filterIcon?: FilterIcon;
  94. filterMultiple?: boolean;
  95. filteredValue?: any[];
  96. /** `filters` is not required if you use `renderFilterDropdown` */
  97. filters?: Filter[];
  98. fixed?: Fixed;
  99. /** the key required by React. If you have already set the `dataIndex`, the key does not need to be set again. */
  100. key?: string | number;
  101. render?: ColumnRender<RecordType>;
  102. renderFilterDropdownItem?: RenderFilterDropdownItem;
  103. sortChildrenRecord?: boolean;
  104. sortOrder?: SortOrder;
  105. /** enable sorting, `dataIndex` is required at the same time */
  106. sorter?: Sorter<RecordType>;
  107. sortIcon?: SortIcon;
  108. title?: ColumnTitle;
  109. useFullRender?: boolean;
  110. width?: string | number;
  111. onCell?: OnCell<RecordType>;
  112. /** enable filtering, `dataIndex` is required at the same time */
  113. onFilter?: OnFilter<RecordType>;
  114. onFilterDropdownVisibleChange?: OnFilterDropdownVisibleChange;
  115. onHeaderCell?: OnHeaderCell<RecordType>;
  116. ellipsis?: BaseEllipsis;
  117. resize?: boolean;
  118. showSortTip?: boolean;
  119. /**
  120. * self control whether to update cell for performance reasons
  121. */
  122. shouldCellUpdate?: (props: TableCellProps, prevProps: TableCellProps) => boolean
  123. }
  124. export type Align = BaseAlign;
  125. export type SortOrder = BaseSortOrder;
  126. export type SortIcon = (props: { sortOrder: SortOrder }) => ReactNode;
  127. export type FilterIcon = boolean | React.ReactNode | FilterIconRenderFunction;
  128. export interface Filter extends BaseFilter {
  129. value?: any;
  130. text?: React.ReactNode;
  131. children?: Filter[]
  132. }
  133. export type Fixed = BaseFixed;
  134. export type OnCell<RecordType> = (record?: RecordType, rowIndex?: number) => OnCellReturnObject;
  135. export type OnFilter<RecordType> = (filteredValue?: any, record?: RecordType) => boolean;
  136. export type OnFilterDropdownVisibleChange = (visible?: boolean) => void;
  137. export type OnHeaderCell<RecordType> = (record?: RecordType, columnIndex?: number, index?: number) => OnHeaderCellReturnObject;
  138. export type ColumnRender<RecordType> = (text: any, record: RecordType, index: number, options?: RenderOptions) => ColumnRenderReturnType;
  139. export type RenderFilterDropdownItem = (itemInfo?: FilterDropdownItem) => ReactNode;
  140. export type Sorter<RecordType> = BaseSorter<RecordType>;
  141. export type ColumnTitle = React.ReactNode | ((ColumnTitleProps?: ColumnTitleProps) => React.ReactNode);
  142. export type FilterIconRenderFunction = (filtered: boolean) => React.ReactNode;
  143. export type ColumnTitleProps = {
  144. sorter?: React.ReactNode;
  145. filter?: React.ReactNode;
  146. selection?: React.ReactNode
  147. };
  148. export type ColumnRenderReturnType = React.ReactNode | RenderReturnObject;
  149. export interface RenderReturnObject {
  150. [x: string]: any;
  151. children: React.ReactNode;
  152. props: {
  153. [x: string]: any;
  154. colSpan?: number;
  155. rowSpan?: number
  156. }
  157. }
  158. export interface FilterDropdownItem {
  159. [x: string]: any;
  160. value?: any;
  161. text?: React.ReactNode;
  162. onChange?: React.MouseEventHandler<HTMLLIElement>;
  163. level?: number;
  164. filterMultiple?: boolean;
  165. checked?: boolean
  166. }
  167. export interface RenderOptions {
  168. expandIcon?: React.ReactNode;
  169. selection?: React.ReactNode;
  170. indentText?: React.ReactNode
  171. }
  172. export interface OnCellReturnObject extends React.TdHTMLAttributes<HTMLElement> {
  173. [x: string]: any;
  174. style?: React.CSSProperties;
  175. className?: string;
  176. onClick?: (e: React.MouseEvent) => void
  177. }
  178. export interface OnHeaderCellReturnObject extends React.ThHTMLAttributes<HTMLElement> {
  179. [x: string]: any;
  180. style?: React.CSSProperties;
  181. className?: string;
  182. onClick?: (e: React.MouseEvent) => void
  183. }
  184. interface OnRowReturnOmit {
  185. ref?: React.RefObject<any>
  186. }
  187. export interface OnRowReturnObject extends Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableRowElement>, HTMLTableRowElement>, keyof OnRowReturnOmit> {
  188. [x: string]: any;
  189. className?: string;
  190. style?: React.CSSProperties;
  191. onClick?: (e: React.MouseEvent) => void
  192. }
  193. export interface OnGroupedRowReturnObject extends React.HTMLAttributes<HTMLTableRowElement> {
  194. [x: string]: any;
  195. style?: React.CSSProperties;
  196. onClick?: (e: React.MouseEvent) => void
  197. }
  198. export type OnHeaderRowReturnObject = Omit<React.HTMLAttributes<HTMLTableRowElement>, 'ref' | 'style'>;
  199. export interface Scroll {
  200. x?: number | string;
  201. y?: number | string;
  202. scrollToFirstRowOnChange?: boolean
  203. }
  204. export interface Data {
  205. [x: string]: any;
  206. key?: string | number
  207. }
  208. export type TableComponent<P> = React.ComponentType<P> | React.ForwardRefExoticComponent<P> | keyof React.ReactHTML;
  209. export interface TableComponents {
  210. table?: TableComponent<any>;
  211. header?: {
  212. outer?: TableComponent<any>;
  213. wrapper?: TableComponent<any>;
  214. row?: TableComponent<any>;
  215. cell?: TableComponent<any>
  216. };
  217. body?: {
  218. outer?: TableComponent<any>;
  219. wrapper?: TableComponent<any>;
  220. row?: TableComponent<any>;
  221. cell?: TableComponent<any>;
  222. colgroup?: {
  223. wrapper?: TableComponent<any>;
  224. col?: TableComponent<any>
  225. }
  226. };
  227. footer?: {
  228. wrapper?: TableComponent<any>;
  229. row?: TableComponent<any>;
  230. cell?: TableComponent<any>;
  231. outer?: TableComponent<any>
  232. }
  233. }
  234. export interface RowSelectionProps<RecordType> {
  235. className?: string;
  236. disabled?: boolean;
  237. fixed?: Fixed;
  238. getCheckboxProps?: GetCheckboxProps<RecordType>;
  239. hidden?: boolean;
  240. selectedRowKeys?: (string | number)[];
  241. title?: ReactNode;
  242. width?: string | number;
  243. onChange?: RowSelectionOnChange<RecordType>;
  244. onSelect?: RowSelectionOnSelect<RecordType>;
  245. onSelectAll?: RowSelectionOnSelectAll<RecordType>;
  246. onCell?: ColumnProps['onCell'];
  247. onHeaderCell?: ColumnProps['onHeaderCell'];
  248. renderCell?: RowSelectionRenderCell<RecordType>;
  249. /**
  250. * self control whether to update cell for performance reasons
  251. */
  252. shouldCellUpdate?: (props: TableCellProps, prevProps: TableCellProps) => boolean
  253. }
  254. export type RowSelectionRenderCell<RecordType> = (renderCellArgs: {
  255. selected: boolean;
  256. record: RecordType;
  257. originNode: JSX.Element;
  258. inHeader: boolean;
  259. disabled: boolean;
  260. indeterminate: boolean;
  261. index?: number;
  262. selectRow?: (selected: boolean, e: Event) => void;
  263. selectAll?: (selected: boolean, e: Event) => void
  264. }) => ReactNode;
  265. export type GetCheckboxProps<RecordType> = (record: RecordType) => Omit<CheckboxProps, 'defaultChecked' | 'checked' | 'indeterminate' | 'onChange'>;
  266. export type RowSelectionOnChange<RecordType> = (selectedRowKeys?: (string | number)[], selectedRows?: RecordType[]) => void;
  267. export type RowSelectionOnSelect<RecordType> = (
  268. record?: RecordType,
  269. selected?: boolean,
  270. selectedRows?: RecordType[],
  271. nativeEvent?: React.MouseEvent
  272. ) => void;
  273. export type RowSelectionOnSelectAll<RecordType> = (selected?: boolean, selectedRows?: RecordType[], changedRows?: RecordType[]) => void;
  274. export type ExpandIcon = ((expanded?: boolean) => React.ReactNode) | React.ReactNode;
  275. export type ExpandedRowRender<RecordType> = (record?: RecordType, index?: number, expanded?: boolean) => React.ReactNode;
  276. export type Footer<RecordType> = ReactNode | ((pageData?: RecordType[]) => React.ReactNode);
  277. export type FormatPageText = ((pageInfo?: { currentStart?: number; currentEnd?: number; total?: number }) => React.ReactNode) | boolean;
  278. /**
  279. * ref to react-window `VariableSizeList` instance
  280. *
  281. * only work when `virtualized` is truthy
  282. *
  283. * @see https://github.com/DefinitelyTyped/DefinitelyTyped/blob/58aabc0cfd2baf08f5f71a2712ae7baa6cb2a3ce/types/react-window/index.d.ts#L378
  284. */
  285. export type GetVirtualizedListRef = (ref: MutableRefObject<{
  286. /**
  287. * Scroll to the specified offset (scrollTop or scrollLeft, depending on the direction prop).
  288. */
  289. scrollTo(scrollOffset: number): void;
  290. /**
  291. * Scroll to the specified item.
  292. *
  293. * By default, the List will scroll as little as possible to ensure the item is visible.
  294. * You can control the alignment of the item though by specifying a second alignment parameter. Acceptable values are:
  295. *
  296. * - auto (default) - Scroll as little as possible to ensure the item is visible. (If the item is already visible, it won't scroll at all.)
  297. * - smart
  298. * - If the item is already visible, don't scroll at all.
  299. * - If it is less than one viewport away, scroll as little as possible so that it becomes visible.
  300. * - If it is more than one viewport away, scroll so that it is centered within the list.
  301. * - center - Center align the item within the list.
  302. * - end - Align the item to the end of the list (the bottom for vertical lists or the right for horizontal lists).
  303. * - start - Align the item to the beginning of the list (the top for vertical lists or the left for horizontal lists).
  304. */
  305. scrollToItem(index: number, align?: "auto" | "smart" | "center" | "end" | "start"): void
  306. }>) => void;
  307. export type GroupByFunction<RecordType> = BaseGroupByFn<RecordType>;
  308. export type GroupBy<RecordType> = BaseGroupBy<RecordType>;
  309. export type Size = ArrayElement<typeof strings.SIZES>;
  310. export type Title<RecordType> = React.ReactNode | ((pageData?: RecordType[]) => React.ReactNode);
  311. export type PaginationPosition = ArrayElement<typeof strings.PAGINATION_POSITIONS>;
  312. export type Pagination = TablePaginationProps | boolean;
  313. export type TablePagination = Pagination;
  314. export interface ChangeInfoFilter<RecordType> extends BaseChangeInfoFilter<RecordType> {
  315. filters?: Filter[];
  316. onFilter?: OnFilter<RecordType>
  317. }
  318. export type ChangeInfoSorter<RecordType> = BaseChangeInfoSorter<RecordType>;
  319. export interface ChangeInfo<RecordType> {
  320. pagination?: TablePaginationProps;
  321. filters?: ChangeInfoFilter<RecordType>[];
  322. sorter?: ChangeInfoSorter<RecordType>;
  323. extra?: OnChangeExtra
  324. }
  325. export type OnChange<RecordType> = (changeInfo: ChangeInfo<RecordType>) => void;
  326. export type OnRow<RecordType> = (record?: RecordType, index?: number) => OnRowReturnObject;
  327. export type OnGroupedRow<RecordType> = (record?: RecordType, index?: number) => OnGroupedRowReturnObject;
  328. export type OnHeaderRow<RecordType> = (columns?: ColumnProps<RecordType>[], index?: number) => OnHeaderRowReturnObject;
  329. export type OnExpandedRowsChange<RecordType> = (expandedRows?: IncludeGroupRecord<RecordType>[]) => void;
  330. export type OnExpand<RecordType> = (expanded?: boolean, record?: IncludeGroupRecord<RecordType>, mouseEvent?: React.MouseEvent) => void;
  331. export type RenderGroupSection = (groupKey?: string | number, group?: (string | number)[]) => ReactNode | {
  332. [x: string]: any;
  333. children: ReactNode
  334. };
  335. export type RenderPagination = (paginationProps: TablePaginationProps) => ReactNode;
  336. export type RowExpandable<RecordType> = (record?: RecordType) => boolean;
  337. export type RowKey<RecordType> = BaseRowKeyType | ((record?: RecordType) => string);
  338. export type RowSelection<RecordType> = RowSelectionProps<RecordType> | boolean;
  339. export type VirtualizedOnScrollArgs = {
  340. scrollDirection?: "forward" | "backward";
  341. scrollOffset?: number;
  342. scrollUpdateWasRequested?: boolean
  343. };
  344. export type VirtualizeItemSizeRow = {
  345. sectionRow?: boolean;
  346. expandedRow?: boolean
  347. };
  348. export type VirtualizedItemSizeFn = (index?: number, row?: VirtualizeItemSizeRow) => number;
  349. export type VirtualizedItemSize = number | VirtualizedItemSizeFn;
  350. export type VirtualizedOnScroll = (object: VirtualizedOnScrollArgs) => void;
  351. export interface VirtualizedProps {
  352. [x: string]: any;
  353. itemSize?: VirtualizedItemSize;
  354. onScroll?: VirtualizedOnScroll
  355. }
  356. export type Virtualized = boolean | VirtualizedProps;
  357. export interface TablePaginationProps extends BaseProps, PaginationProps {
  358. position?: PaginationPosition;
  359. formatPageText?: FormatPageText
  360. }
  361. export type Resizable<RecordType> = ResizableProps<RecordType> | boolean;
  362. export interface ResizableProps<RecordType> {
  363. onResize?: ResizeFn<RecordType>;
  364. onResizeStart?: ResizeFn<RecordType>;
  365. onResizeStop?: ResizeFn<RecordType>
  366. }
  367. export type ResizeFn<RecordType> = (column: RecordType) => RecordType;
  368. export interface BodyScrollEvent extends React.UIEvent {
  369. [x: string]: any;
  370. currentTarget: any;
  371. target: any
  372. }
  373. export type BodyScrollPosition = 'both' | 'middle' | 'left' | 'right';
  374. export type TableLocale = Locale['Table'];
  375. export type Direction = "ltr" | "rtl";
  376. export type IncludeGroupRecord<RecordType> = BaseIncludeGroupRecord<RecordType>;
  377. export type Sticky = boolean | {
  378. top?: number
  379. }