mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-30 11:08:45 +08:00
cbcfd38ca7
* build: try to use dumi as doc tool * docs: migrate demo structure to dumi way * refactor: use type export & import * docs: migrate demo previewer to dumi * docs: create empty layout & components * docs: apply custom rehype plugin * docs: create empty extra pages * docs: Add Banner component * chore: move theme tsconfig.json * docs: home page init * docs: migrate header (#37896) * docs: header * docs: update * docs: home init * clean up * test: fix site lint * chore: tsc ignore demo * chore: dumi demo migrate script * chore: cards * docs: home layout * docs: Update locale logic * docs: fix getLink logic * chore: fix ci (#37899) * chore: fix ci * ci: remove check-ts-demo * ci: preview build * test: ignore demo.tsx * chore: update script * test: update snapshot * test: update node and image test * chore: add .surgeignore * docs: layout providers (#37908) * docs: add components sidebar (#37923) * docs: sidebar * docs: update docs title * docs: update design doc * chore: code clean * docs: handle changelog page * docs: add title * docs: add subtitle * docs: active header nav * chore: code clean * docs: overview * chore: code clean * docs: update intl (#37918) * docs: update intl * chore: code clean * docs: update favicons * chore: update testPathIgnorePatterns * chore: code clean * chore: code clean * chore: copy 404.html (#37996) * docs: Home page theme picker * chore: Update migrate script * docs: home page update * docs: theme editor style * docs: theme lang * chore: update migrate.js * docs: fix demo (#38094) * chore: update migrate.js * docs: update md * docs: update demo * test: fix snapshot * chore: move debug to code attr in migrate script * chore: update md Co-authored-by: PeachScript <scdzwyxst@gmail.com> * feat: overview page * feat: Migrate `404` page (#38118) * feat: migrate IconSearch component (#37916) * feat<site/IconSearch>: copy IconDisplay from site to .dumi * feat<site/IconSearch>: change docs of icon * feat<site/IconSearch>: tweak * feat<site/IconSearch>: use useIntl instead of injectIntl * feat<site/IconSearch>: fix ts type error * feat<site/IconSearch>: use intl.formatMessage to render text * docs: Adjust home btn sizw * docs: Update doc * feat: v5 site overview page (#38131) * feat: site * fix: fix * feat: v5 site overview page * fix: fix path * fix: fix * fix: fix * docs: fix margin logic * feat: v5 site change-log page (#38137) * feat: v5 site change-log page (#38162) * docs: site redirect to home pag * docs: theme picker * docs: use react-intl from dumi (#38183) * docs: Theme Picker * docs: update dumi config * docs: home back fix * docs: picker colorful * docs: locale of it * docs: update components desc * docs: site of links * docs: update components list * docs: update desc * feat: Migrate `DemoWrapper` component (#38166) * feat: Migrate `DemoWrapper` component * feat: remove invalid comments and add comment for `key` prop * docs: FloatButton pure panel * chore: update demo * chore: update dumi config * Revert "chore: update demo" This reverts commit 028265d3ba5987df5f13c3e9d42cf76cb1812b2e. * chore: test logic adjust to support cnpm modules * chore: add locale alias * docs: /index to / * docs: add locale redirect head script * chore: adjust compact * docs: fix missing token * feat: compact switch * chore: code clean * docs: update home * docs: fix radius token * docs: hash of it * chore: adjust home page * docs: Add background map * docs: site theme bac logic * docs: avatar * docs: update logo color * docs: home banner * docs: adjust tour size * docs: purepanl update * docs: transfooter * docs: update banner gif * docs: content (#38361) * docs: title & EditButton * docs: content * chore: fix toc * docs: resource page * docs: transform resource data from hast * docs: filename & Resource Card * chore: enable prerender * chore: remove less * docs: toc style * chore: fix lint * docs: fix Layout page * docs: fix CP page * chore: update demos * docs: workaround for export dynamic html * chore: enable demo eslint * docs: table style * fix: header shadow * chore: update snapshot * fix: toc style * docs: add title * docs: Adjust site * feat: helmet * docs: site css * fix: description * feat: toc debug * docs: update config-provider * feat: use colorPanel * fix: colorPanel value * feat: anchor ink ball style * feat: apply theme editor * fix: code block style * chore: update demo * chore: fix lint * chore: code clean * chore: update snapshot * feat: ts2js * chore: description * docs: site ready for ssr includes: - move client render logic to useEffect in site theme - extract antd cssinjs to a single css file like bisheng - workaround to support react@18 pipeableStream for emotion * chore: bump testing lib * docs: font size of title * chore: remove react-sortable-hoc * chore: update snapshot * chore: update script Co-authored-by: PeachScript <scdzwyxst@gmail.com> Co-authored-by: MadCcc <1075746765@qq.com> Co-authored-by: zqran <uuxnet@gmail.com> Co-authored-by: TrickyPi <530257315@qq.com> Co-authored-by: lijianan <574980606@qq.com>
580 lines
18 KiB
TypeScript
580 lines
18 KiB
TypeScript
import classNames from 'classnames';
|
|
import RcTable, { Summary } from 'rc-table';
|
|
import { convertChildrenToColumns } from 'rc-table/lib/hooks/useColumns';
|
|
import type { TableProps as RcTableProps } from 'rc-table/lib/Table';
|
|
import { INTERNAL_HOOKS } from 'rc-table/lib/Table';
|
|
import omit from 'rc-util/lib/omit';
|
|
import * as React from 'react';
|
|
import { ConfigContext } from '../config-provider/context';
|
|
import defaultRenderEmpty from '../config-provider/defaultRenderEmpty';
|
|
import type { SizeType } from '../config-provider/SizeContext';
|
|
import SizeContext from '../config-provider/SizeContext';
|
|
import useBreakpoint from '../grid/hooks/useBreakpoint';
|
|
import defaultLocale from '../locale/en_US';
|
|
import Pagination from '../pagination';
|
|
import type { SpinProps } from '../spin';
|
|
import Spin from '../spin';
|
|
import type { TooltipProps } from '../tooltip';
|
|
import type { Breakpoint } from '../_util/responsiveObserve';
|
|
import scrollTo from '../_util/scrollTo';
|
|
import warning from '../_util/warning';
|
|
import Column from './Column';
|
|
import ColumnGroup from './ColumnGroup';
|
|
import renderExpandIcon from './ExpandIcon';
|
|
import type { FilterState } from './hooks/useFilter';
|
|
import useFilter, { getFilterData } from './hooks/useFilter';
|
|
import useLazyKVMap from './hooks/useLazyKVMap';
|
|
import usePagination, { DEFAULT_PAGE_SIZE, getPaginationParam } from './hooks/usePagination';
|
|
import useSelection, {
|
|
SELECTION_ALL,
|
|
SELECTION_COLUMN,
|
|
SELECTION_INVERT,
|
|
SELECTION_NONE,
|
|
} from './hooks/useSelection';
|
|
import type { SortState } from './hooks/useSorter';
|
|
import useSorter, { getSortData } from './hooks/useSorter';
|
|
import useTitleColumns from './hooks/useTitleColumns';
|
|
import type {
|
|
ColumnTitleProps,
|
|
ColumnType,
|
|
ExpandableConfig,
|
|
ExpandType,
|
|
FilterValue,
|
|
GetPopupContainer,
|
|
GetRowKey,
|
|
SorterResult,
|
|
SortOrder,
|
|
TableAction,
|
|
TableCurrentDataSource,
|
|
TableLocale,
|
|
TableRowSelection,
|
|
ColumnsType,
|
|
TablePaginationConfig,
|
|
} from './interface';
|
|
|
|
import useStyle from './style';
|
|
|
|
export type { ColumnsType, TablePaginationConfig };
|
|
|
|
const EMPTY_LIST: any[] = [];
|
|
|
|
interface ChangeEventInfo<RecordType> {
|
|
pagination: {
|
|
current?: number;
|
|
pageSize?: number;
|
|
total?: number;
|
|
};
|
|
filters: Record<string, FilterValue | null>;
|
|
sorter: SorterResult<RecordType> | SorterResult<RecordType>[];
|
|
|
|
filterStates: FilterState<RecordType>[];
|
|
sorterStates: SortState<RecordType>[];
|
|
|
|
resetPagination: Function;
|
|
}
|
|
|
|
export interface TableProps<RecordType>
|
|
extends Omit<
|
|
RcTableProps<RecordType>,
|
|
| 'transformColumns'
|
|
| 'internalHooks'
|
|
| 'internalRefs'
|
|
| 'data'
|
|
| 'columns'
|
|
| 'scroll'
|
|
| 'emptyText'
|
|
> {
|
|
dropdownPrefixCls?: string;
|
|
dataSource?: RcTableProps<RecordType>['data'];
|
|
columns?: ColumnsType<RecordType>;
|
|
pagination?: false | TablePaginationConfig;
|
|
loading?: boolean | SpinProps;
|
|
size?: SizeType;
|
|
bordered?: boolean;
|
|
locale?: TableLocale;
|
|
|
|
onChange?: (
|
|
pagination: TablePaginationConfig,
|
|
filters: Record<string, FilterValue | null>,
|
|
sorter: SorterResult<RecordType> | SorterResult<RecordType>[],
|
|
extra: TableCurrentDataSource<RecordType>,
|
|
) => void;
|
|
rowSelection?: TableRowSelection<RecordType>;
|
|
|
|
getPopupContainer?: GetPopupContainer;
|
|
scroll?: RcTableProps<RecordType>['scroll'] & {
|
|
scrollToFirstRowOnChange?: boolean;
|
|
};
|
|
sortDirections?: SortOrder[];
|
|
showSorterTooltip?: boolean | TooltipProps;
|
|
}
|
|
|
|
function InternalTable<RecordType extends object = any>(
|
|
props: TableProps<RecordType>,
|
|
ref: React.MutableRefObject<HTMLDivElement>,
|
|
) {
|
|
const {
|
|
prefixCls: customizePrefixCls,
|
|
className,
|
|
style,
|
|
size: customizeSize,
|
|
bordered,
|
|
dropdownPrefixCls: customizeDropdownPrefixCls,
|
|
dataSource,
|
|
pagination,
|
|
rowSelection,
|
|
rowKey = 'key',
|
|
rowClassName,
|
|
columns,
|
|
children,
|
|
childrenColumnName: legacyChildrenColumnName,
|
|
onChange,
|
|
getPopupContainer,
|
|
loading,
|
|
expandIcon,
|
|
expandable,
|
|
expandedRowRender,
|
|
expandIconColumnIndex,
|
|
indentSize,
|
|
scroll,
|
|
sortDirections,
|
|
locale,
|
|
showSorterTooltip = true,
|
|
} = props;
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
warning(
|
|
!(typeof rowKey === 'function' && rowKey.length > 1),
|
|
'Table',
|
|
'`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.',
|
|
);
|
|
}
|
|
|
|
const baseColumns = React.useMemo(
|
|
() => columns || (convertChildrenToColumns(children) as ColumnsType<RecordType>),
|
|
[columns, children],
|
|
);
|
|
const needResponsive = React.useMemo(
|
|
() => baseColumns.some((col: ColumnType<RecordType>) => col.responsive),
|
|
[baseColumns],
|
|
);
|
|
|
|
const screens = useBreakpoint(needResponsive);
|
|
|
|
const mergedColumns = React.useMemo(() => {
|
|
const matched = new Set(Object.keys(screens).filter((m: Breakpoint) => screens[m]));
|
|
|
|
return baseColumns.filter(
|
|
c => !c.responsive || c.responsive.some((r: Breakpoint) => matched.has(r)),
|
|
);
|
|
}, [baseColumns, screens]);
|
|
|
|
const tableProps = omit(props, ['className', 'style', 'columns']) as TableProps<RecordType>;
|
|
|
|
const size = React.useContext(SizeContext);
|
|
const {
|
|
locale: contextLocale = defaultLocale,
|
|
renderEmpty,
|
|
direction,
|
|
} = React.useContext(ConfigContext);
|
|
const mergedSize = customizeSize || size;
|
|
const tableLocale = { ...contextLocale.Table, ...locale } as TableLocale;
|
|
const rawData: readonly RecordType[] = dataSource || EMPTY_LIST;
|
|
|
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
|
const prefixCls = getPrefixCls('table', customizePrefixCls);
|
|
const dropdownPrefixCls = getPrefixCls('dropdown', customizeDropdownPrefixCls);
|
|
|
|
const mergedExpandable: ExpandableConfig<RecordType> = {
|
|
childrenColumnName: legacyChildrenColumnName,
|
|
expandIconColumnIndex,
|
|
...expandable,
|
|
};
|
|
const { childrenColumnName = 'children' } = mergedExpandable;
|
|
|
|
const expandType = React.useMemo<ExpandType>(() => {
|
|
if (rawData.some(item => (item as any)?.[childrenColumnName])) {
|
|
return 'nest';
|
|
}
|
|
|
|
if (expandedRowRender || (expandable && expandable.expandedRowRender)) {
|
|
return 'row';
|
|
}
|
|
|
|
return null;
|
|
}, [rawData]);
|
|
|
|
const internalRefs = {
|
|
body: React.useRef<HTMLDivElement>(),
|
|
};
|
|
|
|
// ============================ RowKey ============================
|
|
const getRowKey = React.useMemo<GetRowKey<RecordType>>(() => {
|
|
if (typeof rowKey === 'function') {
|
|
return rowKey;
|
|
}
|
|
|
|
return (record: RecordType) => (record as any)?.[rowKey as string];
|
|
}, [rowKey]);
|
|
|
|
const [getRecordByKey] = useLazyKVMap(rawData, childrenColumnName, getRowKey);
|
|
|
|
// ============================ Events =============================
|
|
const changeEventInfo: Partial<ChangeEventInfo<RecordType>> = {};
|
|
|
|
const triggerOnChange = (
|
|
info: Partial<ChangeEventInfo<RecordType>>,
|
|
action: TableAction,
|
|
reset: boolean = false,
|
|
) => {
|
|
const changeInfo = {
|
|
...changeEventInfo,
|
|
...info,
|
|
};
|
|
|
|
if (reset) {
|
|
changeEventInfo.resetPagination!();
|
|
|
|
// Reset event param
|
|
if (changeInfo.pagination!.current) {
|
|
changeInfo.pagination!.current = 1;
|
|
}
|
|
|
|
// Trigger pagination events
|
|
if (pagination && pagination.onChange) {
|
|
pagination.onChange(1, changeInfo.pagination!.pageSize!);
|
|
}
|
|
}
|
|
|
|
if (scroll && scroll.scrollToFirstRowOnChange !== false && internalRefs.body.current) {
|
|
scrollTo(0, {
|
|
getContainer: () => internalRefs.body.current!,
|
|
});
|
|
}
|
|
|
|
onChange?.(changeInfo.pagination!, changeInfo.filters!, changeInfo.sorter!, {
|
|
currentDataSource: getFilterData(
|
|
getSortData(rawData, changeInfo.sorterStates!, childrenColumnName),
|
|
changeInfo.filterStates!,
|
|
),
|
|
action,
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to read
|
|
* state out and then put it back to title render. Move these code into `hooks` but still too
|
|
* complex. We should provides Table props like `sorter` & `filter` to handle control in next big
|
|
* version.
|
|
*/
|
|
|
|
// ============================ Sorter =============================
|
|
const onSorterChange = (
|
|
sorter: SorterResult<RecordType> | SorterResult<RecordType>[],
|
|
sorterStates: SortState<RecordType>[],
|
|
) => {
|
|
triggerOnChange(
|
|
{
|
|
sorter,
|
|
sorterStates,
|
|
},
|
|
'sort',
|
|
false,
|
|
);
|
|
};
|
|
const [transformSorterColumns, sortStates, sorterTitleProps, getSorters] = useSorter<RecordType>({
|
|
prefixCls,
|
|
mergedColumns,
|
|
onSorterChange,
|
|
sortDirections: sortDirections || ['ascend', 'descend'],
|
|
tableLocale,
|
|
showSorterTooltip,
|
|
});
|
|
const sortedData = React.useMemo(
|
|
() => getSortData(rawData, sortStates, childrenColumnName),
|
|
[rawData, sortStates],
|
|
);
|
|
|
|
changeEventInfo.sorter = getSorters();
|
|
changeEventInfo.sorterStates = sortStates;
|
|
|
|
// ============================ Filter ============================
|
|
const onFilterChange = (
|
|
filters: Record<string, FilterValue>,
|
|
filterStates: FilterState<RecordType>[],
|
|
) => {
|
|
triggerOnChange(
|
|
{
|
|
filters,
|
|
filterStates,
|
|
},
|
|
'filter',
|
|
true,
|
|
);
|
|
};
|
|
|
|
const [transformFilterColumns, filterStates, filters] = useFilter<RecordType>({
|
|
prefixCls,
|
|
locale: tableLocale,
|
|
dropdownPrefixCls,
|
|
mergedColumns,
|
|
onFilterChange,
|
|
getPopupContainer,
|
|
});
|
|
const mergedData = getFilterData(sortedData, filterStates);
|
|
|
|
changeEventInfo.filters = filters;
|
|
changeEventInfo.filterStates = filterStates;
|
|
|
|
// ============================ Column ============================
|
|
const columnTitleProps = React.useMemo<ColumnTitleProps<RecordType>>(() => {
|
|
const mergedFilters: Record<string, FilterValue> = {};
|
|
Object.keys(filters).forEach(filterKey => {
|
|
if (filters[filterKey] !== null) {
|
|
mergedFilters[filterKey] = filters[filterKey]!;
|
|
}
|
|
});
|
|
return {
|
|
...sorterTitleProps,
|
|
filters: mergedFilters,
|
|
};
|
|
}, [sorterTitleProps, filters]);
|
|
|
|
const [transformTitleColumns] = useTitleColumns(columnTitleProps);
|
|
|
|
// ========================== Pagination ==========================
|
|
const onPaginationChange = (current: number, pageSize: number) => {
|
|
triggerOnChange(
|
|
{
|
|
pagination: { ...changeEventInfo.pagination, current, pageSize },
|
|
},
|
|
'paginate',
|
|
);
|
|
};
|
|
|
|
const [mergedPagination, resetPagination] = usePagination(
|
|
mergedData.length,
|
|
pagination,
|
|
onPaginationChange,
|
|
);
|
|
|
|
changeEventInfo.pagination =
|
|
pagination === false ? {} : getPaginationParam(pagination, mergedPagination);
|
|
|
|
changeEventInfo.resetPagination = resetPagination;
|
|
|
|
// ============================= Data =============================
|
|
const pageData = React.useMemo<RecordType[]>(() => {
|
|
if (pagination === false || !mergedPagination.pageSize) {
|
|
return mergedData;
|
|
}
|
|
|
|
const { current = 1, total, pageSize = DEFAULT_PAGE_SIZE } = mergedPagination;
|
|
warning(current > 0, 'Table', '`current` should be positive number.');
|
|
|
|
// Dynamic table data
|
|
if (mergedData.length < total!) {
|
|
if (mergedData.length > pageSize) {
|
|
warning(
|
|
false,
|
|
'Table',
|
|
'`dataSource` length is less than `pagination.total` but large than `pagination.pageSize`. Please make sure your config correct data with async mode.',
|
|
);
|
|
return mergedData.slice((current - 1) * pageSize, current * pageSize);
|
|
}
|
|
return mergedData;
|
|
}
|
|
|
|
return mergedData.slice((current - 1) * pageSize, current * pageSize);
|
|
}, [
|
|
!!pagination,
|
|
mergedData,
|
|
mergedPagination && mergedPagination.current,
|
|
mergedPagination && mergedPagination.pageSize,
|
|
mergedPagination && mergedPagination.total,
|
|
]);
|
|
|
|
// ========================== Selections ==========================
|
|
const [transformSelectionColumns, selectedKeySet] = useSelection<RecordType>(rowSelection, {
|
|
prefixCls,
|
|
data: mergedData,
|
|
pageData,
|
|
getRowKey,
|
|
getRecordByKey,
|
|
expandType,
|
|
childrenColumnName,
|
|
locale: tableLocale,
|
|
getPopupContainer,
|
|
});
|
|
|
|
const internalRowClassName = (record: RecordType, index: number, indent: number) => {
|
|
let mergedRowClassName: string;
|
|
if (typeof rowClassName === 'function') {
|
|
mergedRowClassName = classNames(rowClassName(record, index, indent));
|
|
} else {
|
|
mergedRowClassName = classNames(rowClassName);
|
|
}
|
|
|
|
return classNames(
|
|
{
|
|
[`${prefixCls}-row-selected`]: selectedKeySet.has(getRowKey(record, index)),
|
|
},
|
|
mergedRowClassName,
|
|
);
|
|
};
|
|
|
|
// ========================== Expandable ==========================
|
|
|
|
// Pass origin render status into `rc-table`, this can be removed when refactor with `rc-table`
|
|
(mergedExpandable as any).__PARENT_RENDER_ICON__ = mergedExpandable.expandIcon;
|
|
|
|
// Customize expandable icon
|
|
mergedExpandable.expandIcon =
|
|
mergedExpandable.expandIcon || expandIcon || renderExpandIcon(tableLocale!);
|
|
|
|
// Adjust expand icon index, no overwrite expandIconColumnIndex if set.
|
|
if (expandType === 'nest' && mergedExpandable.expandIconColumnIndex === undefined) {
|
|
mergedExpandable.expandIconColumnIndex = rowSelection ? 1 : 0;
|
|
} else if (mergedExpandable.expandIconColumnIndex! > 0 && rowSelection) {
|
|
mergedExpandable.expandIconColumnIndex! -= 1;
|
|
}
|
|
|
|
// Indent size
|
|
if (typeof mergedExpandable.indentSize !== 'number') {
|
|
mergedExpandable.indentSize = typeof indentSize === 'number' ? indentSize : 15;
|
|
}
|
|
|
|
// ============================ Render ============================
|
|
const transformColumns = React.useCallback(
|
|
(innerColumns: ColumnsType<RecordType>): ColumnsType<RecordType> =>
|
|
transformTitleColumns(
|
|
transformSelectionColumns(transformFilterColumns(transformSorterColumns(innerColumns))),
|
|
),
|
|
[transformSorterColumns, transformFilterColumns, transformSelectionColumns],
|
|
);
|
|
|
|
let topPaginationNode: React.ReactNode;
|
|
let bottomPaginationNode: React.ReactNode;
|
|
if (pagination !== false && mergedPagination?.total) {
|
|
let paginationSize: TablePaginationConfig['size'];
|
|
if (mergedPagination.size) {
|
|
paginationSize = mergedPagination.size;
|
|
} else {
|
|
paginationSize = mergedSize === 'small' || mergedSize === 'middle' ? 'small' : undefined;
|
|
}
|
|
|
|
const renderPagination = (position: string) => (
|
|
<Pagination
|
|
{...mergedPagination}
|
|
className={classNames(
|
|
`${prefixCls}-pagination ${prefixCls}-pagination-${position}`,
|
|
mergedPagination.className,
|
|
)}
|
|
size={paginationSize}
|
|
/>
|
|
);
|
|
const defaultPosition = direction === 'rtl' ? 'left' : 'right';
|
|
const { position } = mergedPagination;
|
|
if (position !== null && Array.isArray(position)) {
|
|
const topPos = position.find(p => p.includes('top'));
|
|
const bottomPos = position.find(p => p.includes('bottom'));
|
|
const isDisable = position.every(p => `${p}` === 'none');
|
|
if (!topPos && !bottomPos && !isDisable) {
|
|
bottomPaginationNode = renderPagination(defaultPosition);
|
|
}
|
|
if (topPos) {
|
|
topPaginationNode = renderPagination(topPos!.toLowerCase().replace('top', ''));
|
|
}
|
|
if (bottomPos) {
|
|
bottomPaginationNode = renderPagination(bottomPos!.toLowerCase().replace('bottom', ''));
|
|
}
|
|
} else {
|
|
bottomPaginationNode = renderPagination(defaultPosition);
|
|
}
|
|
}
|
|
|
|
// >>>>>>>>> Spinning
|
|
let spinProps: SpinProps | undefined;
|
|
if (typeof loading === 'boolean') {
|
|
spinProps = {
|
|
spinning: loading,
|
|
};
|
|
} else if (typeof loading === 'object') {
|
|
spinProps = {
|
|
spinning: true,
|
|
...loading,
|
|
};
|
|
}
|
|
|
|
// Style
|
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
|
|
|
const wrapperClassNames = classNames(
|
|
`${prefixCls}-wrapper`,
|
|
{
|
|
[`${prefixCls}-wrapper-rtl`]: direction === 'rtl',
|
|
},
|
|
className,
|
|
hashId,
|
|
);
|
|
return wrapSSR(
|
|
<div ref={ref} className={wrapperClassNames} style={style}>
|
|
<Spin spinning={false} {...spinProps}>
|
|
{topPaginationNode}
|
|
<RcTable<RecordType>
|
|
{...tableProps}
|
|
columns={mergedColumns as RcTableProps<RecordType>['columns']}
|
|
direction={direction}
|
|
expandable={mergedExpandable}
|
|
prefixCls={prefixCls}
|
|
className={classNames({
|
|
[`${prefixCls}-middle`]: mergedSize === 'middle',
|
|
[`${prefixCls}-small`]: mergedSize === 'small',
|
|
[`${prefixCls}-bordered`]: bordered,
|
|
[`${prefixCls}-empty`]: rawData.length === 0,
|
|
})}
|
|
data={pageData}
|
|
rowKey={getRowKey}
|
|
rowClassName={internalRowClassName}
|
|
emptyText={(locale && locale.emptyText) || (renderEmpty || defaultRenderEmpty)('Table')}
|
|
// Internal
|
|
internalHooks={INTERNAL_HOOKS}
|
|
internalRefs={internalRefs as any}
|
|
transformColumns={transformColumns as RcTableProps<RecordType>['transformColumns']}
|
|
/>
|
|
{bottomPaginationNode}
|
|
</Spin>
|
|
</div>,
|
|
);
|
|
}
|
|
|
|
const ForwardTable = React.forwardRef(InternalTable) as <RecordType extends object = any>(
|
|
props: React.PropsWithChildren<TableProps<RecordType>> & { ref?: React.Ref<HTMLDivElement> },
|
|
) => React.ReactElement;
|
|
|
|
type InternalTableType = typeof ForwardTable;
|
|
|
|
interface TableInterface extends InternalTableType {
|
|
SELECTION_COLUMN: typeof SELECTION_COLUMN;
|
|
EXPAND_COLUMN: typeof RcTable.EXPAND_COLUMN;
|
|
SELECTION_ALL: 'SELECT_ALL';
|
|
SELECTION_INVERT: 'SELECT_INVERT';
|
|
SELECTION_NONE: 'SELECT_NONE';
|
|
Column: typeof Column;
|
|
ColumnGroup: typeof ColumnGroup;
|
|
Summary: typeof Summary;
|
|
}
|
|
|
|
const Table = ForwardTable as TableInterface;
|
|
|
|
Table.SELECTION_COLUMN = SELECTION_COLUMN;
|
|
Table.EXPAND_COLUMN = RcTable.EXPAND_COLUMN;
|
|
Table.SELECTION_ALL = SELECTION_ALL;
|
|
Table.SELECTION_INVERT = SELECTION_INVERT;
|
|
Table.SELECTION_NONE = SELECTION_NONE;
|
|
Table.Column = Column;
|
|
Table.ColumnGroup = ColumnGroup;
|
|
Table.Summary = Summary;
|
|
|
|
export default Table;
|