This commit is contained in:
2026-05-25 17:08:18 +08:00
parent df501f6151
commit f1259b71b5
9178 changed files with 1626125 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
import type { AnyObject } from '../_util/type';
import type { ColumnType } from './interface';
export interface ColumnProps<RecordType = AnyObject> extends ColumnType<RecordType> {
children?: null;
}
/** This is a syntactic sugar for `columns` prop. So HOC will not work on this. */
declare const Column: <RecordType extends AnyObject>(_: ColumnProps<RecordType>) => null;
export default Column;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/* istanbul ignore next */
/** This is a syntactic sugar for `columns` prop. So HOC will not work on this. */
const Column = _ => null;
var _default = exports.default = Column;
+10
View File
@@ -0,0 +1,10 @@
import type * as React from 'react';
import type { AnyObject } from '../_util/type';
import type { ColumnProps } from './Column';
import type { ColumnType } from './interface';
export interface ColumnGroupProps<RecordType = AnyObject> extends Omit<ColumnType<RecordType>, 'children'> {
children: React.ReactElement<ColumnProps<RecordType>> | React.ReactElement<ColumnProps<RecordType>>[];
}
/** This is a syntactic sugar for `columns` prop. So HOC will not work on this. */
declare const ColumnGroup: <RecordType extends AnyObject>(_: ColumnGroupProps<RecordType>) => null;
export default ColumnGroup;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/* istanbul ignore next */
/** This is a syntactic sugar for `columns` prop. So HOC will not work on this. */
const ColumnGroup = _ => null;
var _default = exports.default = ColumnGroup;
+12
View File
@@ -0,0 +1,12 @@
import * as React from 'react';
import type { AnyObject } from '../_util/type';
import type { TableLocale } from './interface';
interface DefaultExpandIconProps<RecordType = AnyObject> {
prefixCls: string;
record: RecordType;
expanded: boolean;
expandable: boolean;
onExpand: (record: RecordType, e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
}
declare function renderExpandIcon(locale: TableLocale): <RecordType extends AnyObject = AnyObject>(props: DefaultExpandIconProps<RecordType>) => React.JSX.Element;
export default renderExpandIcon;
+37
View File
@@ -0,0 +1,37 @@
"use strict";
"use client";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _clsx = require("clsx");
function renderExpandIcon(locale) {
return props => {
const {
prefixCls,
onExpand,
record,
expanded,
expandable
} = props;
const iconPrefix = `${prefixCls}-row-expand-icon`;
return /*#__PURE__*/React.createElement("button", {
type: "button",
onClick: e => {
onExpand(record, e);
e.stopPropagation();
},
className: (0, _clsx.clsx)(iconPrefix, {
[`${iconPrefix}-spaced`]: !expandable,
[`${iconPrefix}-expanded`]: expandable && expanded,
[`${iconPrefix}-collapsed`]: expandable && !expanded
}),
"aria-label": expanded ? locale.collapse : locale.expand,
"aria-expanded": expanded
});
};
}
var _default = exports.default = renderExpandIcon;
+73
View File
@@ -0,0 +1,73 @@
import * as React from 'react';
import type { TableProps as RcTableProps } from '@rc-component/table';
import type { SemanticClassNamesType, SemanticStylesType } from '../_util/hooks';
import type { AnyObject } from '../_util/type';
import type { SizeType } from '../config-provider/SizeContext';
import type { PaginationSemanticClassNames, PaginationSemanticStyles } from '../pagination/Pagination';
import type { SpinProps } from '../spin';
import type { ColumnsType, FilterValue, GetPopupContainer, RefInternalTable, SorterResult, SorterTooltipProps, SortOrder, TableCurrentDataSource, TableLocale, TablePaginationConfig, TableRowSelection } from './interface';
export type { ColumnsType, TablePaginationConfig };
export type TableSemanticName = keyof TableSemanticClassNames & keyof TableSemanticStyles;
export type TableSemanticClassNames = {
root?: string;
section?: string;
title?: string;
footer?: string;
content?: string;
};
export type TableSemanticStyles = {
root?: React.CSSProperties;
section?: React.CSSProperties;
title?: React.CSSProperties;
footer?: React.CSSProperties;
content?: React.CSSProperties;
};
export type ComponentsSemantic = keyof ComponentsSemanticClassNames & keyof ComponentsSemanticStyles;
export type ComponentsSemanticClassNames = {
wrapper?: string;
cell?: string;
row?: string;
};
export type ComponentsSemanticStyles = {
wrapper?: React.CSSProperties;
cell?: React.CSSProperties;
row?: React.CSSProperties;
};
export type TableClassNamesType<RecordType = AnyObject> = SemanticClassNamesType<TableProps<RecordType>, TableSemanticClassNames, {
body?: ComponentsSemanticClassNames;
header?: ComponentsSemanticClassNames;
pagination?: PaginationSemanticClassNames;
}>;
export type TableStylesType<RecordType = AnyObject> = SemanticStylesType<TableProps<RecordType>, TableSemanticStyles, {
body?: ComponentsSemanticStyles;
header?: ComponentsSemanticStyles;
pagination?: PaginationSemanticStyles;
}>;
export interface TableProps<RecordType = AnyObject> extends Omit<RcTableProps<RecordType>, 'transformColumns' | 'internalHooks' | 'internalRefs' | 'data' | 'columns' | 'scroll' | 'emptyText' | 'classNames' | 'styles'> {
classNames?: TableClassNamesType<RecordType>;
styles?: TableStylesType<RecordType>;
dropdownPrefixCls?: string;
dataSource?: RcTableProps<RecordType>['data'];
columns?: ColumnsType<RecordType>;
pagination?: false | TablePaginationConfig;
loading?: boolean | SpinProps;
size?: SizeType;
bordered?: boolean;
locale?: TableLocale;
rootClassName?: string;
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 | SorterTooltipProps;
virtual?: boolean;
}
/** Same as `TableProps` but we need record parent render times */
export interface InternalTableProps<RecordType = AnyObject> extends TableProps<RecordType> {
_renderTimes: number;
}
declare const _default_1: RefInternalTable;
export default _default_1;
+489
View File
@@ -0,0 +1,489 @@
"use strict";
"use client";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _table = require("@rc-component/table");
var _useColumns = require("@rc-component/table/lib/hooks/useColumns");
var _util = require("@rc-component/util");
var _clsx = require("clsx");
var _hooks = require("../_util/hooks");
var _is = require("../_util/is");
var _scrollTo = _interopRequireDefault(require("../_util/scrollTo"));
var _warning = require("../_util/warning");
var _configProvider = _interopRequireDefault(require("../config-provider"));
var _context = require("../config-provider/context");
var _defaultRenderEmpty = _interopRequireDefault(require("../config-provider/defaultRenderEmpty"));
var _useCSSVarCls = _interopRequireDefault(require("../config-provider/hooks/useCSSVarCls"));
var _useSize = _interopRequireDefault(require("../config-provider/hooks/useSize"));
var _useBreakpoint = _interopRequireDefault(require("../grid/hooks/useBreakpoint"));
var _locale = require("../locale");
var _en_US = _interopRequireDefault(require("../locale/en_US"));
var _pagination = _interopRequireDefault(require("../pagination"));
var _spin = _interopRequireDefault(require("../spin"));
var _internal = require("../theme/internal");
var _ExpandIcon = _interopRequireDefault(require("./ExpandIcon"));
var _useContainerWidth = _interopRequireDefault(require("./hooks/useContainerWidth"));
var _useFilter = _interopRequireWildcard(require("./hooks/useFilter"));
var _useLazyKVMap = _interopRequireDefault(require("./hooks/useLazyKVMap"));
var _usePagination = _interopRequireWildcard(require("./hooks/usePagination"));
var _useSelection = _interopRequireDefault(require("./hooks/useSelection"));
var _useSorter = _interopRequireWildcard(require("./hooks/useSorter"));
var _useTitleColumns = _interopRequireDefault(require("./hooks/useTitleColumns"));
var _RcTable = _interopRequireDefault(require("./RcTable"));
var _VirtualTable = _interopRequireDefault(require("./RcTable/VirtualTable"));
var _style = _interopRequireDefault(require("./style"));
var _TableMeasureRowContext = _interopRequireDefault(require("./TableMeasureRowContext"));
const EMPTY_LIST = [];
const InternalTable = (props, ref) => {
const {
prefixCls: customizePrefixCls,
className,
rootClassName,
style,
classNames,
styles,
size: customizeSize,
bordered,
dropdownPrefixCls: customizeDropdownPrefixCls,
dataSource,
pagination,
rowSelection: customizeRowSelection,
rowKey: customizeRowKey,
rowClassName,
columns,
children,
childrenColumnName: legacyChildrenColumnName,
onChange,
getPopupContainer,
loading,
expandIcon,
expandable,
expandedRowRender,
expandIconColumnIndex,
indentSize,
scroll,
sortDirections,
locale,
showSorterTooltip = {
target: 'full-header'
},
virtual
} = props;
const warning = (0, _warning.devUseWarning)('Table');
const baseColumns = React.useMemo(() => columns || (0, _useColumns.convertChildrenToColumns)(children), [columns, children]);
const needResponsive = React.useMemo(() => baseColumns.some(col => col.responsive), [baseColumns]);
const screens = (0, _useBreakpoint.default)(needResponsive);
const mergedColumns = React.useMemo(() => {
const matched = new Set(Object.keys(screens).filter(m => screens[m]));
return baseColumns.filter(c => !c.responsive || c.responsive.some(r => matched.has(r)));
}, [baseColumns, screens]);
const tableProps = (0, _util.omit)(props, ['className', 'style', 'columns']);
const {
locale: contextLocale = _en_US.default,
table
} = React.useContext(_context.ConfigContext);
const {
getPrefixCls,
direction,
renderEmpty,
getPopupContainer: getContextPopupContainer,
className: contextClassName,
style: contextStyle,
classNames: contextClassNames,
styles: contextStyles
} = (0, _context.useComponentConfig)('table');
const mergedSize = (0, _useSize.default)(ctx => customizeSize === 'middle' ? 'medium' : customizeSize ?? ctx);
// =========== Merged Props for Semantic ==========
const mergedProps = {
...props,
size: mergedSize,
bordered
};
const [mergedClassNames, mergedStyles] = (0, _hooks.useMergeSemantic)([contextClassNames, classNames], [contextStyles, styles], {
props: mergedProps
}, {
pagination: {
_default: 'root'
},
header: {
_default: 'wrapper'
},
body: {
_default: 'wrapper'
}
});
const tableLocale = {
...contextLocale.Table,
...locale
};
const [globalLocale] = (0, _locale.useLocale)('global', _en_US.default.global);
const rawData = dataSource || EMPTY_LIST;
const prefixCls = getPrefixCls('table', customizePrefixCls);
const dropdownPrefixCls = getPrefixCls('dropdown', customizeDropdownPrefixCls);
const [, token] = (0, _internal.useToken)();
const mergedRowSelection = React.useMemo(() => {
return (0, _is.isPlainObject)(customizeRowSelection) ? {
columnWidth: token.Table?.selectionColumnWidth,
...customizeRowSelection
} : customizeRowSelection;
}, [customizeRowSelection, token.Table?.selectionColumnWidth]);
const rootCls = (0, _useCSSVarCls.default)(prefixCls);
const [hashId, cssVarCls] = (0, _style.default)(prefixCls, rootCls);
const mergedExpandable = {
childrenColumnName: legacyChildrenColumnName,
expandIconColumnIndex,
...expandable,
expandIcon: expandable?.expandIcon ?? table?.expandable?.expandIcon
};
const {
childrenColumnName = 'children'
} = mergedExpandable;
const expandType = React.useMemo(() => {
if (rawData.some(item => item?.[childrenColumnName])) {
return 'nest';
}
if (expandedRowRender || expandable?.expandedRowRender) {
return 'row';
}
return null;
}, [childrenColumnName, rawData]);
const internalRef = {
body: React.useRef(null)
};
// ============================ Width =============================
const getContainerWidth = (0, _useContainerWidth.default)(prefixCls);
// ============================= Refs =============================
const rootRef = React.useRef(null);
const tblRef = React.useRef(null);
(0, _hooks.useProxyImperativeHandle)(ref, () => ({
...tblRef.current,
nativeElement: rootRef.current
}));
// ============================ RowKey ============================
const rowKey = customizeRowKey || table?.rowKey || 'key';
// ============================ Scroll ============================
const mergedScroll = scroll ?? table?.scroll;
if (process.env.NODE_ENV !== 'production') {
process.env.NODE_ENV !== "production" ? warning(!(typeof rowKey === 'function' && rowKey.length > 1), 'usage', '`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.') : void 0;
}
const getRowKey = React.useMemo(() => {
if (typeof rowKey === 'function') {
return rowKey;
}
return record => record?.[rowKey];
}, [rowKey]);
const [getRecordByKey] = (0, _useLazyKVMap.default)(rawData, childrenColumnName, getRowKey);
// ============================ Events =============================
const changeEventInfo = {};
const triggerOnChange = (info, action, reset = 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?.(1, changeInfo.pagination?.pageSize);
}
}
if (scroll && scroll.scrollToFirstRowOnChange !== false && internalRef.body.current) {
(0, _scrollTo.default)(0, {
getContainer: () => internalRef.body.current
});
}
onChange?.(changeInfo.pagination, changeInfo.filters, changeInfo.sorter, {
currentDataSource: (0, _useFilter.getFilterData)((0, _useSorter.getSortData)(rawData, changeInfo.sorterStates, childrenColumnName), changeInfo.filterStates, childrenColumnName),
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, sorterStates) => {
triggerOnChange({
sorter,
sorterStates
}, 'sort', false);
};
const [transformSorterColumns, sortStates, sorterTitleProps, getSorters] = (0, _useSorter.default)({
prefixCls,
mergedColumns,
onSorterChange,
sortDirections: sortDirections || ['ascend', 'descend'],
tableLocale,
showSorterTooltip,
globalLocale
});
const sortedData = React.useMemo(() => (0, _useSorter.getSortData)(rawData, sortStates, childrenColumnName), [childrenColumnName, rawData, sortStates]);
changeEventInfo.sorter = getSorters();
changeEventInfo.sorterStates = sortStates;
// ============================ Filter ============================
const onFilterChange = (filters, filterStates) => {
triggerOnChange({
filters,
filterStates
}, 'filter', true);
};
const [transformFilterColumns, filterStates, filters] = (0, _useFilter.default)({
prefixCls,
locale: tableLocale,
dropdownPrefixCls,
mergedColumns,
onFilterChange,
getPopupContainer: getPopupContainer || getContextPopupContainer,
rootClassName: (0, _clsx.clsx)(rootClassName, rootCls)
});
const mergedData = (0, _useFilter.getFilterData)(sortedData, filterStates, childrenColumnName);
changeEventInfo.filters = filters;
changeEventInfo.filterStates = filterStates;
// ============================ Column ============================
const columnTitleProps = React.useMemo(() => {
const mergedFilters = {};
Object.keys(filters).forEach(filterKey => {
if (filters[filterKey] !== null) {
mergedFilters[filterKey] = filters[filterKey];
}
});
return {
...sorterTitleProps,
filters: mergedFilters
};
}, [sorterTitleProps, filters]);
const [transformTitleColumns] = (0, _useTitleColumns.default)(columnTitleProps);
// ========================== Pagination ==========================
const onPaginationChange = (current, pageSize) => {
triggerOnChange({
pagination: {
...changeEventInfo.pagination,
current,
pageSize
}
}, 'paginate');
};
const [mergedPagination, resetPagination] = (0, _usePagination.default)(mergedData.length, onPaginationChange, pagination);
changeEventInfo.pagination = pagination === false ? {} : (0, _usePagination.getPaginationParam)(mergedPagination, pagination);
changeEventInfo.resetPagination = resetPagination;
// ============================= Data =============================
const pageData = React.useMemo(() => {
if (pagination === false || !mergedPagination.pageSize) {
return mergedData;
}
const {
current = 1,
total,
pageSize = _usePagination.DEFAULT_PAGE_SIZE
} = mergedPagination;
process.env.NODE_ENV !== "production" ? warning(current > 0, 'usage', '`current` should be positive number.') : void 0;
// Dynamic table data
if (mergedData.length < total) {
if (mergedData.length > pageSize) {
process.env.NODE_ENV !== "production" ? warning(false, 'usage', '`dataSource` length is less than `pagination.total` but large than `pagination.pageSize`. Please make sure your config correct data with async mode.') : void 0;
return mergedData.slice((current - 1) * pageSize, current * pageSize);
}
return mergedData;
}
return mergedData.slice((current - 1) * pageSize, current * pageSize);
}, [!!pagination, mergedData, mergedPagination?.current, mergedPagination?.pageSize, mergedPagination?.total]);
// ========================== Selections ==========================
const [transformSelectionColumns, selectedKeySet] = (0, _useSelection.default)({
prefixCls,
data: mergedData,
pageData,
getRowKey,
getRecordByKey,
expandType,
childrenColumnName,
locale: tableLocale,
getPopupContainer: getPopupContainer || getContextPopupContainer
}, mergedRowSelection);
const internalRowClassName = (record, index, indent) => {
const resolvedRowClassName = typeof rowClassName === 'function' ? rowClassName(record, index, indent) : rowClassName;
return (0, _clsx.clsx)({
[`${prefixCls}-row-selected`]: selectedKeySet.has(getRowKey(record, index))
}, resolvedRowClassName);
};
// ========================== Expandable ==========================
// Pass origin render status into `@rc-component/table`, this can be removed when refactor with `@rc-component/table`
mergedExpandable.__PARENT_RENDER_ICON__ = mergedExpandable.expandIcon;
// Customize expandable icon
mergedExpandable.expandIcon = mergedExpandable.expandIcon || expandIcon || (0, _ExpandIcon.default)(tableLocale);
// Adjust expand icon index, no overwrite expandIconColumnIndex if set.
if (expandType === 'nest' && mergedExpandable.expandIconColumnIndex === undefined) {
mergedExpandable.expandIconColumnIndex = mergedRowSelection ? 1 : 0;
} else if (mergedExpandable.expandIconColumnIndex > 0 && mergedRowSelection) {
mergedExpandable.expandIconColumnIndex -= 1;
}
// Indent size
if (typeof mergedExpandable.indentSize !== 'number') {
mergedExpandable.indentSize = (0, _is.isNumber)(indentSize) ? indentSize : 15;
}
// ============================ Render ============================
const transformColumns = React.useCallback(innerColumns => transformTitleColumns(transformSelectionColumns(transformFilterColumns(transformSorterColumns(innerColumns)))), [transformSorterColumns, transformFilterColumns, transformSelectionColumns]);
let topPaginationNode;
let bottomPaginationNode;
if (pagination !== false && mergedPagination?.total) {
let paginationSize;
if (mergedPagination.size) {
paginationSize = mergedPagination.size;
} else {
paginationSize = mergedSize === 'small' || mergedSize === 'medium' ? 'small' : undefined;
}
const renderPagination = (placement = 'end') => (/*#__PURE__*/React.createElement(_pagination.default, {
...mergedPagination,
classNames: mergedClassNames.pagination,
styles: mergedStyles.pagination,
className: (0, _clsx.clsx)(`${prefixCls}-pagination ${prefixCls}-pagination-${placement}`, mergedPagination.className),
size: paginationSize
}));
const {
placement,
position
} = mergedPagination;
const mergedPlacement = placement ?? position;
const normalizePlacement = pos => {
const lowerPos = pos.toLowerCase();
if (lowerPos.includes('center')) {
return 'center';
}
return lowerPos.includes('left') || lowerPos.includes('start') ? 'start' : 'end';
};
if (Array.isArray(mergedPlacement)) {
const [topPos, bottomPos] = ['top', 'bottom'].map(dir => mergedPlacement.find(p => p.includes(dir)));
const isDisable = mergedPlacement.every(p => `${p}` === 'none');
if (!topPos && !bottomPos && !isDisable) {
bottomPaginationNode = renderPagination();
}
if (topPos) {
topPaginationNode = renderPagination(normalizePlacement(topPos));
}
if (bottomPos) {
bottomPaginationNode = renderPagination(normalizePlacement(bottomPos));
}
} else {
bottomPaginationNode = renderPagination();
}
if (process.env.NODE_ENV !== 'production') {
warning.deprecated(!position, 'pagination.position', 'pagination.placement');
}
}
// >>>>>>>>> Spinning
const spinProps = React.useMemo(() => {
if (typeof loading === 'boolean') {
return {
spinning: loading
};
} else if ((0, _is.isPlainObject)(loading)) {
return {
spinning: true,
...loading
};
} else {
return undefined;
}
}, [loading]);
const wrappercls = (0, _clsx.clsx)(cssVarCls, rootCls, `${prefixCls}-wrapper`, contextClassName, {
[`${prefixCls}-wrapper-rtl`]: direction === 'rtl'
}, className, rootClassName, mergedClassNames.root, hashId);
const mergedStyle = {
...mergedStyles.root,
...contextStyle,
...style
};
// ========== empty ==========
const mergedEmptyNode = React.useMemo(() => {
// When dataSource is null/undefined (detected by reference equality with EMPTY_LIST),
// and the table is in a loading state, we only show the loading spinner without the empty placeholder.
// For empty arrays (datasource={[]}), both loading and empty states would normally be shown.
// discussion https://github.com/ant-design/ant-design/issues/54601#issuecomment-3158091383
if (spinProps?.spinning && rawData === EMPTY_LIST) {
return null;
}
if (typeof locale?.emptyText !== 'undefined') {
return locale.emptyText;
}
return renderEmpty?.('Table') || /*#__PURE__*/React.createElement(_defaultRenderEmpty.default, {
componentName: "Table"
});
}, [spinProps?.spinning, rawData, locale?.emptyText, renderEmpty]);
// ========================== Render ==========================
const TableComponent = virtual ? _VirtualTable.default : _RcTable.default;
// >>> Virtual Table props. We set height here since it will affect height collection
const virtualProps = {};
const listItemHeight = React.useMemo(() => {
const {
fontSize,
lineHeight,
lineWidth,
padding,
paddingXS,
paddingSM
} = token;
const fontHeight = Math.floor(fontSize * lineHeight);
switch (mergedSize) {
case 'medium':
return paddingSM * 2 + fontHeight + lineWidth;
case 'small':
return paddingXS * 2 + fontHeight + lineWidth;
default:
return padding * 2 + fontHeight + lineWidth;
}
}, [token, mergedSize]);
if (virtual) {
virtualProps.listItemHeight = listItemHeight;
}
return /*#__PURE__*/React.createElement("div", {
ref: rootRef,
className: wrappercls,
style: mergedStyle
}, /*#__PURE__*/React.createElement(_spin.default, {
spinning: false,
...spinProps
}, topPaginationNode, /*#__PURE__*/React.createElement(TableComponent, {
...virtualProps,
...tableProps,
scroll: mergedScroll,
classNames: mergedClassNames,
styles: mergedStyles,
ref: tblRef,
columns: mergedColumns,
direction: direction,
expandable: mergedExpandable,
prefixCls: prefixCls,
className: (0, _clsx.clsx)({
[`${prefixCls}-medium`]: mergedSize === 'medium',
[`${prefixCls}-small`]: mergedSize === 'small',
[`${prefixCls}-bordered`]: bordered,
[`${prefixCls}-empty`]: rawData.length === 0
}, cssVarCls, rootCls, hashId),
data: pageData,
rowKey: getRowKey,
rowClassName: internalRowClassName,
emptyText: mergedEmptyNode,
// Internal
internalHooks: _table.INTERNAL_HOOKS,
internalRefs: internalRef,
transformColumns: transformColumns,
getContainerWidth: getContainerWidth,
measureRowRender: measureRow => (/*#__PURE__*/React.createElement(_TableMeasureRowContext.default.Provider, {
value: true
}, /*#__PURE__*/React.createElement(_configProvider.default, {
getPopupContainer: node => node
}, measureRow)))
}), bottomPaginationNode));
};
var _default = exports.default = /*#__PURE__*/React.forwardRef(InternalTable);
@@ -0,0 +1,5 @@
/**
* Same as `rc-component/table` but we modify trigger children update logic instead.
*/
declare const RcVirtualTable: import("@rc-component/table/lib/VirtualTable").ForwardGenericVirtualTable;
export default RcVirtualTable;
+21
View File
@@ -0,0 +1,21 @@
"use strict";
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _table = require("@rc-component/table");
/**
* Same as `rc-component/table` but we modify trigger children update logic instead.
*/
const RcVirtualTable = (0, _table.genVirtualTable)((prev, next) => {
const {
_renderTimes: prevRenderTimes
} = prev;
const {
_renderTimes: nextRenderTimes
} = next;
return prevRenderTimes !== nextRenderTimes;
});
var _default = exports.default = RcVirtualTable;
+5
View File
@@ -0,0 +1,5 @@
/**
* Same as `rc-component/table` but we modify trigger children update logic instead.
*/
declare const RcTable: import("@rc-component/table/lib/Table").ForwardGenericTable;
export default RcTable;
+21
View File
@@ -0,0 +1,21 @@
"use strict";
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _table = require("@rc-component/table");
/**
* Same as `rc-component/table` but we modify trigger children update logic instead.
*/
const RcTable = (0, _table.genTable)((prev, next) => {
const {
_renderTimes: prevRenderTimes
} = prev;
const {
_renderTimes: nextRenderTimes
} = next;
return prevRenderTimes !== nextRenderTimes;
});
var _default = exports.default = RcTable;
+17
View File
@@ -0,0 +1,17 @@
import { EXPAND_COLUMN, Summary } from '@rc-component/table';
import Column from './Column';
import ColumnGroup from './ColumnGroup';
import { SELECTION_ALL, SELECTION_COLUMN, SELECTION_INVERT, SELECTION_NONE } from './hooks/useSelection';
import type { RefTable } from './interface';
declare const ForwardTable: RefTable & {
displayName?: string;
SELECTION_COLUMN: typeof SELECTION_COLUMN;
EXPAND_COLUMN: typeof EXPAND_COLUMN;
SELECTION_ALL: typeof SELECTION_ALL;
SELECTION_INVERT: typeof SELECTION_INVERT;
SELECTION_NONE: typeof SELECTION_NONE;
Column: typeof Column;
ColumnGroup: typeof ColumnGroup;
Summary: typeof Summary;
};
export default ForwardTable;
+37
View File
@@ -0,0 +1,37 @@
"use strict";
"use client";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _table = require("@rc-component/table");
var _Column = _interopRequireDefault(require("./Column"));
var _ColumnGroup = _interopRequireDefault(require("./ColumnGroup"));
var _useSelection = require("./hooks/useSelection");
var _InternalTable = _interopRequireDefault(require("./InternalTable"));
const Table = (props, ref) => {
const renderTimesRef = React.useRef(0);
renderTimesRef.current += 1;
return /*#__PURE__*/React.createElement(_InternalTable.default, {
...props,
ref: ref,
_renderTimes: renderTimesRef.current
});
};
const ForwardTable = /*#__PURE__*/React.forwardRef(Table);
ForwardTable.SELECTION_COLUMN = _useSelection.SELECTION_COLUMN;
ForwardTable.EXPAND_COLUMN = _table.EXPAND_COLUMN;
ForwardTable.SELECTION_ALL = _useSelection.SELECTION_ALL;
ForwardTable.SELECTION_INVERT = _useSelection.SELECTION_INVERT;
ForwardTable.SELECTION_NONE = _useSelection.SELECTION_NONE;
ForwardTable.Column = _Column.default;
ForwardTable.ColumnGroup = _ColumnGroup.default;
ForwardTable.Summary = _table.Summary;
if (process.env.NODE_ENV !== 'production') {
ForwardTable.displayName = 'Table';
}
var _default = exports.default = ForwardTable;
@@ -0,0 +1,3 @@
import React from 'react';
declare const TableMeasureRowContext: React.Context<boolean>;
export default TableMeasureRowContext;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireDefault(require("react"));
const TableMeasureRowContext = /*#__PURE__*/_react.default.createContext(false);
var _default = exports.default = TableMeasureRowContext;
@@ -0,0 +1 @@
export default function useContainerWidth(prefixCls: string): (ele: HTMLElement, width: number) => number;
+20
View File
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useContainerWidth;
function useContainerWidth(prefixCls) {
const getContainerWidth = (ele, width) => {
const container = ele.querySelector(`.${prefixCls}-container`);
let returnWidth = width;
if (container) {
const style = getComputedStyle(container);
const borderLeft = Number.parseInt(style.borderLeftWidth, 10);
const borderRight = Number.parseInt(style.borderRightWidth, 10);
returnWidth = width - borderLeft - borderRight;
}
return returnWidth;
};
return getContainerWidth;
}
@@ -0,0 +1,31 @@
import * as React from 'react';
import type { FieldDataNode } from '@rc-component/tree';
import type { FilterState } from '.';
import type { AnyObject } from '../../../_util/type';
import type { ColumnFilterItem, ColumnType, FilterSearchType, FilterValue, GetPopupContainer, Key, TableLocale } from '../../interface';
type FilterTreeDataNode = FieldDataNode<{
title: React.ReactNode;
key: string;
}>;
export declare function flattenKeys(filters?: ColumnFilterItem[]): FilterValue;
export type TreeColumnFilterItem = ColumnFilterItem & FilterTreeDataNode;
export interface FilterDropdownProps<RecordType = AnyObject> {
tablePrefixCls: string;
prefixCls: string;
dropdownPrefixCls: string;
column: ColumnType<RecordType>;
filterState?: FilterState<RecordType>;
filterOnClose: boolean;
filterMultiple: boolean;
filterMode?: 'menu' | 'tree';
filterSearch?: FilterSearchType<ColumnFilterItem | TreeColumnFilterItem>;
columnKey: Key;
children: React.ReactNode;
triggerFilter: (filterState: FilterState<RecordType>) => void;
locale: TableLocale;
getPopupContainer?: GetPopupContainer;
filterResetToDefaultFilteredValue?: boolean;
rootClassName?: string;
}
declare const FilterDropdown: <RecordType extends AnyObject = AnyObject>(props: FilterDropdownProps<RecordType>) => React.JSX.Element;
export default FilterDropdown;
@@ -0,0 +1,485 @@
"use strict";
"use client";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.flattenKeys = flattenKeys;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var React = _interopRequireWildcard(require("react"));
var _FilterFilled = _interopRequireDefault(require("@ant-design/icons/FilterFilled"));
var _isEqual = _interopRequireDefault(require("@rc-component/util/lib/isEqual"));
var _clsx = require("clsx");
var _extendsObject = _interopRequireDefault(require("../../../_util/extendsObject"));
var _hooks = require("../../../_util/hooks");
var _is = require("../../../_util/is");
var _warning = require("../../../_util/warning");
var _Button = _interopRequireDefault(require("../../../button/Button"));
var _checkbox = _interopRequireDefault(require("../../../checkbox"));
var _context = require("../../../config-provider/context");
var _dropdown = _interopRequireDefault(require("../../../dropdown"));
var _empty = _interopRequireDefault(require("../../../empty"));
var _menu = _interopRequireDefault(require("../../../menu"));
var _OverrideContext = require("../../../menu/OverrideContext");
var _radio = _interopRequireDefault(require("../../../radio"));
var _tree = _interopRequireDefault(require("../../../tree"));
var _TableMeasureRowContext = _interopRequireDefault(require("../../TableMeasureRowContext"));
var _FilterSearch = _interopRequireDefault(require("./FilterSearch"));
var _FilterWrapper = _interopRequireDefault(require("./FilterWrapper"));
function flattenKeys(filters) {
let keys = [];
(filters || []).forEach(({
value,
children
}) => {
keys.push(value);
if (children) {
keys = [].concat((0, _toConsumableArray2.default)(keys), (0, _toConsumableArray2.default)(flattenKeys(children)));
}
});
return keys;
}
function hasSubMenu(filters) {
return filters.some(({
children
}) => children);
}
const searchValueMatched = (normalizedSearchValue, text) => {
if (typeof text === 'string' || (0, _is.isNumber)(text)) {
return text.toString().toLowerCase().includes(normalizedSearchValue);
}
return false;
};
const renderFilterItems = options => {
const {
filters,
prefixCls,
filteredKeys,
filterMultiple,
searchValue,
normalizedSearchValue,
filterSearch
} = options;
return filters.map((filter, index) => {
const key = String(filter.value);
if (filter.children) {
return {
key: key || index,
label: filter.text,
popupClassName: `${prefixCls}-dropdown-submenu`,
children: renderFilterItems({
filters: filter.children,
prefixCls,
filteredKeys,
filterMultiple,
searchValue,
normalizedSearchValue,
filterSearch
})
};
}
const Component = filterMultiple ? _checkbox.default : _radio.default;
const item = {
key: filter.value !== undefined ? key : index,
label: (/*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Component, {
checked: filteredKeys.includes(key)
}), /*#__PURE__*/React.createElement("span", null, filter.text)))
};
if (normalizedSearchValue) {
if (typeof filterSearch === 'function') {
return filterSearch(normalizedSearchValue, filter) ? item : null;
}
return searchValueMatched(normalizedSearchValue, filter.text) ? item : null;
}
return item;
});
};
function wrapStringListType(keys) {
return keys || [];
}
const FilterDropdown = props => {
const {
tablePrefixCls,
prefixCls,
column,
dropdownPrefixCls,
columnKey,
filterOnClose,
filterMultiple,
filterMode = 'menu',
filterSearch = false,
filterState,
triggerFilter,
locale,
children,
getPopupContainer,
rootClassName
} = props;
const {
filterResetToDefaultFilteredValue,
defaultFilteredValue,
filterDropdownProps = {},
// Deprecated
filterDropdownOpen,
onFilterDropdownOpenChange
} = column;
const [visible, setVisible] = React.useState(false);
const inMeasureRow = React.useContext(_TableMeasureRowContext.default);
const filtered = !!(filterState && (filterState.filteredKeys?.length || filterState.forceFiltered));
const triggerVisible = newVisible => {
setVisible(newVisible);
filterDropdownProps.onOpenChange?.(newVisible);
// deprecated
onFilterDropdownOpenChange?.(newVisible);
};
// =================Warning===================
if (process.env.NODE_ENV !== 'production') {
const warning = (0, _warning.devUseWarning)('Table');
const deprecatedList = [['filterDropdownOpen', 'filterDropdownProps.open'], ['onFilterDropdownOpenChange', 'filterDropdownProps.onOpenChange']];
deprecatedList.forEach(([deprecatedName, newName]) => {
warning.deprecated(!(deprecatedName in column), deprecatedName, newName);
});
warning.deprecated(!('filterCheckall' in locale), 'filterCheckall', 'locale.filterCheckAll');
}
const mergedVisible = filterDropdownProps.open ?? filterDropdownOpen ??
// deprecated
visible; // inner state
// ===================== Select Keys =====================
const propFilteredKeys = filterState?.filteredKeys;
const [getFilteredKeysSync, setFilteredKeysSync] = (0, _hooks.useSyncState)(wrapStringListType(propFilteredKeys));
const onSelectKeys = ({
selectedKeys
}) => {
setFilteredKeysSync(selectedKeys);
};
const onCheck = (keys, {
node,
checked
}) => {
if (!filterMultiple) {
onSelectKeys({
selectedKeys: checked && node.key ? [node.key] : []
});
} else {
onSelectKeys({
selectedKeys: keys
});
}
};
React.useEffect(() => {
if (!visible) {
return;
}
onSelectKeys({
selectedKeys: wrapStringListType(propFilteredKeys)
});
}, [propFilteredKeys]);
// ====================== Open Keys ======================
const [openKeys, setOpenKeys] = React.useState([]);
const onOpenChange = keys => {
setOpenKeys(keys);
};
// search in tree mode column filter
const [searchValue, setSearchValue] = React.useState('');
const normalizedSearchValue = React.useMemo(() => searchValue.trim().toLowerCase(), [searchValue]);
const onSearch = e => {
const {
value
} = e.target;
setSearchValue(value);
};
// clear search value after close filter dropdown
React.useEffect(() => {
if (!visible) {
setSearchValue('');
}
}, [visible]);
// ======================= Submit ========================
const internalTriggerFilter = keys => {
const mergedKeys = keys?.length ? keys : null;
if (mergedKeys === null && (!filterState || !filterState.filteredKeys)) {
return null;
}
if ((0, _isEqual.default)(mergedKeys, filterState?.filteredKeys, true)) {
return null;
}
triggerFilter({
column,
key: columnKey,
filteredKeys: mergedKeys
});
};
const onConfirm = () => {
triggerVisible(false);
internalTriggerFilter(getFilteredKeysSync());
};
const onReset = ({
confirm,
closeDropdown
} = {
confirm: false,
closeDropdown: false
}) => {
if (confirm) {
internalTriggerFilter([]);
}
if (closeDropdown) {
triggerVisible(false);
}
setSearchValue('');
if (filterResetToDefaultFilteredValue) {
setFilteredKeysSync((defaultFilteredValue || []).map(String));
} else {
setFilteredKeysSync([]);
}
};
const doFilter = ({
closeDropdown
} = {
closeDropdown: true
}) => {
if (closeDropdown) {
triggerVisible(false);
}
internalTriggerFilter(getFilteredKeysSync());
};
const onVisibleChange = (newVisible, info) => {
if (info.source === 'trigger') {
if (newVisible && propFilteredKeys !== undefined) {
// Sync filteredKeys on appear in controlled mode (propFilteredKeys !== undefined)
setFilteredKeysSync(wrapStringListType(propFilteredKeys));
}
triggerVisible(newVisible);
if (!newVisible && !column.filterDropdown && filterOnClose) {
onConfirm();
}
}
};
// ======================== Style ========================
const dropdownMenuClass = (0, _clsx.clsx)({
[`${dropdownPrefixCls}-menu-without-submenu`]: !hasSubMenu(column.filters || [])
});
const onCheckAll = e => {
if (e.target.checked) {
const allFilterKeys = flattenKeys(column?.filters).map(String);
setFilteredKeysSync(allFilterKeys);
} else {
setFilteredKeysSync([]);
}
};
const getTreeData = ({
filters
}) => (filters || []).map((filter, index) => {
const key = String(filter.value);
const item = {
title: filter.text,
key: filter.value !== undefined ? key : String(index)
};
if (filter.children) {
item.children = getTreeData({
filters: filter.children
});
}
return item;
});
const getFilterData = node => ({
...node,
text: node.title,
value: node.key,
children: node.children?.map(getFilterData) || []
});
let dropdownContent;
const {
direction,
renderEmpty
} = React.useContext(_context.ConfigContext);
if (typeof column.filterDropdown === 'function') {
dropdownContent = column.filterDropdown({
prefixCls: `${dropdownPrefixCls}-custom`,
setSelectedKeys: selectedKeys => onSelectKeys({
selectedKeys: selectedKeys
}),
selectedKeys: getFilteredKeysSync(),
confirm: doFilter,
clearFilters: onReset,
filters: column.filters,
visible: mergedVisible,
close: () => {
triggerVisible(false);
}
});
} else if (column.filterDropdown) {
dropdownContent = column.filterDropdown;
} else {
const selectedKeys = getFilteredKeysSync() || [];
const getFilterComponent = () => {
const empty = renderEmpty?.('Table.filter') ?? (/*#__PURE__*/React.createElement(_empty.default, {
image: _empty.default.PRESENTED_IMAGE_SIMPLE,
description: locale.filterEmptyText,
styles: {
image: {
height: 24
}
},
style: {
margin: 0,
padding: '16px 0'
}
}));
if ((column.filters || []).length === 0) {
return empty;
}
if (filterMode === 'tree') {
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_FilterSearch.default, {
filterSearch: filterSearch,
value: searchValue,
onChange: onSearch,
tablePrefixCls: tablePrefixCls,
locale: locale
}), /*#__PURE__*/React.createElement("div", {
className: `${tablePrefixCls}-filter-dropdown-tree`
}, filterMultiple ? (/*#__PURE__*/React.createElement(_checkbox.default, {
checked: selectedKeys.length === flattenKeys(column.filters).length,
indeterminate: selectedKeys.length > 0 && selectedKeys.length < flattenKeys(column.filters).length,
className: `${tablePrefixCls}-filter-dropdown-checkall`,
onChange: onCheckAll
}, locale?.filterCheckall ?? locale?.filterCheckAll)) : null, /*#__PURE__*/React.createElement(_tree.default, {
checkable: true,
selectable: false,
blockNode: true,
multiple: filterMultiple,
checkStrictly: !filterMultiple,
className: `${dropdownPrefixCls}-menu`,
onCheck: onCheck,
checkedKeys: selectedKeys,
selectedKeys: selectedKeys,
showIcon: false,
treeData: getTreeData({
filters: column.filters
}),
autoExpandParent: true,
defaultExpandAll: true,
filterTreeNode: normalizedSearchValue ? node => {
if (typeof filterSearch === 'function') {
return filterSearch(searchValue, getFilterData(node));
}
return searchValueMatched(normalizedSearchValue, node.title);
} : undefined
})));
}
const items = renderFilterItems({
filters: column.filters || [],
filterSearch,
prefixCls,
filteredKeys: getFilteredKeysSync(),
filterMultiple,
searchValue,
normalizedSearchValue
});
const isEmpty = items.every(item => item === null);
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_FilterSearch.default, {
filterSearch: filterSearch,
value: searchValue,
onChange: onSearch,
tablePrefixCls: tablePrefixCls,
locale: locale
}), isEmpty ? empty : (/*#__PURE__*/React.createElement(_menu.default, {
selectable: true,
multiple: filterMultiple,
prefixCls: `${dropdownPrefixCls}-menu`,
className: dropdownMenuClass,
onSelect: onSelectKeys,
onDeselect: onSelectKeys,
selectedKeys: selectedKeys,
getPopupContainer: getPopupContainer,
openKeys: openKeys,
onOpenChange: onOpenChange,
items: items
})));
};
const getResetDisabled = () => {
if (filterResetToDefaultFilteredValue) {
return (0, _isEqual.default)((defaultFilteredValue || []).map(String), selectedKeys, true);
}
return selectedKeys.length === 0;
};
dropdownContent = /*#__PURE__*/React.createElement(React.Fragment, null, getFilterComponent(), /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-dropdown-btns`
}, /*#__PURE__*/React.createElement(_Button.default, {
type: "link",
size: "small",
disabled: getResetDisabled(),
onClick: () => onReset()
}, locale.filterReset), /*#__PURE__*/React.createElement(_Button.default, {
type: "primary",
size: "small",
onClick: onConfirm
}, locale.filterConfirm)));
}
// We should not block customize Menu with additional props
if (column.filterDropdown) {
dropdownContent = /*#__PURE__*/React.createElement(_OverrideContext.OverrideProvider, {
selectable: undefined
}, dropdownContent);
}
dropdownContent = /*#__PURE__*/React.createElement(_FilterWrapper.default, {
className: `${prefixCls}-dropdown`
}, dropdownContent);
const getDropdownTrigger = () => {
let filterIcon;
if (typeof column.filterIcon === 'function') {
filterIcon = column.filterIcon(filtered);
} else if (column.filterIcon) {
filterIcon = column.filterIcon;
} else {
filterIcon = /*#__PURE__*/React.createElement(_FilterFilled.default, null);
}
return /*#__PURE__*/React.createElement("span", {
role: "button",
tabIndex: -1,
className: (0, _clsx.clsx)(`${prefixCls}-trigger`, {
active: filtered
}),
onClick: e => {
e.stopPropagation();
}
}, filterIcon);
};
const triggerNode = getDropdownTrigger();
// MeasureRow:仅渲染静态 trigger,不渲染 Dropdown 实例
if (inMeasureRow) {
return /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-column`
}, /*#__PURE__*/React.createElement("span", {
className: `${tablePrefixCls}-column-title`
}, children), triggerNode);
}
const mergedDropdownProps = (0, _extendsObject.default)({
trigger: ['click'],
placement: direction === 'rtl' ? 'bottomLeft' : 'bottomRight',
children: triggerNode,
getPopupContainer
}, {
...filterDropdownProps,
rootClassName: (0, _clsx.clsx)(rootClassName, filterDropdownProps.rootClassName),
open: mergedVisible,
onOpenChange: onVisibleChange,
popupRender: () => {
if (typeof filterDropdownProps?.dropdownRender === 'function') {
return filterDropdownProps.dropdownRender(dropdownContent);
}
return dropdownContent;
}
});
return /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-column`
}, /*#__PURE__*/React.createElement("span", {
className: `${tablePrefixCls}-column-title`
}, children), /*#__PURE__*/React.createElement(_dropdown.default, {
...mergedDropdownProps
}));
};
var _default = exports.default = FilterDropdown;
@@ -0,0 +1,12 @@
import * as React from 'react';
import type { AnyObject } from '../../../_util/type';
import type { FilterSearchType, TableLocale } from '../../interface';
interface FilterSearchProps<RecordType = AnyObject> {
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
filterSearch: FilterSearchType<RecordType>;
tablePrefixCls: string;
locale: TableLocale;
}
declare const FilterSearch: <RecordType extends AnyObject = AnyObject>(props: FilterSearchProps<RecordType>) => React.JSX.Element | null;
export default FilterSearch;
@@ -0,0 +1,36 @@
"use strict";
"use client";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _SearchOutlined = _interopRequireDefault(require("@ant-design/icons/SearchOutlined"));
var _Input = _interopRequireDefault(require("../../../input/Input"));
const FilterSearch = props => {
const {
value,
filterSearch,
tablePrefixCls,
locale,
onChange
} = props;
if (!filterSearch) {
return null;
}
return /*#__PURE__*/React.createElement("div", {
className: `${tablePrefixCls}-filter-dropdown-search`
}, /*#__PURE__*/React.createElement(_Input.default, {
prefix: /*#__PURE__*/React.createElement(_SearchOutlined.default, null),
placeholder: locale.filterSearchPlaceholder,
onChange: onChange,
value: value,
// for skip min-width of input
htmlSize: 1,
className: `${tablePrefixCls}-filter-dropdown-search-input`
}));
};
var _default = exports.default = FilterSearch;
@@ -0,0 +1,8 @@
import * as React from 'react';
export interface FilterDropdownMenuWrapperProps {
className?: string;
}
declare const FilterDropdownMenuWrapper: React.ForwardRefExoticComponent<FilterDropdownMenuWrapperProps & {
children?: React.ReactNode | undefined;
} & React.RefAttributes<HTMLDivElement>>;
export default FilterDropdownMenuWrapper;
@@ -0,0 +1,29 @@
"use strict";
"use client";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
const onKeyDown = event => {
const {
keyCode
} = event;
if (keyCode === _KeyCode.default.ENTER) {
event.stopPropagation();
}
};
const FilterDropdownMenuWrapper = /*#__PURE__*/React.forwardRef((props, ref) => (/*#__PURE__*/React.createElement("div", {
className: props.className,
onClick: e => e.stopPropagation(),
onKeyDown: onKeyDown,
ref: ref
}, props.children)));
if (process.env.NODE_ENV !== 'production') {
FilterDropdownMenuWrapper.displayName = 'FilterDropdownMenuWrapper';
}
var _default = exports.default = FilterDropdownMenuWrapper;
+22
View File
@@ -0,0 +1,22 @@
import type { AnyObject } from '../../../_util/type';
import type { ColumnsType, ColumnType, FilterKey, FilterValue, GetPopupContainer, Key, TableLocale, TransformColumns } from '../../interface';
import { flattenKeys } from './FilterDropdown';
export interface FilterState<RecordType = AnyObject> {
column: ColumnType<RecordType>;
key: Key;
filteredKeys?: FilterKey;
forceFiltered?: boolean;
}
export declare const getFilterData: <RecordType extends AnyObject = AnyObject>(data: RecordType[], filterStates: FilterState<RecordType>[], childrenColumnName: string) => RecordType[];
export interface FilterConfig<RecordType = AnyObject> {
prefixCls: string;
dropdownPrefixCls: string;
mergedColumns: ColumnsType<RecordType>;
locale: TableLocale;
onFilterChange: (filters: Record<string, FilterValue | null>, filterStates: FilterState<RecordType>[]) => void;
getPopupContainer?: GetPopupContainer;
rootClassName?: string;
}
declare const useFilter: <RecordType extends AnyObject = AnyObject>(props: FilterConfig<RecordType>) => [TransformColumns<RecordType>, FilterState<RecordType>[], Record<string, FilterValue | null>];
export { flattenKeys };
export default useFilter;
+234
View File
@@ -0,0 +1,234 @@
"use strict";
"use client";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "flattenKeys", {
enumerable: true,
get: function () {
return _FilterDropdown.flattenKeys;
}
});
exports.getFilterData = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var React = _interopRequireWildcard(require("react"));
var _warning = require("../../../_util/warning");
var _util = require("../../util");
var _FilterDropdown = _interopRequireWildcard(require("./FilterDropdown"));
const collectFilterStates = (columns, init, pos) => {
let filterStates = [];
(columns || []).forEach((column, index) => {
const columnPos = (0, _util.getColumnPos)(index, pos);
const filterDropdownIsDefined = column.filterDropdown !== undefined;
if (column.filters || filterDropdownIsDefined || 'onFilter' in column) {
if ('filteredValue' in column) {
// Controlled
let filteredValues = column.filteredValue;
if (!filterDropdownIsDefined) {
filteredValues = filteredValues?.map(String) ?? filteredValues;
}
filterStates.push({
column,
key: (0, _util.getColumnKey)(column, columnPos),
filteredKeys: filteredValues,
forceFiltered: column.filtered
});
} else {
// Uncontrolled
filterStates.push({
column,
key: (0, _util.getColumnKey)(column, columnPos),
filteredKeys: init && column.defaultFilteredValue ? column.defaultFilteredValue : undefined,
forceFiltered: column.filtered
});
}
}
if ('children' in column) {
filterStates = [].concat((0, _toConsumableArray2.default)(filterStates), (0, _toConsumableArray2.default)(collectFilterStates(column.children, init, columnPos)));
}
});
return filterStates;
};
function injectFilter(prefixCls, dropdownPrefixCls, columns, filterStates, locale, triggerFilter, getPopupContainer, pos, rootClassName) {
return columns.map((column, index) => {
const columnPos = (0, _util.getColumnPos)(index, pos);
const {
filterOnClose = true,
filterMultiple = true,
filterMode,
filterSearch
} = column;
let newColumn = column;
if (newColumn.filters || newColumn.filterDropdown) {
const columnKey = (0, _util.getColumnKey)(newColumn, columnPos);
const filterState = filterStates.find(({
key
}) => columnKey === key);
newColumn = {
...newColumn,
title: renderProps => (/*#__PURE__*/React.createElement(_FilterDropdown.default, {
tablePrefixCls: prefixCls,
prefixCls: `${prefixCls}-filter`,
dropdownPrefixCls: dropdownPrefixCls,
column: newColumn,
columnKey: columnKey,
filterState: filterState,
filterOnClose: filterOnClose,
filterMultiple: filterMultiple,
filterMode: filterMode,
filterSearch: filterSearch,
triggerFilter: triggerFilter,
locale: locale,
getPopupContainer: getPopupContainer,
rootClassName: rootClassName
}, (0, _util.renderColumnTitle)(column.title, renderProps)))
};
}
if ('children' in newColumn) {
newColumn = {
...newColumn,
children: injectFilter(prefixCls, dropdownPrefixCls, newColumn.children, filterStates, locale, triggerFilter, getPopupContainer, columnPos, rootClassName)
};
}
return newColumn;
});
}
const generateFilterInfo = filterStates => {
const currentFilters = {};
filterStates.forEach(({
key,
filteredKeys,
column
}) => {
const keyAsString = key;
const {
filters,
filterDropdown
} = column;
if (filterDropdown) {
currentFilters[keyAsString] = filteredKeys || null;
} else if (Array.isArray(filteredKeys)) {
const keys = (0, _FilterDropdown.flattenKeys)(filters);
currentFilters[keyAsString] = keys.filter(originKey => filteredKeys.includes(String(originKey)));
} else {
currentFilters[keyAsString] = null;
}
});
return currentFilters;
};
const getFilterData = (data, filterStates, childrenColumnName) => {
const filterDatas = filterStates.reduce((currentData, filterState) => {
const {
column: {
onFilter,
filters
},
filteredKeys
} = filterState;
if (onFilter && filteredKeys && filteredKeys.length) {
// Preprocess the keys corresponding to the filter tree,
// use Map to improve lookup performance to O(1).
const flatKeys = (0, _FilterDropdown.flattenKeys)(filters);
const keyMap = new Map();
flatKeys.forEach(k => {
const strKey = String(k);
if (!keyMap.has(strKey)) {
keyMap.set(strKey, k);
}
});
const realKeys = filteredKeys.map(key => {
const strKey = String(key);
return keyMap.get(strKey) ?? key;
});
const internalFilter = subset => subset.reduce((acc, record) => {
const clonedRecord = {
...record
};
if (clonedRecord[childrenColumnName]) {
clonedRecord[childrenColumnName] = getFilterData(clonedRecord[childrenColumnName], filterStates, childrenColumnName);
}
if (realKeys.some(realKey => onFilter(realKey, clonedRecord))) {
acc.push(clonedRecord);
}
return acc;
}, []);
return internalFilter(currentData);
}
return currentData;
}, data);
return filterDatas;
};
exports.getFilterData = getFilterData;
const getMergedColumns = rawMergedColumns => rawMergedColumns.flatMap(column => {
if ('children' in column) {
return [column].concat((0, _toConsumableArray2.default)(getMergedColumns(column.children || [])));
}
return [column];
});
const useFilter = props => {
const {
prefixCls,
dropdownPrefixCls,
mergedColumns: rawMergedColumns,
onFilterChange,
getPopupContainer,
locale: tableLocale,
rootClassName
} = props;
const warning = (0, _warning.devUseWarning)('Table');
const mergedColumns = React.useMemo(() => getMergedColumns(rawMergedColumns || []), [rawMergedColumns]);
const [filterStates, setFilterStates] = React.useState(() => collectFilterStates(mergedColumns, true));
const mergedFilterStates = React.useMemo(() => {
const collectedStates = collectFilterStates(mergedColumns, false);
if (collectedStates.length === 0) {
return collectedStates;
}
let filteredKeysIsAllNotControlled = true;
let filteredKeysIsAllControlled = true;
collectedStates.forEach(({
filteredKeys
}) => {
if (filteredKeys !== undefined) {
filteredKeysIsAllNotControlled = false;
} else {
filteredKeysIsAllControlled = false;
}
});
// Return if not controlled
if (filteredKeysIsAllNotControlled) {
// Filter column may have been removed
const keyList = (mergedColumns || []).map((column, index) => (0, _util.getColumnKey)(column, (0, _util.getColumnPos)(index)));
return filterStates.filter(({
key
}) => keyList.includes(key)).map(item => {
const col = mergedColumns[keyList.indexOf(item.key)];
return {
...item,
column: {
...item.column,
...col
},
forceFiltered: col.filtered
};
});
}
process.env.NODE_ENV !== "production" ? warning(filteredKeysIsAllControlled, 'usage', 'Columns should all contain `filteredValue` or not contain `filteredValue`.') : void 0;
return collectedStates;
}, [mergedColumns, filterStates]);
const filters = React.useMemo(() => generateFilterInfo(mergedFilterStates), [mergedFilterStates]);
const triggerFilter = filterState => {
const newFilterStates = mergedFilterStates.filter(({
key
}) => key !== filterState.key);
newFilterStates.push(filterState);
setFilterStates(newFilterStates);
onFilterChange(generateFilterInfo(newFilterStates), newFilterStates);
};
const transformColumns = innerColumns => injectFilter(prefixCls, dropdownPrefixCls, innerColumns, mergedFilterStates, tableLocale, triggerFilter, getPopupContainer, undefined, rootClassName);
return [transformColumns, mergedFilterStates, filters];
};
var _default = exports.default = useFilter;
+4
View File
@@ -0,0 +1,4 @@
import type { AnyObject } from '../../_util/type';
import type { GetRowKey, Key } from '../interface';
declare const useLazyKVMap: <RecordType extends AnyObject = AnyObject>(data: readonly RecordType[], childrenColumnName: string, getRowKey: GetRowKey<RecordType>) => readonly [(key: Key) => RecordType];
export default useLazyKVMap;
+36
View File
@@ -0,0 +1,36 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _is = require("../../_util/is");
const useLazyKVMap = (data, childrenColumnName, getRowKey) => {
const mapCacheRef = React.useRef({});
function getRecordByKey(key) {
if (!mapCacheRef.current || mapCacheRef.current.data !== data || mapCacheRef.current.childrenColumnName !== childrenColumnName || mapCacheRef.current.getRowKey !== getRowKey) {
const kvMap = new Map();
function dig(records) {
records.forEach((record, index) => {
const rowKey = getRowKey(record, index);
kvMap.set(rowKey, record);
if ((0, _is.isPlainObject)(record) && childrenColumnName in record) {
dig(record[childrenColumnName] || []);
}
});
}
dig(data);
mapCacheRef.current = {
data,
childrenColumnName,
kvMap,
getRowKey
};
}
return mapCacheRef.current.kvMap?.get(key);
}
return [getRecordByKey];
};
var _default = exports.default = useLazyKVMap;
+5
View File
@@ -0,0 +1,5 @@
import type { TablePaginationConfig } from '../interface';
export declare const DEFAULT_PAGE_SIZE = 10;
export declare function getPaginationParam(mergedPagination: TablePaginationConfig, pagination?: TablePaginationConfig | boolean): any;
declare function usePagination(total: number, onChange: (current: number, pageSize: number) => void, pagination?: TablePaginationConfig | false): readonly [TablePaginationConfig, (current?: number, pageSize?: number) => void];
export default usePagination;
+67
View File
@@ -0,0 +1,67 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.DEFAULT_PAGE_SIZE = void 0;
exports.getPaginationParam = getPaginationParam;
var _react = require("react");
var _extendsObject = _interopRequireDefault(require("../../_util/extendsObject"));
var _is = require("../../_util/is");
const DEFAULT_PAGE_SIZE = exports.DEFAULT_PAGE_SIZE = 10;
function getPaginationParam(mergedPagination, pagination) {
const param = {
current: mergedPagination.current,
pageSize: mergedPagination.pageSize
};
const paginationObj = (0, _is.isPlainObject)(pagination) ? pagination : {};
Object.keys(paginationObj).forEach(pageProp => {
const value = mergedPagination[pageProp];
if (typeof value !== 'function') {
param[pageProp] = value;
}
});
return param;
}
function usePagination(total, onChange, pagination) {
const {
total: paginationTotal = 0,
...paginationObj
} = (0, _is.isPlainObject)(pagination) ? pagination : {};
const [innerPagination, setInnerPagination] = (0, _react.useState)(() => ({
current: 'defaultCurrent' in paginationObj ? paginationObj.defaultCurrent : 1,
pageSize: 'defaultPageSize' in paginationObj ? paginationObj.defaultPageSize : DEFAULT_PAGE_SIZE
}));
// ============ Basic Pagination Config ============
const mergedPagination = (0, _extendsObject.default)(innerPagination, paginationObj, {
total: paginationTotal > 0 ? paginationTotal : total
});
// Reset `current` if data length or pageSize changed
const maxPage = Math.ceil((paginationTotal || total) / mergedPagination.pageSize);
if (mergedPagination.current > maxPage) {
// Prevent a maximum page count of 0
mergedPagination.current = maxPage || 1;
}
const refreshPagination = (current, pageSize) => {
setInnerPagination({
current: current ?? 1,
pageSize: pageSize || mergedPagination.pageSize
});
};
const onInternalChange = (current, pageSize) => {
if (pagination) {
pagination.onChange?.(current, pageSize);
}
refreshPagination(current, pageSize);
onChange(current, pageSize || mergedPagination?.pageSize);
};
if (pagination === false) {
return [{}, () => {}];
}
return [{
...mergedPagination,
onChange: onInternalChange
}, refreshPagination];
}
var _default = exports.default = usePagination;
+20
View File
@@ -0,0 +1,20 @@
import type { AnyObject } from '../../_util/type';
import type { ExpandType, GetPopupContainer, GetRowKey, Key, SelectionItem, TableLocale, TableRowSelection, TransformColumns } from '../interface';
export declare const SELECTION_COLUMN: {};
export declare const SELECTION_ALL: "SELECT_ALL";
export declare const SELECTION_INVERT: "SELECT_INVERT";
export declare const SELECTION_NONE: "SELECT_NONE";
interface UseSelectionConfig<RecordType = AnyObject> {
prefixCls: string;
pageData: RecordType[];
data: RecordType[];
getRowKey: GetRowKey<RecordType>;
getRecordByKey: (key: Key) => RecordType;
expandType: ExpandType;
childrenColumnName: string;
locale: TableLocale;
getPopupContainer?: GetPopupContainer;
}
export type INTERNAL_SELECTION_ITEM = SelectionItem | typeof SELECTION_ALL | typeof SELECTION_INVERT | typeof SELECTION_NONE;
declare const useSelection: <RecordType extends AnyObject = AnyObject>(config: UseSelectionConfig<RecordType>, rowSelection?: TableRowSelection<RecordType>) => readonly [TransformColumns<RecordType>, Set<Key>];
export default useSelection;
+536
View File
@@ -0,0 +1,536 @@
"use strict";
"use client";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.SELECTION_NONE = exports.SELECTION_INVERT = exports.SELECTION_COLUMN = exports.SELECTION_ALL = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _react = _interopRequireWildcard(require("react"));
var React = _react;
var _DownOutlined = _interopRequireDefault(require("@ant-design/icons/DownOutlined"));
var _table = require("@rc-component/table");
var _util = require("@rc-component/tree/lib/util");
var _conductUtil = require("@rc-component/tree/lib/utils/conductUtil");
var _treeUtil = require("@rc-component/tree/lib/utils/treeUtil");
var _util2 = require("@rc-component/util");
var _clsx = require("clsx");
var _hooks = require("../../_util/hooks");
var _is = require("../../_util/is");
var _warning = require("../../_util/warning");
var _checkbox = _interopRequireDefault(require("../../checkbox"));
var _dropdown = _interopRequireDefault(require("../../dropdown"));
var _radio = _interopRequireDefault(require("../../radio"));
// TODO: warning if use ajax!!!
const SELECTION_COLUMN = exports.SELECTION_COLUMN = {};
const SELECTION_ALL = exports.SELECTION_ALL = 'SELECT_ALL';
const SELECTION_INVERT = exports.SELECTION_INVERT = 'SELECT_INVERT';
const SELECTION_NONE = exports.SELECTION_NONE = 'SELECT_NONE';
const EMPTY_LIST = [];
const flattenData = (childrenColumnName, data, list = []) => {
(data || []).forEach(record => {
list.push(record);
if ((0, _is.isPlainObject)(record) && childrenColumnName in record) {
flattenData(childrenColumnName, record[childrenColumnName], list);
}
});
return list;
};
const useSelection = (config, rowSelection) => {
const {
preserveSelectedRowKeys,
selectedRowKeys,
defaultSelectedRowKeys,
getCheckboxProps,
getTitleCheckboxProps,
onChange: onSelectionChange,
onSelect,
onSelectAll,
onSelectInvert,
onSelectNone,
onSelectMultiple,
columnWidth: selectionColWidth,
type: selectionType,
selections,
fixed,
renderCell: customizeRenderCell,
hideSelectAll,
checkStrictly = true
} = rowSelection || {};
const {
prefixCls,
data,
pageData,
getRecordByKey,
getRowKey,
expandType,
childrenColumnName,
locale: tableLocale,
getPopupContainer
} = config;
const warning = (0, _warning.devUseWarning)('Table');
// ========================= MultipleSelect =========================
const [multipleSelect, updatePrevSelectedIndex] = (0, _hooks.useMultipleSelect)(item => item);
// ========================= Keys =========================
const [mergedSelectedKeys, setMergedSelectedKeys] = (0, _util2.useControlledState)(defaultSelectedRowKeys || EMPTY_LIST, selectedRowKeys);
const mergedSelectedKeyList = mergedSelectedKeys ?? EMPTY_LIST;
// ======================== Caches ========================
const preserveRecordsRef = React.useRef(new Map());
const updatePreserveRecordsCache = (0, _react.useCallback)(keys => {
if (preserveSelectedRowKeys) {
const newCache = new Map();
// Keep key if mark as preserveSelectedRowKeys
keys.forEach(key => {
let record = getRecordByKey(key);
if (!record && preserveRecordsRef.current.has(key)) {
record = preserveRecordsRef.current.get(key);
}
newCache.set(key, record);
});
// Refresh to new cache
preserveRecordsRef.current = newCache;
}
}, [getRecordByKey, preserveSelectedRowKeys]);
// Update cache with selectedKeys
React.useEffect(() => {
updatePreserveRecordsCache(mergedSelectedKeyList);
}, [mergedSelectedKeyList, updatePreserveRecordsCache]);
// Get flatten data
const flattedData = (0, _react.useMemo)(() => flattenData(childrenColumnName, pageData), [childrenColumnName, pageData]);
const {
keyEntities
} = (0, _react.useMemo)(() => {
if (checkStrictly) {
return {
keyEntities: null
};
}
let convertData = data;
if (preserveSelectedRowKeys) {
// use flattedData keys
const keysSet = new Set(flattedData.map(getRowKey));
// remove preserveRecords that duplicate data
const preserveRecords = Array.from(preserveRecordsRef.current).reduce((total, [key, value]) => keysSet.has(key) ? total : total.concat(value), []);
convertData = [].concat((0, _toConsumableArray2.default)(convertData), (0, _toConsumableArray2.default)(preserveRecords));
}
return (0, _treeUtil.convertDataToEntities)(convertData, {
externalGetKey: getRowKey,
childrenPropName: childrenColumnName
});
}, [data, getRowKey, checkStrictly, childrenColumnName, preserveSelectedRowKeys, flattedData]);
// Get all checkbox props
const checkboxPropsMap = (0, _react.useMemo)(() => {
const map = new Map();
flattedData.forEach((record, index) => {
const key = getRowKey(record, index);
const checkboxProps = (getCheckboxProps ? getCheckboxProps(record) : null) || {};
map.set(key, checkboxProps);
process.env.NODE_ENV !== "production" ? warning(!('checked' in checkboxProps || 'defaultChecked' in checkboxProps), 'usage', 'Do not set `checked` or `defaultChecked` in `getCheckboxProps`. Please use `selectedRowKeys` instead.') : void 0;
});
return map;
}, [flattedData, getRowKey, getCheckboxProps]);
const isCheckboxDisabled = (0, _react.useCallback)(r => {
const rowKey = getRowKey(r);
let checkboxProps;
if (checkboxPropsMap.has(rowKey)) {
checkboxProps = checkboxPropsMap.get(getRowKey(r));
} else {
checkboxProps = getCheckboxProps ? getCheckboxProps(r) : undefined;
}
return !!checkboxProps?.disabled;
}, [checkboxPropsMap, getRowKey]);
const [derivedSelectedKeys, derivedHalfSelectedKeys] = (0, _react.useMemo)(() => {
if (checkStrictly) {
return [mergedSelectedKeyList, []];
}
const {
checkedKeys,
halfCheckedKeys
} = (0, _conductUtil.conductCheck)(mergedSelectedKeyList, true, keyEntities, isCheckboxDisabled);
return [checkedKeys || [], halfCheckedKeys];
}, [mergedSelectedKeyList, checkStrictly, keyEntities, isCheckboxDisabled]);
const derivedSelectedKeySet = (0, _react.useMemo)(() => {
const keys = selectionType === 'radio' ? derivedSelectedKeys.slice(0, 1) : derivedSelectedKeys;
return new Set(keys);
}, [derivedSelectedKeys, selectionType]);
const derivedHalfSelectedKeySet = (0, _react.useMemo)(() => selectionType === 'radio' ? new Set() : new Set(derivedHalfSelectedKeys), [derivedHalfSelectedKeys, selectionType]);
// Reset if rowSelection reset
React.useEffect(() => {
if (!rowSelection) {
setMergedSelectedKeys(EMPTY_LIST);
}
}, [!!rowSelection]);
const setSelectedKeys = (0, _react.useCallback)((keys, method) => {
let availableKeys;
let records;
updatePreserveRecordsCache(keys);
if (preserveSelectedRowKeys) {
availableKeys = keys;
records = keys.map(key => preserveRecordsRef.current.get(key));
} else {
// Filter key which not exist in the `dataSource`
availableKeys = [];
records = [];
keys.forEach(key => {
const record = getRecordByKey(key);
if (record !== undefined) {
availableKeys.push(key);
records.push(record);
}
});
}
setMergedSelectedKeys(availableKeys);
onSelectionChange?.(availableKeys, records, {
type: method
});
}, [setMergedSelectedKeys, getRecordByKey, onSelectionChange, preserveSelectedRowKeys]);
// ====================== Selections ======================
// Trigger single `onSelect` event
const triggerSingleSelection = (0, _react.useCallback)((key, selected, keys, event) => {
if (onSelect) {
const rows = keys.map(getRecordByKey);
onSelect(getRecordByKey(key), selected, rows, event);
}
setSelectedKeys(keys, 'single');
}, [onSelect, getRecordByKey, setSelectedKeys]);
const mergedSelections = (0, _react.useMemo)(() => {
if (!selections || hideSelectAll) {
return null;
}
const selectionList = selections === true ? [SELECTION_ALL, SELECTION_INVERT, SELECTION_NONE] : selections;
return selectionList.map(selection => {
if (selection === SELECTION_ALL) {
return {
key: 'all',
text: tableLocale.selectionAll,
onSelect() {
setSelectedKeys(data.map((record, index) => getRowKey(record, index)).filter(key => {
const checkProps = checkboxPropsMap.get(key);
return !checkProps?.disabled || derivedSelectedKeySet.has(key);
}), 'all');
}
};
}
if (selection === SELECTION_INVERT) {
return {
key: 'invert',
text: tableLocale.selectInvert,
onSelect() {
const keySet = new Set(derivedSelectedKeySet);
pageData.forEach((record, index) => {
const key = getRowKey(record, index);
const checkProps = checkboxPropsMap.get(key);
if (!checkProps?.disabled) {
if (keySet.has(key)) {
keySet.delete(key);
} else {
keySet.add(key);
}
}
});
const keys = Array.from(keySet);
if (onSelectInvert) {
warning.deprecated(false, 'onSelectInvert', 'onChange');
onSelectInvert(keys);
}
setSelectedKeys(keys, 'invert');
}
};
}
if (selection === SELECTION_NONE) {
return {
key: 'none',
text: tableLocale.selectNone,
onSelect() {
onSelectNone?.();
setSelectedKeys(Array.from(derivedSelectedKeySet).filter(key => {
const checkProps = checkboxPropsMap.get(key);
return checkProps?.disabled;
}), 'none');
}
};
}
return selection;
}).map(selection => ({
...selection,
onSelect: (...rest) => {
selection.onSelect?.(...rest);
updatePrevSelectedIndex(null);
}
}));
}, [selections, hideSelectAll, tableLocale.selectionAll, tableLocale.selectInvert, tableLocale.selectNone, checkboxPropsMap, derivedSelectedKeySet, data, pageData, getRowKey, onSelectInvert, setSelectedKeys]);
// ======================= Columns ========================
const transformColumns = (0, _react.useCallback)(columns => {
// >>>>>>>>>>> Skip if not exists `rowSelection`
if (!rowSelection) {
process.env.NODE_ENV !== "production" ? warning(!columns.includes(SELECTION_COLUMN), 'usage', '`rowSelection` is not config but `SELECTION_COLUMN` exists in the `columns`.') : void 0;
return columns.filter(col => col !== SELECTION_COLUMN);
}
// >>>>>>>>>>> Support selection
let cloneColumns = (0, _toConsumableArray2.default)(columns);
const keySet = new Set(derivedSelectedKeySet);
// Record key only need check with enabled
const recordKeys = flattedData.map(getRowKey).filter(key => !checkboxPropsMap.get(key).disabled);
const checkedCurrentAll = recordKeys.every(key => keySet.has(key));
const checkedCurrentSome = recordKeys.some(key => keySet.has(key));
const onSelectAllChange = () => {
const changeKeys = [];
if (checkedCurrentAll) {
recordKeys.forEach(key => {
keySet.delete(key);
changeKeys.push(key);
});
} else {
recordKeys.forEach(key => {
if (!keySet.has(key)) {
keySet.add(key);
changeKeys.push(key);
}
});
}
const keys = Array.from(keySet);
onSelectAll?.(!checkedCurrentAll, keys.map(getRecordByKey), changeKeys.map(getRecordByKey));
setSelectedKeys(keys, 'all');
updatePrevSelectedIndex(null);
};
// ===================== Render =====================
// Title Cell
let title;
let columnTitleCheckbox;
if (selectionType !== 'radio') {
let customizeSelections;
if (mergedSelections) {
const menu = {
getPopupContainer,
items: mergedSelections.map((selection, index) => {
const {
key,
text,
onSelect: onSelectionClick
} = selection;
return {
key: key ?? index,
onClick: () => {
onSelectionClick?.(recordKeys);
},
label: text
};
})
};
customizeSelections = /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-selection-extra`
}, /*#__PURE__*/React.createElement(_dropdown.default, {
menu: menu,
getPopupContainer: getPopupContainer
}, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(_DownOutlined.default, null))));
}
const allDisabledData = flattedData.map((record, index) => {
const key = getRowKey(record, index);
const checkboxProps = checkboxPropsMap.get(key) || {};
return {
checked: keySet.has(key),
...checkboxProps
};
}).filter(({
disabled
}) => disabled);
const allDisabled = !!allDisabledData.length && allDisabledData.length === flattedData.length;
const allDisabledAndChecked = allDisabled && allDisabledData.every(({
checked
}) => checked);
const allDisabledSomeChecked = allDisabled && allDisabledData.some(({
checked
}) => checked);
const customCheckboxProps = getTitleCheckboxProps?.() || {};
const {
onChange,
disabled
} = customCheckboxProps;
columnTitleCheckbox = /*#__PURE__*/React.createElement(_checkbox.default, {
"aria-label": customizeSelections ? 'Custom selection' : 'Select all',
...customCheckboxProps,
checked: !allDisabled ? !!flattedData.length && checkedCurrentAll : allDisabledAndChecked,
indeterminate: !allDisabled ? !checkedCurrentAll && checkedCurrentSome : !allDisabledAndChecked && allDisabledSomeChecked,
onChange: e => {
onSelectAllChange();
onChange?.(e);
},
disabled: disabled ?? (flattedData.length === 0 || allDisabled),
skipGroup: true
});
title = !hideSelectAll && (/*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-selection`
}, columnTitleCheckbox, customizeSelections));
}
// Body Cell
let renderCell;
if (selectionType === 'radio') {
renderCell = (_, record, index) => {
const key = getRowKey(record, index);
const checked = keySet.has(key);
const checkboxProps = checkboxPropsMap.get(key);
return {
node: (/*#__PURE__*/React.createElement(_radio.default, {
...checkboxProps,
checked: checked,
onClick: e => {
e.stopPropagation();
checkboxProps?.onClick?.(e);
},
onChange: event => {
if (!keySet.has(key)) {
triggerSingleSelection(key, true, [key], event.nativeEvent);
}
checkboxProps?.onChange?.(event);
}
})),
checked
};
};
} else {
renderCell = (_, record, index) => {
const key = getRowKey(record, index);
const checked = keySet.has(key);
const indeterminate = derivedHalfSelectedKeySet.has(key);
const checkboxProps = checkboxPropsMap.get(key);
let mergedIndeterminate;
if (expandType === 'nest') {
mergedIndeterminate = indeterminate;
process.env.NODE_ENV !== "production" ? warning(typeof checkboxProps?.indeterminate !== 'boolean', 'usage', 'set `indeterminate` using `rowSelection.getCheckboxProps` is not allowed with tree structured dataSource.') : void 0;
} else {
mergedIndeterminate = checkboxProps?.indeterminate ?? indeterminate;
}
// Record checked
return {
node: (/*#__PURE__*/React.createElement(_checkbox.default, {
...checkboxProps,
indeterminate: mergedIndeterminate,
checked: checked,
skipGroup: true,
onClick: e => {
e.stopPropagation();
checkboxProps?.onClick?.(e);
},
onChange: event => {
const {
nativeEvent
} = event;
const {
shiftKey
} = nativeEvent;
const currentSelectedIndex = recordKeys.indexOf(key);
const isMultiple = derivedSelectedKeys.some(item => recordKeys.includes(item));
if (shiftKey && checkStrictly && isMultiple) {
const changedKeys = multipleSelect(currentSelectedIndex, recordKeys, keySet);
const keys = Array.from(keySet);
onSelectMultiple?.(!checked, keys.map(getRecordByKey), changedKeys.map(getRecordByKey));
setSelectedKeys(keys, 'multiple');
} else {
// Single record selected
const originCheckedKeys = derivedSelectedKeys;
if (checkStrictly) {
const checkedKeys = checked ? (0, _util.arrDel)(originCheckedKeys, key) : (0, _util.arrAdd)(originCheckedKeys, key);
triggerSingleSelection(key, !checked, checkedKeys, nativeEvent);
} else {
// Always fill first
const result = (0, _conductUtil.conductCheck)([].concat((0, _toConsumableArray2.default)(originCheckedKeys), [key]), true, keyEntities, isCheckboxDisabled);
const {
checkedKeys,
halfCheckedKeys
} = result;
let nextCheckedKeys = checkedKeys;
// If remove, we do it again to correction
if (checked) {
const tempKeySet = new Set(checkedKeys);
tempKeySet.delete(key);
nextCheckedKeys = (0, _conductUtil.conductCheck)(Array.from(tempKeySet), {
checked: false,
halfCheckedKeys
}, keyEntities, isCheckboxDisabled).checkedKeys;
}
triggerSingleSelection(key, !checked, nextCheckedKeys, nativeEvent);
}
}
if (checked) {
updatePrevSelectedIndex(null);
} else {
updatePrevSelectedIndex(currentSelectedIndex);
}
checkboxProps?.onChange?.(event);
}
})),
checked
};
};
}
const renderSelectionCell = (_, record, index) => {
const {
node,
checked
} = renderCell(_, record, index);
if (customizeRenderCell) {
return customizeRenderCell(checked, record, index, node);
}
return node;
};
// Insert selection column if not exist
if (!cloneColumns.includes(SELECTION_COLUMN)) {
// Always after expand icon
if (cloneColumns.findIndex(col => col[_table.INTERNAL_COL_DEFINE]?.columnType === 'EXPAND_COLUMN') === 0) {
const [expandColumn, ...restColumns] = cloneColumns;
cloneColumns = [expandColumn, SELECTION_COLUMN].concat((0, _toConsumableArray2.default)(restColumns));
} else {
// Normal insert at first column
cloneColumns = [SELECTION_COLUMN].concat((0, _toConsumableArray2.default)(cloneColumns));
}
}
// Deduplicate selection column
const selectionColumnIndex = cloneColumns.indexOf(SELECTION_COLUMN);
process.env.NODE_ENV !== "production" ? warning(cloneColumns.filter(col => col === SELECTION_COLUMN).length <= 1, 'usage', 'Multiple `SELECTION_COLUMN` exist in `columns`.') : void 0;
cloneColumns = cloneColumns.filter((column, index) => column !== SELECTION_COLUMN || index === selectionColumnIndex);
// Fixed column logic
const prevCol = cloneColumns[selectionColumnIndex - 1];
const nextCol = cloneColumns[selectionColumnIndex + 1];
let mergedFixed = fixed;
if (mergedFixed === undefined) {
if (nextCol?.fixed !== undefined) {
mergedFixed = nextCol.fixed;
} else if (prevCol?.fixed !== undefined) {
mergedFixed = prevCol.fixed;
}
}
if (mergedFixed && prevCol && prevCol[_table.INTERNAL_COL_DEFINE]?.columnType === 'EXPAND_COLUMN' && prevCol.fixed === undefined) {
prevCol.fixed = mergedFixed;
}
const columnCls = (0, _clsx.clsx)(`${prefixCls}-selection-col`, {
[`${prefixCls}-selection-col-with-dropdown`]: selections && selectionType === 'checkbox'
});
const renderColumnTitle = () => {
if (!rowSelection?.columnTitle) {
return title;
}
if (typeof rowSelection.columnTitle === 'function') {
return rowSelection.columnTitle(columnTitleCheckbox);
}
return rowSelection.columnTitle;
};
// Replace with real selection column
const selectionColumn = {
fixed: mergedFixed,
width: selectionColWidth,
className: `${prefixCls}-selection-column`,
title: renderColumnTitle(),
render: renderSelectionCell,
onCell: rowSelection.onCell,
align: rowSelection.align,
[_table.INTERNAL_COL_DEFINE]: {
className: columnCls
}
};
return cloneColumns.map(col => col === SELECTION_COLUMN ? selectionColumn : col);
}, [getRowKey, flattedData, rowSelection, derivedSelectedKeys, derivedSelectedKeySet, derivedHalfSelectedKeySet, selectionColWidth, mergedSelections, expandType, checkboxPropsMap, onSelectMultiple, triggerSingleSelection, isCheckboxDisabled]);
return [transformColumns, derivedSelectedKeySet];
};
var _default = exports.default = useSelection;
+21
View File
@@ -0,0 +1,21 @@
import type { AnyObject } from '../../_util/type';
import type { Locale } from '../../locale';
import type { ColumnsType, ColumnTitleProps, ColumnType, Key, SorterResult, SorterTooltipProps, SortOrder, TableLocale, TransformColumns } from '../interface';
export interface SortState<RecordType = AnyObject> {
column: ColumnType<RecordType>;
key: Key;
sortOrder: SortOrder | null;
multiplePriority: number | false;
}
export declare const getSortData: <RecordType extends AnyObject = AnyObject>(data: readonly RecordType[], sortStates: SortState<RecordType>[], childrenColumnName: string) => RecordType[];
interface SorterConfig<RecordType = AnyObject> {
prefixCls: string;
mergedColumns: ColumnsType<RecordType>;
onSorterChange: (sorterResult: SorterResult<RecordType> | SorterResult<RecordType>[], sortStates: SortState<RecordType>[]) => void;
sortDirections: SortOrder[];
tableLocale?: TableLocale;
showSorterTooltip?: boolean | SorterTooltipProps;
globalLocale?: Locale['global'];
}
declare const useFilterSorter: <RecordType extends AnyObject = AnyObject>(props: SorterConfig<RecordType>) => [TransformColumns<RecordType>, SortState<RecordType>[], ColumnTitleProps<RecordType>, () => SorterResult<RecordType> | SorterResult<RecordType>[]];
export default useFilterSorter;
+383
View File
@@ -0,0 +1,383 @@
"use strict";
"use client";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getSortData = exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var React = _interopRequireWildcard(require("react"));
var _CaretDownOutlined = _interopRequireDefault(require("@ant-design/icons/CaretDownOutlined"));
var _CaretUpOutlined = _interopRequireDefault(require("@ant-design/icons/CaretUpOutlined"));
var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
var _clsx = require("clsx");
var _is = require("../../_util/is");
var _tooltip = _interopRequireDefault(require("../../tooltip"));
var _util = require("../util");
const ASCEND = 'ascend';
const DESCEND = 'descend';
const getMultiplePriority = column => {
if (column.sorter && typeof column.sorter === 'object' && (0, _is.isNumber)(column.sorter.multiple)) {
return column.sorter.multiple;
}
return false;
};
const getSortFunction = sorter => {
if (typeof sorter === 'function') {
return sorter;
}
if ((0, _is.isPlainObject)(sorter) && sorter.compare) {
return sorter.compare;
}
return false;
};
const nextSortDirection = (sortDirections, current) => {
if (!current) {
return sortDirections[0];
}
return sortDirections[sortDirections.indexOf(current) + 1];
};
const collectSortStates = (columns, init, pos) => {
let sortStates = [];
const pushState = (column, columnPos) => {
sortStates.push({
column,
key: (0, _util.getColumnKey)(column, columnPos),
multiplePriority: getMultiplePriority(column),
sortOrder: column.sortOrder
});
};
(columns || []).forEach((column, index) => {
const columnPos = (0, _util.getColumnPos)(index, pos);
if (column.children) {
if ('sortOrder' in column) {
// Controlled
pushState(column, columnPos);
}
sortStates = [].concat((0, _toConsumableArray2.default)(sortStates), (0, _toConsumableArray2.default)(collectSortStates(column.children, init, columnPos)));
} else if (column.sorter) {
if ('sortOrder' in column) {
// Controlled
pushState(column, columnPos);
} else if (init && column.defaultSortOrder) {
// Default sorter
sortStates.push({
column,
key: (0, _util.getColumnKey)(column, columnPos),
multiplePriority: getMultiplePriority(column),
sortOrder: column.defaultSortOrder
});
}
}
});
return sortStates;
};
const injectSorter = (prefixCls, columns, sorterStates, triggerSorter, defaultSortDirections, tableLocale, tableShowSorterTooltip, pos, a11yLocale) => {
const finalColumns = (columns || []).map((column, index) => {
const columnPos = (0, _util.getColumnPos)(index, pos);
let newColumn = column;
if (newColumn.sorter) {
const sortDirections = newColumn.sortDirections || defaultSortDirections;
const showSorterTooltip = newColumn.showSorterTooltip === undefined ? tableShowSorterTooltip : newColumn.showSorterTooltip;
const columnKey = (0, _util.getColumnKey)(newColumn, columnPos);
const sorterState = sorterStates.find(({
key
}) => key === columnKey);
const sortOrder = sorterState ? sorterState.sortOrder : null;
const nextSortOrder = nextSortDirection(sortDirections, sortOrder);
let sorter;
if (column.sortIcon) {
sorter = column.sortIcon({
sortOrder
});
} else {
const upNode = sortDirections.includes(ASCEND) && (/*#__PURE__*/React.createElement(_CaretUpOutlined.default, {
className: (0, _clsx.clsx)(`${prefixCls}-column-sorter-up`, {
active: sortOrder === ASCEND
})
}));
const downNode = sortDirections.includes(DESCEND) && (/*#__PURE__*/React.createElement(_CaretDownOutlined.default, {
className: (0, _clsx.clsx)(`${prefixCls}-column-sorter-down`, {
active: sortOrder === DESCEND
})
}));
sorter = /*#__PURE__*/React.createElement("span", {
className: (0, _clsx.clsx)(`${prefixCls}-column-sorter`, {
[`${prefixCls}-column-sorter-full`]: !!(upNode && downNode)
})
}, /*#__PURE__*/React.createElement("span", {
className: `${prefixCls}-column-sorter-inner`,
"aria-hidden": "true"
}, upNode, downNode));
}
const {
cancelSort,
triggerAsc,
triggerDesc
} = tableLocale || {};
let sortTip = cancelSort;
if (nextSortOrder === DESCEND) {
sortTip = triggerDesc;
} else if (nextSortOrder === ASCEND) {
sortTip = triggerAsc;
}
const tooltipProps = (0, _is.isPlainObject)(showSorterTooltip) ? {
title: sortTip,
...showSorterTooltip
} : {
title: sortTip
};
newColumn = {
...newColumn,
className: (0, _clsx.clsx)(newColumn.className, {
[`${prefixCls}-column-sort`]: sortOrder
}),
title: renderProps => {
const columnSortersClass = `${prefixCls}-column-sorters`;
const renderColumnTitleWrapper = /*#__PURE__*/React.createElement("span", {
className: `${prefixCls}-column-title`
}, (0, _util.renderColumnTitle)(column.title, renderProps));
const renderSortTitle = /*#__PURE__*/React.createElement("div", {
className: columnSortersClass
}, renderColumnTitleWrapper, sorter);
if (showSorterTooltip) {
if (typeof showSorterTooltip !== 'boolean' && showSorterTooltip?.target === 'sorter-icon') {
return /*#__PURE__*/React.createElement("div", {
className: (0, _clsx.clsx)(columnSortersClass, `${columnSortersClass}-tooltip-target-sorter`)
}, renderColumnTitleWrapper, /*#__PURE__*/React.createElement(_tooltip.default, {
...tooltipProps
}, sorter));
}
return /*#__PURE__*/React.createElement(_tooltip.default, {
...tooltipProps
}, renderSortTitle);
}
return renderSortTitle;
},
onHeaderCell: col => {
const cell = column.onHeaderCell?.(col) || {};
const originOnClick = cell.onClick;
const originOKeyDown = cell.onKeyDown;
cell.onClick = event => {
triggerSorter({
column,
key: columnKey,
sortOrder: nextSortOrder,
multiplePriority: getMultiplePriority(column)
});
originOnClick?.(event);
};
cell.onKeyDown = event => {
if (event.keyCode === _KeyCode.default.ENTER) {
triggerSorter({
column,
key: columnKey,
sortOrder: nextSortOrder,
multiplePriority: getMultiplePriority(column)
});
originOKeyDown?.(event);
}
};
const renderTitle = (0, _util.safeColumnTitle)(column.title, {});
const displayTitle = renderTitle?.toString();
// Inform the screen-reader so it can tell the visually impaired user which column is sorted
if (sortOrder) {
cell['aria-sort'] = sortOrder === 'ascend' ? 'ascending' : 'descending';
}
// Inform the screen-reader so it can tell the visually impaired user that this column can be sorted
cell['aria-description'] = a11yLocale?.sortable;
cell['aria-label'] = displayTitle || '';
cell.className = (0, _clsx.clsx)(cell.className, `${prefixCls}-column-has-sorters`);
cell.tabIndex = 0;
if (column.ellipsis) {
cell.title = (renderTitle ?? '').toString();
}
return cell;
}
};
}
if ('children' in newColumn) {
newColumn = {
...newColumn,
children: injectSorter(prefixCls, newColumn.children, sorterStates, triggerSorter, defaultSortDirections, tableLocale, tableShowSorterTooltip, columnPos, a11yLocale)
};
}
return newColumn;
});
return finalColumns;
};
const stateToInfo = sorterState => {
const {
column,
sortOrder
} = sorterState;
return {
column,
order: sortOrder,
field: column.dataIndex,
columnKey: column.key
};
};
const generateSorterInfo = sorterStates => {
const activeSorters = sorterStates.filter(({
sortOrder
}) => sortOrder).map(stateToInfo);
// =========== Legacy compatible support ===========
// https://github.com/ant-design/ant-design/pull/19226
if (activeSorters.length === 0 && sorterStates.length) {
const lastIndex = sorterStates.length - 1;
return {
...stateToInfo(sorterStates[lastIndex]),
column: undefined,
order: undefined,
field: undefined,
columnKey: undefined
};
}
if (activeSorters.length <= 1) {
return activeSorters[0] || {};
}
return activeSorters;
};
const getSortData = (data, sortStates, childrenColumnName) => {
const innerSorterStates = sortStates.slice().sort((a, b) => b.multiplePriority - a.multiplePriority);
const cloneData = data.slice();
const runningSorters = innerSorterStates.filter(({
column: {
sorter
},
sortOrder
}) => getSortFunction(sorter) && sortOrder);
// Skip if no sorter needed
if (!runningSorters.length) {
return cloneData;
}
return cloneData.sort((record1, record2) => {
for (let i = 0; i < runningSorters.length; i += 1) {
const sorterState = runningSorters[i];
const {
column: {
sorter
},
sortOrder
} = sorterState;
const compareFn = getSortFunction(sorter);
if (compareFn && sortOrder) {
const compareResult = compareFn(record1, record2, sortOrder);
if (compareResult !== 0) {
return sortOrder === ASCEND ? compareResult : -compareResult;
}
}
}
return 0;
}).map(record => {
const subRecords = record[childrenColumnName];
if (subRecords) {
return {
...record,
[childrenColumnName]: getSortData(subRecords, sortStates, childrenColumnName)
};
}
return record;
});
};
exports.getSortData = getSortData;
const useFilterSorter = props => {
const {
prefixCls,
mergedColumns,
sortDirections,
tableLocale,
showSorterTooltip,
onSorterChange,
globalLocale
} = props;
const [sortStates, setSortStates] = React.useState(() => collectSortStates(mergedColumns, true));
const getColumnKeys = (columns, pos) => {
const newKeys = [];
columns.forEach((item, index) => {
const columnPos = (0, _util.getColumnPos)(index, pos);
newKeys.push((0, _util.getColumnKey)(item, columnPos));
if (Array.isArray(item.children)) {
const childKeys = getColumnKeys(item.children, columnPos);
newKeys.push.apply(newKeys, (0, _toConsumableArray2.default)(childKeys));
}
});
return newKeys;
};
const mergedSorterStates = React.useMemo(() => {
let validate = true;
const collectedStates = collectSortStates(mergedColumns, false);
// Return if not controlled
if (!collectedStates.length) {
const mergedColumnsKeys = getColumnKeys(mergedColumns);
return sortStates.filter(({
key
}) => mergedColumnsKeys.includes(key));
}
const validateStates = [];
function patchStates(state) {
if (validate) {
validateStates.push(state);
} else {
validateStates.push({
...state,
sortOrder: null
});
}
}
let multipleMode = null;
collectedStates.forEach(state => {
if (multipleMode === null) {
patchStates(state);
if (state.sortOrder) {
if (state.multiplePriority === false) {
validate = false;
} else {
multipleMode = true;
}
}
} else if (multipleMode && state.multiplePriority !== false) {
patchStates(state);
} else {
validate = false;
patchStates(state);
}
});
return validateStates;
}, [mergedColumns, sortStates]);
// Get render columns title required props
const columnTitleSorterProps = React.useMemo(() => {
const sortColumns = mergedSorterStates.map(({
column,
sortOrder
}) => ({
column,
order: sortOrder
}));
return {
sortColumns,
// Legacy
sortColumn: sortColumns[0]?.column,
sortOrder: sortColumns[0]?.order
};
}, [mergedSorterStates]);
const triggerSorter = sortState => {
let newSorterStates;
if (sortState.multiplePriority === false || !mergedSorterStates.length || mergedSorterStates[0].multiplePriority === false) {
newSorterStates = [sortState];
} else {
newSorterStates = [].concat((0, _toConsumableArray2.default)(mergedSorterStates.filter(({
key
}) => key !== sortState.key)), [sortState]);
}
setSortStates(newSorterStates);
onSorterChange(generateSorterInfo(newSorterStates), newSorterStates);
};
const transformColumns = innerColumns => injectSorter(prefixCls, innerColumns, mergedSorterStates, triggerSorter, sortDirections, tableLocale, showSorterTooltip, undefined, globalLocale);
const getSorters = () => generateSorterInfo(mergedSorterStates);
return [transformColumns, mergedSorterStates, columnTitleSorterProps, getSorters];
};
var _default = exports.default = useFilterSorter;
@@ -0,0 +1,4 @@
import type { AnyObject } from 'antd/es/_util/type';
import type { ColumnTitleProps, TransformColumns } from '../interface';
declare const useTitleColumns: <RecordType extends AnyObject = AnyObject>(columnTitleProps: ColumnTitleProps<RecordType>) => readonly [TransformColumns<RecordType>];
export default useTitleColumns;
+27
View File
@@ -0,0 +1,27 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _util = require("../util");
const fillTitle = (columns, columnTitleProps) => {
const finalColumns = columns.map(column => {
const cloneColumn = {
...column
};
cloneColumn.title = (0, _util.renderColumnTitle)(column.title, columnTitleProps);
if ('children' in cloneColumn) {
cloneColumn.children = fillTitle(cloneColumn.children, columnTitleProps);
}
return cloneColumn;
});
return finalColumns;
};
const useTitleColumns = columnTitleProps => {
const filledColumns = React.useCallback(columns => fillTitle(columns, columnTitleProps), [columnTitleProps]);
return [filledColumns];
};
var _default = exports.default = useTitleColumns;
+7
View File
@@ -0,0 +1,7 @@
import type { ComponentsSemantic, ComponentsSemanticClassNames, ComponentsSemanticStyles, TablePaginationConfig, TableProps, TableSemanticClassNames, TableSemanticName, TableSemanticStyles } from './InternalTable';
import Table from './Table';
export type { ColumnProps } from './Column';
export type { ColumnGroupType, ColumnsType, ColumnType } from './interface';
export type { Reference as TableRef } from '@rc-component/table';
export type { ComponentsSemantic, ComponentsSemanticClassNames, ComponentsSemanticStyles, TablePaginationConfig, TableProps, TableSemanticClassNames, TableSemanticName, TableSemanticStyles, };
export default Table;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
"use client";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _Table = _interopRequireDefault(require("./Table"));
var _default = exports.default = _Table.default;
+199
View File
@@ -0,0 +1,199 @@
import type * as React from 'react';
import type { Reference } from '@rc-component/table';
import type { ExpandableConfig, FixedType, GetComponentProps, GetRowKey, ColumnType as RcColumnType, RenderedCell as RcRenderedCell } from '@rc-component/table/lib/interface';
import type { Breakpoint } from '../_util/responsiveObserver';
import type { AnyObject } from '../_util/type';
import type { CheckboxProps } from '../checkbox';
import type { DropdownProps } from '../dropdown';
import type { PaginationProps } from '../pagination';
import type { TooltipProps } from '../tooltip';
import type { INTERNAL_SELECTION_ITEM } from './hooks/useSelection';
import type { InternalTableProps, TableProps } from './InternalTable';
export type RefTable = <RecordType = AnyObject>(props: React.PropsWithChildren<TableProps<RecordType>> & React.RefAttributes<Reference>) => React.ReactElement;
export type RefInternalTable = <RecordType = AnyObject>(props: React.PropsWithChildren<InternalTableProps<RecordType>> & React.RefAttributes<Reference>) => React.ReactElement;
export type { ExpandableConfig, GetRowKey };
export type Key = React.Key;
export type SafeKey = Exclude<Key, bigint>;
export type RowSelectionType = 'checkbox' | 'radio';
export type SelectionItemSelectFn = (currentRowKeys: Key[]) => void;
export type ExpandType = null | 'row' | 'nest';
export interface TableLocale {
filterTitle?: string;
filterConfirm?: React.ReactNode;
filterReset?: React.ReactNode;
filterEmptyText?: React.ReactNode;
/**
* @deprecated Please use `filterCheckAll` instead.
*/
filterCheckall?: React.ReactNode;
filterCheckAll?: React.ReactNode;
filterSearchPlaceholder?: string;
emptyText?: React.ReactNode | (() => React.ReactNode);
selectAll?: React.ReactNode;
selectNone?: React.ReactNode;
selectInvert?: React.ReactNode;
selectionAll?: React.ReactNode;
sortTitle?: string;
expand?: string;
collapse?: string;
triggerDesc?: string;
triggerAsc?: string;
cancelSort?: string;
}
export type SortOrder = 'descend' | 'ascend' | null;
export type SorterTooltipTarget = 'full-header' | 'sorter-icon';
export type SorterTooltipProps = TooltipProps & {
target?: SorterTooltipTarget;
};
declare const _TableActions: readonly ["paginate", "sort", "filter"];
export type TableAction = (typeof _TableActions)[number];
export type CompareFn<T = AnyObject> = (a: T, b: T, sortOrder?: SortOrder) => number;
export interface ColumnFilterItem {
text: React.ReactNode;
value: React.Key | boolean;
children?: ColumnFilterItem[];
}
export interface ColumnTitleProps<RecordType = AnyObject> {
/** @deprecated Will be remove in v7, Please use `sorterColumns` instead. */
sortOrder?: SortOrder;
/** @deprecated Will be remove in v7, Please use `sorterColumns` instead. */
sortColumn?: ColumnType<RecordType>;
sortColumns?: {
column: ColumnType<RecordType>;
order: SortOrder;
}[];
filters?: Record<string, FilterValue>;
}
export type ColumnTitle<RecordType = AnyObject> = React.ReactNode | ((props: ColumnTitleProps<RecordType>) => React.ReactNode);
export type FilterValue = (Key | boolean)[];
export type FilterKey = (string | number)[] | null;
export type FilterSearchType<RecordType = AnyObject> = boolean | ((input: string, record: RecordType) => boolean);
export interface FilterConfirmProps {
closeDropdown: boolean;
}
export interface FilterRestProps {
confirm?: boolean;
closeDropdown?: boolean;
}
export interface FilterDropdownProps {
prefixCls: string;
setSelectedKeys: (selectedKeys: React.Key[]) => void;
selectedKeys: React.Key[];
/**
* Confirm filter value, if you want to close dropdown before commit, you can call with
* {closeDropdown: true}
*/
confirm: (param?: FilterConfirmProps) => void;
clearFilters?: (param?: FilterRestProps) => void;
filters?: ColumnFilterItem[];
/** Only close filterDropdown */
close: () => void;
visible: boolean;
}
interface CoverableDropdownProps extends Omit<DropdownProps, 'onOpenChange' | 'overlay' | 'visible' | 'onVisibleChange'> {
onOpenChange?: (open: boolean) => void;
}
export interface ColumnType<RecordType = AnyObject> extends Omit<RcColumnType<RecordType>, 'title'> {
title?: ColumnTitle<RecordType>;
sorter?: boolean | CompareFn<RecordType> | {
compare?: CompareFn<RecordType>;
/** Config multiple sorter order priority */
multiple?: number;
};
sortOrder?: SortOrder;
defaultSortOrder?: SortOrder;
sortDirections?: SortOrder[];
sortIcon?: (props: {
sortOrder: SortOrder;
}) => React.ReactNode;
showSorterTooltip?: boolean | SorterTooltipProps;
filtered?: boolean;
filters?: ColumnFilterItem[];
filterDropdown?: React.ReactNode | ((props: FilterDropdownProps) => React.ReactNode);
filterOnClose?: boolean;
filterMultiple?: boolean;
filteredValue?: FilterValue | null;
defaultFilteredValue?: FilterValue | null;
filterIcon?: React.ReactNode | ((filtered: boolean) => React.ReactNode);
filterMode?: 'menu' | 'tree';
filterSearch?: FilterSearchType<ColumnFilterItem>;
onFilter?: (value: React.Key | boolean, record: RecordType) => boolean;
/**
* Can cover `<Dropdown>` props
* @since 5.22.0
*/
filterDropdownProps?: CoverableDropdownProps;
filterResetToDefaultFilteredValue?: boolean;
responsive?: Breakpoint[];
/**
* @deprecated Please use `filterDropdownProps.open` instead.
* @since 4.23.0
*/
filterDropdownOpen?: boolean;
/**
* @deprecated Please use `filterDropdownProps.onOpenChange` instead.
* @since 4.23.0
*/
onFilterDropdownOpenChange?: (visible: boolean) => void;
}
export interface ColumnGroupType<RecordType = AnyObject> extends Omit<ColumnType<RecordType>, 'dataIndex'> {
children: ColumnsType<RecordType>;
}
export type ColumnsType<RecordType = AnyObject> = (ColumnGroupType<RecordType> | ColumnType<RecordType>)[];
export interface SelectionItem {
key: string;
text: React.ReactNode;
onSelect?: SelectionItemSelectFn;
}
export type SelectionSelectFn<T = AnyObject> = (record: T, selected: boolean, selectedRows: T[], nativeEvent: Event) => void;
export type RowSelectMethod = 'all' | 'none' | 'invert' | 'single' | 'multiple';
export interface TableRowSelection<T = AnyObject> {
/** Keep the selection keys in list even the key not exist in `dataSource` anymore */
preserveSelectedRowKeys?: boolean;
type?: RowSelectionType;
selectedRowKeys?: Key[];
defaultSelectedRowKeys?: Key[];
onChange?: (selectedRowKeys: Key[], selectedRows: T[], info: {
type: RowSelectMethod;
}) => void;
getCheckboxProps?: (record: T) => Partial<Omit<CheckboxProps, 'checked' | 'defaultChecked'>>;
onSelect?: SelectionSelectFn<T>;
/** @deprecated This function will be remove in v7 and should use `onChange` instead */
onSelectMultiple?: (selected: boolean, selectedRows: T[], changeRows: T[]) => void;
/** @deprecated This function will be remove in v7 and should use `onChange` instead */
onSelectAll?: (selected: boolean, selectedRows: T[], changeRows: T[]) => void;
/** @deprecated This function will be remove in v7 and should use `onChange` instead */
onSelectInvert?: (selectedRowKeys: Key[]) => void;
/** @deprecated This function will be remove in v7 and should use `onChange` instead */
onSelectNone?: () => void;
selections?: INTERNAL_SELECTION_ITEM[] | boolean;
hideSelectAll?: boolean;
fixed?: FixedType;
columnWidth?: string | number;
columnTitle?: React.ReactNode | ((checkboxNode: React.ReactNode) => React.ReactNode);
checkStrictly?: boolean;
/** Set the alignment of the selection column */
align?: 'left' | 'center' | 'right';
renderCell?: (value: boolean, record: T, index: number, originNode: React.ReactNode) => React.ReactNode | RcRenderedCell<T>;
onCell?: GetComponentProps<T>;
getTitleCheckboxProps?: () => Partial<Omit<CheckboxProps, 'checked' | 'defaultChecked'>> & React.AriaAttributes;
}
export type TransformColumns<RecordType = AnyObject> = (columns: ColumnsType<RecordType>) => ColumnsType<RecordType>;
export interface TableCurrentDataSource<RecordType = AnyObject> {
currentDataSource: RecordType[];
action: TableAction;
}
export interface SorterResult<RecordType = AnyObject> {
column?: ColumnType<RecordType>;
order?: SortOrder;
field?: Key | readonly Key[];
columnKey?: Key;
}
export type GetPopupContainer = (triggerNode: HTMLElement) => HTMLElement;
export type TablePaginationPlacement = 'topStart' | 'topCenter' | 'topEnd' | 'bottomStart' | 'bottomCenter' | 'bottomEnd' | 'none';
export type TablePaginationPosition = 'topLeft' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight' | 'none';
export interface TablePaginationConfig extends PaginationProps {
placement?: TablePaginationPlacement[];
/** @deprecated please use `placement` instead */
position?: TablePaginationPosition[];
}
+6
View File
@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _TableActions = ['paginate', 'sort', 'filter'];
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genBorderedStyle: GenerateStyle<TableToken, CSSObject>;
export default genBorderedStyle;
+125
View File
@@ -0,0 +1,125 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
const genBorderedStyle = token => {
const {
componentCls,
lineWidth,
lineType,
tableBorderColor,
tableHeaderBg,
tablePaddingVertical,
tablePaddingHorizontal,
calc
} = token;
const tableBorder = `${(0, _cssinjs.unit)(lineWidth)} ${lineType} ${tableBorderColor}`;
const getSizeBorderStyle = (size, paddingVertical, paddingHorizontal) => ({
[`&${componentCls}-${size}`]: {
[`> ${componentCls}-container`]: {
[`> ${componentCls}-content, > ${componentCls}-body`]: {
'> table > tbody > tr > th, > table > tbody > tr > td': {
[`> ${componentCls}-expanded-row-fixed`]: {
margin: `${(0, _cssinjs.unit)(calc(paddingVertical).mul(-1).equal())}
${(0, _cssinjs.unit)(calc(calc(paddingHorizontal).add(lineWidth)).mul(-1).equal())}`
}
}
}
}
}
});
return {
[`${componentCls}-wrapper`]: {
[`${componentCls}${componentCls}-bordered`]: {
// ============================ Title =============================
[`> ${componentCls}-title`]: {
border: tableBorder,
borderBottom: 0
},
// ============================ Content ============================
[`> ${componentCls}-container`]: {
borderInlineStart: tableBorder,
borderTop: tableBorder,
[`> ${componentCls}-content, > ${componentCls}-header, > ${componentCls}-body, > ${componentCls}-summary`]: {
'> table': {
// ============================= Cell =============================
'> thead > tr > th, > thead > tr > td, > tbody > tr > th, > tbody > tr > td, > tfoot > tr > th, > tfoot > tr > td': {
borderInlineEnd: tableBorder
},
// ============================ Header ============================
'> thead': {
'> tr:not(:last-child) > th': {
borderBottom: tableBorder
},
'> tr > th::before': {
backgroundColor: 'transparent !important'
}
},
// Fixed right should provides additional border
'> thead > tr, > tbody > tr, > tfoot > tr': {
[`> ${componentCls}-cell-fix-right-first::after`]: {
borderInlineEnd: tableBorder
}
},
// ========================== Expandable ==========================
'> tbody > tr > th, > tbody > tr > td': {
[`> ${componentCls}-expanded-row-fixed`]: {
margin: `${(0, _cssinjs.unit)(calc(tablePaddingVertical).mul(-1).equal())} ${(0, _cssinjs.unit)(calc(calc(tablePaddingHorizontal).add(lineWidth)).mul(-1).equal())}`,
'&::after': {
position: 'absolute',
top: 0,
insetInlineEnd: lineWidth,
bottom: 0,
borderInlineEnd: tableBorder,
content: '""'
}
}
}
}
}
},
// ============================ Scroll ============================
[`&${componentCls}-scroll-horizontal`]: {
[`> ${componentCls}-container > ${componentCls}-body`]: {
'> table > tbody': {
[`
> tr${componentCls}-expanded-row,
> tr${componentCls}-placeholder
`]: {
'> th, > td': {
borderInlineEnd: 0
}
}
}
}
},
// ============================ Size ============================
...getSizeBorderStyle('medium', token.tablePaddingVerticalMiddle, token.tablePaddingHorizontalMiddle),
...getSizeBorderStyle('small', token.tablePaddingVerticalSmall, token.tablePaddingHorizontalSmall),
// ============================ Footer ============================
[`> ${componentCls}-footer`]: {
border: tableBorder,
borderTop: 0
}
},
// ============================ Nested ============================
[`${componentCls}-cell`]: {
[`${componentCls}-container:first-child`]: {
// :first-child to avoid the case when bordered and title is set
borderTop: 0
},
// https://github.com/ant-design/ant-design/issues/35577
'&-scrollbar:not([rowspan])': {
boxShadow: `0 ${(0, _cssinjs.unit)(lineWidth)} 0 ${(0, _cssinjs.unit)(lineWidth)} ${tableHeaderBg}`
}
},
[`${componentCls}-bordered ${componentCls}-cell-scrollbar`]: {
borderInlineEnd: tableBorder
}
}
};
};
var _default = exports.default = genBorderedStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genEllipsisStyle: GenerateStyle<TableToken, CSSObject>;
export default genEllipsisStyle;
+36
View File
@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _style = require("../../style");
const genEllipsisStyle = token => {
const {
componentCls
} = token;
return {
[`${componentCls}-wrapper`]: {
[`${componentCls}-cell-ellipsis`]: {
..._style.textEllipsis,
wordBreak: 'keep-all',
// Fixed first or last should special process
[`
&${componentCls}-cell-fix-start-shadow,
&${componentCls}-cell-fix-end-shadow
`]: {
overflow: 'visible',
[`${componentCls}-cell-content`]: {
..._style.textEllipsis,
display: 'block'
}
},
[`${componentCls}-column-title`]: {
..._style.textEllipsis,
wordBreak: 'keep-all'
}
}
}
};
};
var _default = exports.default = genEllipsisStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genEmptyStyle: GenerateStyle<TableToken, CSSObject>;
export default genEmptyStyle;
+24
View File
@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
// ========================= Placeholder ==========================
const genEmptyStyle = token => {
const {
componentCls
} = token;
return {
[`${componentCls}-wrapper`]: {
[`${componentCls}-tbody > tr${componentCls}-placeholder`]: {
textAlign: 'center',
color: token.colorTextDisabled,
'&:hover > th, &:hover > td': {
background: token.colorBgContainer
}
}
}
};
};
var _default = exports.default = genEmptyStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genExpandStyle: GenerateStyle<TableToken, CSSObject>;
export default genExpandStyle;
+129
View File
@@ -0,0 +1,129 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
var _style = require("../../style");
const genExpandStyle = token => {
const {
componentCls,
antCls,
motionDurationSlow,
lineWidth,
paddingXS,
lineType,
tableBorderColor,
tableExpandIconBg,
tableExpandColumnWidth,
borderRadius,
tablePaddingVertical,
tablePaddingHorizontal,
tableExpandedRowBg,
paddingXXS,
expandIconMarginTop,
expandIconSize,
expandIconHalfInner,
expandIconScale,
calc
} = token;
const tableBorder = `${(0, _cssinjs.unit)(lineWidth)} ${lineType} ${tableBorderColor}`;
const expandIconLineOffset = calc(paddingXXS).sub(lineWidth).equal();
return {
[`${componentCls}-wrapper`]: {
[`${componentCls}-expand-icon-col`]: {
width: tableExpandColumnWidth
},
[`${componentCls}-row-expand-icon-cell`]: {
textAlign: 'center',
[`${componentCls}-row-expand-icon`]: {
display: 'inline-flex',
float: 'none',
verticalAlign: 'sub'
}
},
[`${componentCls}-row-indent`]: {
height: 1,
float: 'left'
},
[`${componentCls}-row-expand-icon`]: {
...(0, _style.operationUnit)(token),
position: 'relative',
float: 'left',
width: expandIconSize,
height: expandIconSize,
color: 'inherit',
lineHeight: (0, _cssinjs.unit)(expandIconSize),
background: tableExpandIconBg,
border: tableBorder,
borderRadius,
transform: `scale(${expandIconScale})`,
'&:focus, &:hover, &:active': {
borderColor: 'currentcolor'
},
'&::before, &::after': {
position: 'absolute',
background: 'currentcolor',
transition: `transform ${motionDurationSlow} ease-out`,
content: '""'
},
'&::before': {
top: expandIconHalfInner,
insetInlineEnd: expandIconLineOffset,
insetInlineStart: expandIconLineOffset,
height: lineWidth
},
'&::after': {
top: expandIconLineOffset,
bottom: expandIconLineOffset,
insetInlineStart: expandIconHalfInner,
width: lineWidth,
transform: 'rotate(90deg)'
},
// Motion effect
'&-collapsed::before': {
transform: 'rotate(-180deg)'
},
'&-collapsed::after': {
transform: 'rotate(0deg)'
},
'&-spaced': {
'&::before, &::after': {
display: 'none',
content: 'none'
},
background: 'transparent',
border: 0,
visibility: 'hidden'
}
},
[`${componentCls}-row-indent + ${componentCls}-row-expand-icon`]: {
marginTop: expandIconMarginTop,
marginInlineEnd: paddingXS
},
[`tr${componentCls}-expanded-row`]: {
'&, &:hover': {
'> th, > td': {
background: tableExpandedRowBg
}
},
// https://github.com/ant-design/ant-design/issues/25573
[`${antCls}-descriptions-view`]: {
display: 'flex',
table: {
flex: 'auto',
width: '100%'
}
}
},
// With fixed
[`${componentCls}-expanded-row-fixed`]: {
position: 'relative',
margin: `${(0, _cssinjs.unit)(calc(tablePaddingVertical).mul(-1).equal())} ${(0, _cssinjs.unit)(calc(tablePaddingHorizontal).mul(-1).equal())}`,
padding: `${(0, _cssinjs.unit)(tablePaddingVertical)} ${(0, _cssinjs.unit)(tablePaddingHorizontal)}`
}
}
};
};
var _default = exports.default = genExpandStyle;
+4
View File
@@ -0,0 +1,4 @@
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genFilterStyle: GenerateStyle<TableToken>;
export default genFilterStyle;
+159
View File
@@ -0,0 +1,159 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
var _style = require("../../style");
const genFilterStyle = token => {
const {
componentCls,
antCls,
iconCls,
tableFilterDropdownWidth,
tableFilterDropdownSearchWidth,
paddingXXS,
paddingXS,
colorText,
lineWidth,
lineType,
tableBorderColor,
headerIconColor,
fontSizeSM,
tablePaddingHorizontal,
borderRadius,
motionDurationSlow,
colorIcon,
colorPrimary,
tableHeaderFilterActiveBg,
colorTextDisabled,
tableFilterDropdownBg,
tableFilterDropdownHeight,
controlItemBgHover,
controlItemBgActive,
boxShadowSecondary,
filterDropdownMenuBg,
calc
} = token;
const dropdownPrefixCls = `${antCls}-dropdown`;
const tableFilterDropdownPrefixCls = `${componentCls}-filter-dropdown`;
const treePrefixCls = `${antCls}-tree`;
const tableBorder = `${(0, _cssinjs.unit)(lineWidth)} ${lineType} ${tableBorderColor}`;
return [{
[`${componentCls}-wrapper`]: {
[`${componentCls}-filter-column`]: {
display: 'flex',
justifyContent: 'space-between'
},
[`${componentCls}-filter-trigger`]: {
position: 'relative',
display: 'flex',
alignItems: 'center',
marginBlock: calc(paddingXXS).mul(-1).equal(),
marginInline: `${(0, _cssinjs.unit)(paddingXXS)} ${(0, _cssinjs.unit)(calc(tablePaddingHorizontal).div(2).mul(-1).equal())}`,
padding: `0 ${(0, _cssinjs.unit)(paddingXXS)}`,
color: headerIconColor,
fontSize: fontSizeSM,
borderRadius,
cursor: 'pointer',
transition: `all ${motionDurationSlow}`,
'&:hover': {
color: colorIcon,
background: tableHeaderFilterActiveBg
},
'&.active': {
color: colorPrimary
}
}
}
}, {
// Dropdown
[`${antCls}-dropdown`]: {
[tableFilterDropdownPrefixCls]: {
...(0, _style.resetComponent)(token),
minWidth: tableFilterDropdownWidth,
backgroundColor: tableFilterDropdownBg,
borderRadius,
boxShadow: boxShadowSecondary,
overflow: 'hidden',
// Reset menu
[`${dropdownPrefixCls}-menu`]: {
// https://github.com/ant-design/ant-design/issues/4916
// https://github.com/ant-design/ant-design/issues/19542
maxHeight: tableFilterDropdownHeight,
overflowX: 'hidden',
border: 0,
boxShadow: 'none',
borderRadius: 'unset',
backgroundColor: filterDropdownMenuBg,
'&:empty::after': {
display: 'block',
padding: `${(0, _cssinjs.unit)(paddingXS)} 0`,
color: colorTextDisabled,
fontSize: fontSizeSM,
textAlign: 'center',
content: '"Not Found"'
}
},
[`${tableFilterDropdownPrefixCls}-tree`]: {
paddingBlock: `${(0, _cssinjs.unit)(paddingXS)} 0`,
paddingInline: paddingXS,
[treePrefixCls]: {
padding: 0
},
[`${treePrefixCls}-treenode ${treePrefixCls}-node-content-wrapper:hover`]: {
backgroundColor: controlItemBgHover
},
[`${treePrefixCls}-treenode-checkbox-checked ${treePrefixCls}-node-content-wrapper`]: {
'&, &:hover': {
backgroundColor: controlItemBgActive
}
}
},
[`${tableFilterDropdownPrefixCls}-search`]: {
padding: paddingXS,
borderBottom: tableBorder,
'&-input': {
input: {
minWidth: tableFilterDropdownSearchWidth
},
[iconCls]: {
color: colorTextDisabled
}
}
},
[`${tableFilterDropdownPrefixCls}-checkall`]: {
width: '100%',
marginBottom: paddingXXS,
marginInlineStart: paddingXXS
},
// Operation
[`${tableFilterDropdownPrefixCls}-btns`]: {
display: 'flex',
justifyContent: 'space-between',
padding: `${(0, _cssinjs.unit)(calc(paddingXS).sub(lineWidth).equal())} ${(0, _cssinjs.unit)(paddingXS)}`,
overflow: 'hidden',
borderTop: tableBorder
}
}
}
},
// Dropdown Menu & SubMenu
{
// submenu of table filter dropdown
[`${antCls}-dropdown ${tableFilterDropdownPrefixCls}, ${tableFilterDropdownPrefixCls}-submenu`]: {
// Checkbox
[`${antCls}-checkbox-wrapper + span`]: {
paddingInlineStart: paddingXS,
color: colorText
},
'> ul': {
maxHeight: 'calc(100vh - 130px)',
overflowX: 'hidden',
overflowY: 'auto'
}
}
}];
};
var _default = exports.default = genFilterStyle;
+6
View File
@@ -0,0 +1,6 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
export declare function getShadowStyle({ colorSplit: shadowColor, }: Pick<TableToken, 'colorSplit'>): [left: CSSObject, right: CSSObject];
declare const genFixedStyle: GenerateStyle<TableToken, CSSObject>;
export default genFixedStyle;
+87
View File
@@ -0,0 +1,87 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.getShadowStyle = getShadowStyle;
function getShadowStyle({
colorSplit: shadowColor
}) {
const leftShadowStyle = {
boxShadow: `inset 10px 0 8px -8px ${shadowColor}`
};
const rightShadowStyle = {
boxShadow: `inset -10px 0 8px -8px ${shadowColor}`
};
return [leftShadowStyle, rightShadowStyle];
}
const genFixedStyle = token => {
const {
componentCls,
lineWidth,
motionDurationSlow,
zIndexTableFixed,
tableBg,
calc
} = token;
const cellCls = `${componentCls}-cell`;
const fixCellCls = `${cellCls}-fix`;
const sharedShadowStyle = {
position: 'absolute',
top: 0,
bottom: calc(lineWidth).mul(-1).equal(),
width: 30,
transition: `box-shadow ${motionDurationSlow}`,
content: '""',
pointerEvents: 'none'
};
const [leftShadowStyle, rightShadowStyle] = getShadowStyle(token);
// Follow style is magic of shadow which should not follow token:
return {
[`${componentCls}-wrapper`]: {
// ====================== Cell ======================
[`${cellCls}${fixCellCls}`]: {
position: 'sticky'
},
[fixCellCls]: {
zIndex: `calc(var(--z-offset-reverse) + ${zIndexTableFixed})`,
background: tableBg,
'&:after': sharedShadowStyle,
// Position
'&-start:after': {
insetInlineStart: '100%'
},
'&-end:after': {
insetInlineEnd: '100%'
},
// visible
'&-start-shadow-show:after': leftShadowStyle,
'&-end-shadow-show:after': rightShadowStyle
},
// =================== Container ====================
[`${componentCls}-container`]: {
position: 'relative',
'&:before, &:after': {
...sharedShadowStyle,
zIndex: `calc(var(--columns-count) * 2 + ${zIndexTableFixed} + 1)`
},
'&:before': {
insetInlineStart: 0
},
'&:after': {
insetInlineEnd: 0
}
},
[`${componentCls}-has-fix-start ${componentCls}-container:before`]: {
display: 'none'
},
[`${componentCls}-has-fix-end ${componentCls}-container:after`]: {
display: 'none'
},
[`${componentCls}-fix-start-shadow-show ${componentCls}-container:before`]: leftShadowStyle,
[`${componentCls}-fix-end-shadow-show ${componentCls}-container:after`]: rightShadowStyle
}
};
};
var _default = exports.default = genFixedStyle;
+201
View File
@@ -0,0 +1,201 @@
import type { FullToken, GetDefaultToken } from '../../theme/internal';
export interface ComponentToken {
/**
* @desc 表头背景
* @descEN Background of table header
*/
headerBg: string;
/**
* @desc 表头文字颜色
* @descEN Color of table header text
*/
headerColor: string;
/**
* @desc 表头排序激活态背景色
* @descEN Background color of table header when sorted
*/
headerSortActiveBg: string;
/**
* @desc 表头排序激活态悬浮背景色
* @descEN Background color of table header when sorted and hovered
*/
headerSortHoverBg: string;
/**
* @desc 表格排序列背景色
* @descEN Background color of table sorted column
*/
bodySortBg: string;
/**
* @desc 表格行悬浮背景色
* @descEN Background color of table hovered row
*/
rowHoverBg: string;
/**
* @desc 表格行选中背景色
* @descEN Background color of table selected row
*/
rowSelectedBg: string;
/**
* @desc 表格行选中悬浮背景色
* @descEN Background color of table selected row when hovered
*/
rowSelectedHoverBg: string;
/**
* @desc 表格行展开背景色
* @descEN Background color of table expanded row
*/
rowExpandedBg: string;
/**
* @desc 单元格纵向内间距
* @descEN Vertical padding of table cell
*/
cellPaddingBlock: number;
/**
* @desc 单元格横向内间距(默认大尺寸)
* @descEN Horizontal padding of table cell (large size by default)
*/
cellPaddingInline: number;
/**
* @desc 单元格纵向内间距(中等尺寸)
* @descEN Vertical padding of table cell (middle size)
*/
cellPaddingBlockMD: number;
/**
* @desc 单元格横向内间距(中等尺寸)
* @descEN Horizontal padding of table cell (middle size)
*/
cellPaddingInlineMD: number;
/**
* @desc 单元格纵向内间距(小尺寸)
* @descEN Vertical padding of table cell (small size)
*/
cellPaddingBlockSM: number;
/**
* @desc 单元格横向内间距(小尺寸)
* @descEN Horizontal padding of table cell (small size)
*/
cellPaddingInlineSM: number;
/**
* @desc 表格边框/分割线颜色
* @descEN Border color of table
*/
borderColor: string;
/**
* @desc 表头圆角
* @descEN Border radius of table header
*/
headerBorderRadius: number;
/**
* @desc 表格底部背景色
* @descEN Background of footer
*/
footerBg: string;
/**
* @desc 表格底部文字颜色
* @descEN Color of footer text
*/
footerColor: string;
/**
* @desc 单元格文字大小(默认大尺寸)
* @descEN Font size of table cell (large size by default)
*/
cellFontSize: number;
/**
* @desc 单元格文字大小(中等尺寸)
* @descEN Font size of table cell (middle size)
*/
cellFontSizeMD: number;
/**
* @desc 单元格文字大小(小尺寸)
* @descEN Font size of table cell (small size)
*/
cellFontSizeSM: number;
/**
* @desc 表头分割线颜色
* @descEN Split border color of table header
*/
headerSplitColor: string;
/**
* @desc 固定表头排序激活态背景色
* @descEN Background color of fixed table header when sorted
*/
fixedHeaderSortActiveBg: string;
/**
* @desc 表头过滤按钮悬浮背景色
* @descEN Background color of table header filter button when hovered
*/
headerFilterHoverBg: string;
/**
* @desc 过滤下拉菜单选项背景
* @descEN Background of filter dropdown menu item
*/
filterDropdownMenuBg: string;
/**
* @desc 过滤下拉菜单颜色
* @descEN Color of filter dropdown
*/
filterDropdownBg: string;
/**
* @desc 展开按钮背景色
* @descEN Background of expand button
*/
expandIconBg: string;
/**
* @desc 选择列宽度
* @descEN Width of selection column
*/
selectionColumnWidth: number | string;
/**
* @desc Sticky 模式下滚动条背景色
* @descEN Background of sticky scrollbar
*/
stickyScrollBarBg: string;
/**
* @desc Sticky 模式下滚动条圆角
* @descEN Border radius of sticky scrollbar
*/
stickyScrollBarBorderRadius: number;
}
export interface TableToken extends FullToken<'Table'> {
tableFontSize: number;
tableBg: string;
tableRadius: number;
tablePaddingHorizontal: number;
tablePaddingVertical: number;
tablePaddingHorizontalMiddle: number;
tablePaddingVerticalMiddle: number;
tablePaddingHorizontalSmall: number;
tablePaddingVerticalSmall: number;
tableBorderColor: string;
tableHeaderTextColor: string;
tableHeaderBg: string;
tableFooterTextColor: string;
tableFooterBg: string;
tableHeaderCellSplitColor: string;
tableHeaderSortBg: string;
tableHeaderSortHoverBg: string;
tableBodySortBg: string;
tableFixedHeaderSortActiveBg: string;
tableHeaderFilterActiveBg: string;
tableFilterDropdownBg: string;
tableFilterDropdownHeight: number | string;
tableRowHoverBg: string;
tableSelectedRowBg: string;
tableSelectedRowHoverBg: string;
tableFontSizeMiddle: number;
tableFontSizeSmall: number;
tableSelectionColumnWidth: number | string;
tableExpandIconBg: string;
tableExpandColumnWidth: number | string;
tableExpandedRowBg: string;
tableFilterDropdownWidth: number;
tableFilterDropdownSearchWidth: number;
zIndexTableFixed: number;
tableScrollThumbSize: number;
tableScrollThumbBg: string;
tableScrollThumbBgHover: string;
tableScrollBg: string;
}
export declare const prepareComponentToken: GetDefaultToken<'Table'>;
declare const _default: (prefixCls: string, rootCls?: string) => readonly [string, string];
export default _default;
+333
View File
@@ -0,0 +1,333 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.prepareComponentToken = exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
var _fastColor = require("@ant-design/fast-color");
var _style = require("../../style");
var _internal = require("../../theme/internal");
var _bordered = _interopRequireDefault(require("./bordered"));
var _ellipsis = _interopRequireDefault(require("./ellipsis"));
var _empty = _interopRequireDefault(require("./empty"));
var _expand = _interopRequireDefault(require("./expand"));
var _filter = _interopRequireDefault(require("./filter"));
var _fixed = _interopRequireDefault(require("./fixed"));
var _pagination = _interopRequireDefault(require("./pagination"));
var _radius = _interopRequireDefault(require("./radius"));
var _rtl = _interopRequireDefault(require("./rtl"));
var _selection = _interopRequireDefault(require("./selection"));
var _size = _interopRequireDefault(require("./size"));
var _sorter = _interopRequireDefault(require("./sorter"));
var _sticky = _interopRequireDefault(require("./sticky"));
var _summary = _interopRequireDefault(require("./summary"));
var _virtual = _interopRequireDefault(require("./virtual"));
const genTableStyle = token => {
const {
componentCls,
fontWeightStrong,
tablePaddingVertical,
tablePaddingHorizontal,
tableExpandColumnWidth,
lineWidth,
lineType,
tableBorderColor,
tableFontSize,
tableBg,
tableRadius,
tableHeaderTextColor,
motionDurationMid,
tableHeaderBg,
tableHeaderCellSplitColor,
tableFooterTextColor,
tableFooterBg,
calc
} = token;
const tableBorder = `${(0, _cssinjs.unit)(lineWidth)} ${lineType} ${tableBorderColor}`;
return {
[`${componentCls}-wrapper`]: {
clear: 'both',
maxWidth: '100%',
// fix https://github.com/ant-design/ant-design/issues/46177
['--rc-virtual-list-scrollbar-bg']: token.tableScrollBg,
...(0, _style.clearFix)(),
[componentCls]: {
...(0, _style.resetComponent)(token),
fontSize: tableFontSize,
background: tableBg,
borderRadius: `${(0, _cssinjs.unit)(tableRadius)} ${(0, _cssinjs.unit)(tableRadius)} 0 0`,
// https://github.com/ant-design/ant-design/issues/47486
scrollbarColor: `${token.tableScrollThumbBg} ${token.tableScrollBg}`
},
// https://github.com/ant-design/ant-design/issues/17611
table: {
width: '100%',
textAlign: 'start',
borderRadius: `${(0, _cssinjs.unit)(tableRadius)} ${(0, _cssinjs.unit)(tableRadius)} 0 0`,
borderCollapse: 'separate',
borderSpacing: 0
},
// ============================= Cell ==============================
[`
${componentCls}-cell,
${componentCls}-thead > tr > th,
${componentCls}-tbody > tr > th,
${componentCls}-tbody > tr > td,
tfoot > tr > th,
tfoot > tr > td
`]: {
position: 'relative',
padding: `${(0, _cssinjs.unit)(tablePaddingVertical)} ${(0, _cssinjs.unit)(tablePaddingHorizontal)}`,
overflowWrap: 'break-word'
},
// ============================ Title =============================
[`${componentCls}-title`]: {
padding: `${(0, _cssinjs.unit)(tablePaddingVertical)} ${(0, _cssinjs.unit)(tablePaddingHorizontal)}`
},
// ============================ Header ============================
[`${componentCls}-thead`]: {
'> tr > th, > tr > td': {
position: 'relative',
color: tableHeaderTextColor,
fontWeight: fontWeightStrong,
textAlign: 'start',
background: tableHeaderBg,
borderBottom: tableBorder,
transition: `background-color ${motionDurationMid} ease`,
"&[colspan]:not([colspan='1'])": {
textAlign: 'center'
},
[`&:not(:last-child):not(${componentCls}-selection-column):not(${componentCls}-row-expand-icon-cell):not([colspan])::before`]: {
position: 'absolute',
top: '50%',
insetInlineEnd: 0,
width: 1,
height: '1.6em',
backgroundColor: tableHeaderCellSplitColor,
transform: 'translateY(-50%)',
transition: `background-color ${motionDurationMid}`,
content: '""'
}
},
'> tr:not(:last-child) > th[colspan]': {
borderBottom: 0
}
},
// ============================ Body ============================
[`${componentCls}-tbody`]: {
'> tr': {
'> th, > td': {
borderBottom: tableBorder,
transition: [`background-color`, `border-color`].map(prop => `${prop} ${motionDurationMid}`).join(', '),
// ========================= Nest Table ===========================
[`
> ${componentCls}-wrapper:only-child,
> ${componentCls}-expanded-row-fixed > ${componentCls}-wrapper:only-child
`]: {
[componentCls]: {
marginBlock: (0, _cssinjs.unit)(calc(tablePaddingVertical).mul(-1).equal()),
marginInline: `${(0, _cssinjs.unit)(calc(tableExpandColumnWidth).sub(tablePaddingHorizontal).equal())}
${(0, _cssinjs.unit)(calc(tablePaddingHorizontal).mul(-1).equal())}`,
[`${componentCls}-tbody > tr:last-child > td`]: {
borderBottomWidth: 0,
'&:first-child, &:last-child': {
borderRadius: 0
}
}
}
}
},
'> th': {
position: 'relative',
color: tableHeaderTextColor,
fontWeight: fontWeightStrong,
textAlign: 'start',
background: tableHeaderBg,
borderBottom: tableBorder,
transition: `background-color ${motionDurationMid} ease`
},
// measure cell styles
[`& > ${componentCls}-measure-cell`]: {
paddingBlock: `0 !important`,
borderBlock: `0 !important`,
[`${componentCls}-measure-cell-content`]: {
height: 0,
overflow: 'hidden',
pointerEvents: 'none'
}
}
}
},
// ============================ Footer ============================
[`${componentCls}-footer`]: {
padding: `${(0, _cssinjs.unit)(tablePaddingVertical)} ${(0, _cssinjs.unit)(tablePaddingHorizontal)}`,
color: tableFooterTextColor,
background: tableFooterBg
}
}
};
};
const prepareComponentToken = token => {
const {
colorFillAlter,
colorBgContainer,
colorTextHeading,
colorFillSecondary,
colorFillContent,
controlItemBgActive,
controlItemBgActiveHover,
padding,
paddingSM,
paddingXS,
colorBorderSecondary,
borderRadiusLG,
controlHeight,
colorTextPlaceholder,
fontSize,
fontSizeSM,
lineHeight,
lineWidth,
colorIcon,
colorIconHover,
opacityLoading,
controlInteractiveSize
} = token;
const colorFillSecondarySolid = new _fastColor.FastColor(colorFillSecondary).onBackground(colorBgContainer).toHexString();
const colorFillContentSolid = new _fastColor.FastColor(colorFillContent).onBackground(colorBgContainer).toHexString();
const colorFillAlterSolid = new _fastColor.FastColor(colorFillAlter).onBackground(colorBgContainer).toHexString();
const baseColorAction = new _fastColor.FastColor(colorIcon);
const baseColorActionHover = new _fastColor.FastColor(colorIconHover);
const expandIconHalfInner = controlInteractiveSize / 2 - lineWidth;
const expandIconSize = expandIconHalfInner * 2 + lineWidth * 3;
return {
headerBg: colorFillAlterSolid,
headerColor: colorTextHeading,
headerSortActiveBg: colorFillSecondarySolid,
headerSortHoverBg: colorFillContentSolid,
bodySortBg: colorFillAlterSolid,
rowHoverBg: colorFillAlterSolid,
rowSelectedBg: controlItemBgActive,
rowSelectedHoverBg: controlItemBgActiveHover,
rowExpandedBg: colorFillAlter,
cellPaddingBlock: padding,
cellPaddingInline: padding,
cellPaddingBlockMD: paddingSM,
cellPaddingInlineMD: paddingXS,
cellPaddingBlockSM: paddingXS,
cellPaddingInlineSM: paddingXS,
borderColor: colorBorderSecondary,
headerBorderRadius: borderRadiusLG,
footerBg: colorFillAlterSolid,
footerColor: colorTextHeading,
cellFontSize: fontSize,
cellFontSizeMD: fontSize,
cellFontSizeSM: fontSize,
headerSplitColor: colorBorderSecondary,
fixedHeaderSortActiveBg: colorFillSecondarySolid,
headerFilterHoverBg: colorFillContent,
filterDropdownMenuBg: colorBgContainer,
filterDropdownBg: colorBgContainer,
expandIconBg: colorBgContainer,
selectionColumnWidth: controlHeight,
stickyScrollBarBg: colorTextPlaceholder,
stickyScrollBarBorderRadius: 100,
expandIconMarginTop: (fontSize * lineHeight - lineWidth * 3) / 2 - Math.ceil((fontSizeSM * 1.4 - lineWidth * 3) / 2),
headerIconColor: baseColorAction.clone().setA(baseColorAction.a * opacityLoading).toRgbString(),
headerIconHoverColor: baseColorActionHover.clone().setA(baseColorActionHover.a * opacityLoading).toRgbString(),
expandIconHalfInner,
expandIconSize,
expandIconScale: controlInteractiveSize / expandIconSize
};
};
exports.prepareComponentToken = prepareComponentToken;
const zIndexTableFixed = 2;
// ============================== Export ==============================
var _default = exports.default = (0, _internal.genStyleHooks)('Table', token => {
const {
colorTextHeading,
colorSplit,
colorBgContainer,
controlInteractiveSize: checkboxSize,
headerBg,
headerColor,
headerSortActiveBg,
headerSortHoverBg,
bodySortBg,
rowHoverBg,
rowSelectedBg,
rowSelectedHoverBg,
rowExpandedBg,
cellPaddingBlock,
cellPaddingInline,
cellPaddingBlockMD,
cellPaddingInlineMD,
cellPaddingBlockSM,
cellPaddingInlineSM,
borderColor,
footerBg,
footerColor,
headerBorderRadius,
cellFontSize,
cellFontSizeMD,
cellFontSizeSM,
headerSplitColor,
fixedHeaderSortActiveBg,
headerFilterHoverBg,
filterDropdownBg,
expandIconBg,
selectionColumnWidth,
stickyScrollBarBg,
calc
} = token;
const tableToken = (0, _internal.mergeToken)(token, {
tableFontSize: cellFontSize,
tableBg: colorBgContainer,
tableRadius: headerBorderRadius,
tablePaddingVertical: cellPaddingBlock,
tablePaddingHorizontal: cellPaddingInline,
tablePaddingVerticalMiddle: cellPaddingBlockMD,
tablePaddingHorizontalMiddle: cellPaddingInlineMD,
tablePaddingVerticalSmall: cellPaddingBlockSM,
tablePaddingHorizontalSmall: cellPaddingInlineSM,
tableBorderColor: borderColor,
tableHeaderTextColor: headerColor,
tableHeaderBg: headerBg,
tableFooterTextColor: footerColor,
tableFooterBg: footerBg,
tableHeaderCellSplitColor: headerSplitColor,
tableHeaderSortBg: headerSortActiveBg,
tableHeaderSortHoverBg: headerSortHoverBg,
tableBodySortBg: bodySortBg,
tableFixedHeaderSortActiveBg: fixedHeaderSortActiveBg,
tableHeaderFilterActiveBg: headerFilterHoverBg,
tableFilterDropdownBg: filterDropdownBg,
tableRowHoverBg: rowHoverBg,
tableSelectedRowBg: rowSelectedBg,
tableSelectedRowHoverBg: rowSelectedHoverBg,
zIndexTableFixed,
tableFontSizeMiddle: cellFontSizeMD,
tableFontSizeSmall: cellFontSizeSM,
tableSelectionColumnWidth: selectionColumnWidth,
tableExpandIconBg: expandIconBg,
tableExpandColumnWidth: calc(checkboxSize).add(calc(token.padding).mul(2)).equal(),
tableExpandedRowBg: rowExpandedBg,
// Dropdown
tableFilterDropdownWidth: 120,
tableFilterDropdownHeight: 264,
tableFilterDropdownSearchWidth: 140,
// Virtual Scroll Bar
tableScrollThumbSize: 8,
// Mac scroll bar size
tableScrollThumbBg: stickyScrollBarBg,
tableScrollThumbBgHover: colorTextHeading,
tableScrollBg: colorSplit
});
return [genTableStyle(tableToken), (0, _pagination.default)(tableToken), (0, _summary.default)(tableToken), (0, _sorter.default)(tableToken), (0, _filter.default)(tableToken), (0, _bordered.default)(tableToken), (0, _radius.default)(tableToken), (0, _expand.default)(tableToken), (0, _summary.default)(tableToken), (0, _empty.default)(tableToken), (0, _selection.default)(tableToken), (0, _fixed.default)(tableToken), (0, _sticky.default)(tableToken), (0, _ellipsis.default)(tableToken), (0, _size.default)(tableToken), (0, _rtl.default)(tableToken), (0, _virtual.default)(tableToken)];
}, prepareComponentToken, {
resetFont: false,
unitless: {
expandIconScale: true
}
});
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genPaginationStyle: GenerateStyle<TableToken, CSSObject>;
export default genPaginationStyle;
+40
View File
@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
const genPaginationStyle = token => {
const {
componentCls,
antCls,
margin
} = token;
return {
[`${componentCls}-wrapper`]: {
// ========================== Pagination ==========================
[`${componentCls}-pagination${antCls}-pagination`]: {
margin: `${(0, _cssinjs.unit)(margin)} 0`
},
[`${componentCls}-pagination`]: {
display: 'flex',
flexWrap: 'wrap',
rowGap: token.paddingXS,
'> *': {
flex: 'none'
},
'&-start': {
justifyContent: 'flex-start'
},
'&-center': {
justifyContent: 'center'
},
'&-end': {
justifyContent: 'flex-end'
}
}
}
};
};
var _default = exports.default = genPaginationStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genRadiusStyle: GenerateStyle<TableToken, CSSObject>;
export default genRadiusStyle;
+62
View File
@@ -0,0 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
const genRadiusStyle = token => {
const {
componentCls,
tableRadius
} = token;
return {
[`${componentCls}-wrapper`]: {
[componentCls]: {
// https://github.com/ant-design/ant-design/issues/39115#issuecomment-1362314574
[`${componentCls}-title, ${componentCls}-header`]: {
borderRadius: `${(0, _cssinjs.unit)(tableRadius)} ${(0, _cssinjs.unit)(tableRadius)} 0 0`
},
[`${componentCls}-title + ${componentCls}-container`]: {
borderStartStartRadius: 0,
borderStartEndRadius: 0,
// https://github.com/ant-design/ant-design/issues/41975
[`${componentCls}-header, table`]: {
borderRadius: 0
},
'table > thead > tr:first-child': {
'th:first-child, th:last-child, td:first-child, td:last-child': {
borderRadius: 0
}
}
},
'&-container': {
borderStartStartRadius: tableRadius,
borderStartEndRadius: tableRadius,
'&::before': {
borderStartStartRadius: tableRadius
},
'&::after': {
borderStartEndRadius: tableRadius
},
[`> ${componentCls}-content`]: {
borderStartStartRadius: tableRadius,
borderStartEndRadius: tableRadius
},
'table > thead > tr:first-child': {
'> *:first-child': {
borderStartStartRadius: tableRadius
},
'> *:last-child': {
borderStartEndRadius: tableRadius
}
}
},
'&-footer': {
borderRadius: `0 0 ${(0, _cssinjs.unit)(tableRadius)} ${(0, _cssinjs.unit)(tableRadius)}`
}
}
}
};
};
var _default = exports.default = genRadiusStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genStyle: GenerateStyle<TableToken, CSSObject>;
export default genStyle;
+47
View File
@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _fixed = require("./fixed");
const genStyle = token => {
const {
componentCls
} = token;
const [leftShadowStyle, rightShadowStyle] = (0, _fixed.getShadowStyle)(token);
return {
[`${componentCls}-wrapper-rtl`]: {
direction: 'rtl',
table: {
direction: 'rtl'
},
[`${componentCls}-row-expand-icon`]: {
float: 'right',
'&::after': {
transform: 'rotate(-90deg)'
},
'&-collapsed::before': {
transform: 'rotate(180deg)'
},
'&-collapsed::after': {
transform: 'rotate(0deg)'
}
},
// ====================== Cell ======================
[`${componentCls}-cell-fix`]: {
'&-start-shadow-show:after': rightShadowStyle,
'&-end-shadow-show:after': leftShadowStyle
},
// =================== Container ====================
[`${componentCls}-container`]: {
[`${componentCls}-row-indent`]: {
float: 'right'
}
},
[`${componentCls}-fix-start-shadow-show ${componentCls}-container:before`]: rightShadowStyle,
[`${componentCls}-fix-end-shadow-show ${componentCls}-container:after`]: leftShadowStyle
}
};
};
var _default = exports.default = genStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genSelectionStyle: GenerateStyle<TableToken, CSSObject>;
export default genSelectionStyle;
+101
View File
@@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
const genSelectionStyle = token => {
const {
componentCls,
antCls,
iconCls,
fontSizeIcon,
padding,
paddingXS,
headerIconColor,
headerIconHoverColor,
tableSelectionColumnWidth,
tableSelectedRowBg,
tableSelectedRowHoverBg,
tableRowHoverBg,
tablePaddingHorizontal,
calc
} = token;
return {
[`${componentCls}-wrapper`]: {
// ========================== Selections ==========================
[`${componentCls}-selection-col`]: {
width: tableSelectionColumnWidth,
[`&${componentCls}-selection-col-with-dropdown`]: {
width: calc(tableSelectionColumnWidth).add(fontSizeIcon).add(calc(padding).div(4)).equal()
}
},
[`${componentCls}-bordered ${componentCls}-selection-col`]: {
width: calc(tableSelectionColumnWidth).add(calc(paddingXS).mul(2)).equal(),
[`&${componentCls}-selection-col-with-dropdown`]: {
width: calc(tableSelectionColumnWidth).add(fontSizeIcon).add(calc(padding).div(4)).add(calc(paddingXS).mul(2)).equal()
}
},
[`
table tr th${componentCls}-selection-column,
table tr td${componentCls}-selection-column,
${componentCls}-selection-column
`]: {
paddingInlineEnd: token.paddingXS,
paddingInlineStart: token.paddingXS,
textAlign: 'center',
[`${antCls}-radio-wrapper`]: {
marginInlineEnd: 0
}
},
[`table tr th${componentCls}-selection-column${componentCls}-cell-fix-left`]: {
zIndex: calc(token.zIndexTableFixed).add(1).equal({
unit: false
})
},
[`table tr th${componentCls}-selection-column::after`]: {
backgroundColor: 'transparent !important'
},
[`${componentCls}-selection`]: {
position: 'relative',
display: 'inline-flex',
flexDirection: 'column'
},
[`${componentCls}-selection-extra`]: {
position: 'absolute',
top: 0,
zIndex: 1,
cursor: 'pointer',
transition: `all ${token.motionDurationSlow}`,
marginInlineStart: '100%',
paddingInlineStart: (0, _cssinjs.unit)(calc(tablePaddingHorizontal).div(4).equal()),
[iconCls]: {
color: headerIconColor,
fontSize: fontSizeIcon,
verticalAlign: 'baseline',
'&:hover': {
color: headerIconHoverColor
}
}
},
// ============================= Rows =============================
[`${componentCls}-tbody`]: {
[`${componentCls}-row`]: {
[`&${componentCls}-row-selected`]: {
[`> ${componentCls}-cell`]: {
background: tableSelectedRowBg,
'&-row-hover': {
background: tableSelectedRowHoverBg
}
}
},
[`> ${componentCls}-cell-row-hover`]: {
background: tableRowHoverBg
}
}
}
}
};
};
var _default = exports.default = genSelectionStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genSizeStyle: GenerateStyle<TableToken, CSSObject>;
export default genSizeStyle;
+55
View File
@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
const genSizeStyle = token => {
const {
componentCls,
tableExpandColumnWidth,
calc
} = token;
const getSizeStyle = (size, paddingVertical, paddingHorizontal, fontSize) => ({
[`${componentCls}${componentCls}-${size}`]: {
fontSize,
[`
${componentCls}-title,
${componentCls}-footer,
${componentCls}-cell,
${componentCls}-thead > tr > th,
${componentCls}-tbody > tr > th,
${componentCls}-tbody > tr > td,
tfoot > tr > th,
tfoot > tr > td
`]: {
padding: `${(0, _cssinjs.unit)(paddingVertical)} ${(0, _cssinjs.unit)(paddingHorizontal)}`
},
[`${componentCls}-filter-trigger`]: {
marginInlineEnd: (0, _cssinjs.unit)(calc(paddingHorizontal).div(2).mul(-1).equal())
},
[`${componentCls}-expanded-row-fixed`]: {
margin: `${(0, _cssinjs.unit)(calc(paddingVertical).mul(-1).equal())} ${(0, _cssinjs.unit)(calc(paddingHorizontal).mul(-1).equal())}`
},
[`${componentCls}-tbody`]: {
// ========================= Nest Table ===========================
[`${componentCls}-wrapper:only-child ${componentCls}`]: {
marginBlock: (0, _cssinjs.unit)(calc(paddingVertical).mul(-1).equal()),
marginInline: `${(0, _cssinjs.unit)(calc(tableExpandColumnWidth).sub(paddingHorizontal).equal())} ${(0, _cssinjs.unit)(calc(paddingHorizontal).mul(-1).equal())}`
}
},
// https://github.com/ant-design/ant-design/issues/35167
[`${componentCls}-selection-extra`]: {
paddingInlineStart: (0, _cssinjs.unit)(calc(paddingHorizontal).div(4).equal())
}
}
});
return {
[`${componentCls}-wrapper`]: {
...getSizeStyle('medium', token.tablePaddingVerticalMiddle, token.tablePaddingHorizontalMiddle, token.tableFontSizeMiddle),
...getSizeStyle('small', token.tablePaddingVerticalSmall, token.tablePaddingHorizontalSmall, token.tableFontSizeSmall)
}
};
};
var _default = exports.default = genSizeStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genSorterStyle: GenerateStyle<TableToken, CSSObject>;
export default genSorterStyle;
+99
View File
@@ -0,0 +1,99 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
const genSorterStyle = token => {
const {
componentCls,
marginXXS,
fontSizeIcon,
headerIconColor,
headerIconHoverColor
} = token;
return {
[`${componentCls}-wrapper`]: {
[`${componentCls}-thead th${componentCls}-column-has-sorters`]: {
outline: 'none',
cursor: 'pointer',
// why left 0s? Avoid column header move with transition when left is changed
// https://github.com/ant-design/ant-design/issues/50588
transition: `all ${token.motionDurationSlow}, left 0s`,
'&:hover': {
background: token.tableHeaderSortHoverBg,
'&::before': {
backgroundColor: 'transparent !important'
}
},
'&:focus-visible': {
color: token.colorPrimary
},
// https://github.com/ant-design/ant-design/issues/30969
[`
&${componentCls}-cell-fix-left:hover,
&${componentCls}-cell-fix-right:hover
`]: {
background: token.tableFixedHeaderSortActiveBg
}
},
[`${componentCls}-thead th${componentCls}-column-sort`]: {
background: token.tableHeaderSortBg,
'&::before': {
backgroundColor: 'transparent !important'
}
},
[`td${componentCls}-column-sort`]: {
background: token.tableBodySortBg
},
[`${componentCls}-column-title`]: {
position: 'relative',
zIndex: 1,
flex: 1,
minWidth: 0
},
[`${componentCls}-column-sorters`]: {
display: 'flex',
flex: 'auto',
alignItems: 'center',
justifyContent: 'space-between',
'&::after': {
position: 'absolute',
inset: 0,
width: '100%',
height: '100%',
content: '""'
}
},
[`${componentCls}-column-sorters-tooltip-target-sorter`]: {
'&::after': {
content: 'none'
}
},
[`${componentCls}-column-sorter`]: {
marginInlineStart: marginXXS,
color: headerIconColor,
fontSize: 0,
transition: `color ${token.motionDurationSlow}`,
'&-inner': {
display: 'inline-flex',
flexDirection: 'column',
alignItems: 'center'
},
'&-up, &-down': {
fontSize: fontSizeIcon,
'&.active': {
color: token.colorPrimary
}
},
[`${componentCls}-column-sorter-up + ${componentCls}-column-sorter-down`]: {
marginTop: '-0.3em'
}
},
[`${componentCls}-column-sorters:hover ${componentCls}-column-sorter`]: {
color: headerIconHoverColor
}
}
};
};
var _default = exports.default = genSorterStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genStickyStyle: GenerateStyle<TableToken, CSSObject>;
export default genStickyStyle;
+61
View File
@@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
const genStickyStyle = token => {
const {
componentCls,
opacityLoading,
tableScrollThumbBg,
tableScrollThumbBgHover,
tableScrollThumbSize,
tableScrollBg,
stickyScrollBarBorderRadius,
lineWidth,
lineType,
tableBorderColor,
zIndexTableFixed
} = token;
const tableBorder = `${(0, _cssinjs.unit)(lineWidth)} ${lineType} ${tableBorderColor}`;
return {
[`${componentCls}-wrapper`]: {
[`${componentCls}-sticky`]: {
'&-holder': {
position: 'sticky',
zIndex: `calc(var(--columns-count) * 2 + ${zIndexTableFixed} + 1)`,
background: token.colorBgContainer
},
'&-scroll': {
position: 'sticky',
bottom: 0,
height: `${(0, _cssinjs.unit)(tableScrollThumbSize)} !important`,
zIndex: `calc(var(--columns-count) * 2 + ${zIndexTableFixed} + 1)`,
display: 'flex',
alignItems: 'center',
background: tableScrollBg,
borderTop: tableBorder,
opacity: opacityLoading,
'&:hover': {
transformOrigin: 'center bottom'
},
// fake scrollbar style of sticky
'&-bar': {
height: tableScrollThumbSize,
backgroundColor: tableScrollThumbBg,
borderRadius: stickyScrollBarBorderRadius,
transition: `all ${token.motionDurationSlow}, transform 0s`,
position: 'absolute',
bottom: 0,
'&:hover, &-active': {
backgroundColor: tableScrollThumbBgHover
}
}
}
}
}
};
};
var _default = exports.default = genStickyStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genSummaryStyle: GenerateStyle<TableToken, CSSObject>;
export default genSummaryStyle;
+34
View File
@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
const genSummaryStyle = token => {
const {
componentCls,
lineWidth,
tableBorderColor,
calc
} = token;
const tableBorder = `${(0, _cssinjs.unit)(lineWidth)} ${token.lineType} ${tableBorderColor}`;
return {
[`${componentCls}-wrapper`]: {
[`${componentCls}-summary`]: {
position: 'relative',
zIndex: token.zIndexTableFixed,
background: token.tableBg,
'> tr': {
'> th, > td': {
borderBottom: tableBorder
}
}
},
[`div${componentCls}-summary`]: {
boxShadow: `0 ${(0, _cssinjs.unit)(calc(lineWidth).mul(-1).equal())} 0 ${tableBorderColor}`
}
}
};
};
var _default = exports.default = genSummaryStyle;
+5
View File
@@ -0,0 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { GenerateStyle } from '../../theme/internal';
import type { TableToken } from './index';
declare const genVirtualStyle: GenerateStyle<TableToken, CSSObject>;
export default genVirtualStyle;
+79
View File
@@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _cssinjs = require("@ant-design/cssinjs");
const genVirtualStyle = token => {
const {
componentCls,
motionDurationMid,
lineWidth,
lineType,
tableBorderColor,
calc
} = token;
const tableBorder = `${(0, _cssinjs.unit)(lineWidth)} ${lineType} ${tableBorderColor}`;
const rowCellCls = `${componentCls}-expanded-row-cell`;
return {
[`${componentCls}-wrapper`]: {
// ========================== Row ==========================
[`${componentCls}-tbody-virtual`]: {
[`${componentCls}-tbody-virtual-holder-inner`]: {
[`
& > ${componentCls}-row,
& > div:not(${componentCls}-row) > ${componentCls}-row
`]: {
display: 'flex',
boxSizing: 'border-box',
width: '100%'
}
},
[`${componentCls}-cell`]: {
borderBottom: tableBorder,
transition: `background-color ${motionDurationMid}`
},
[`${componentCls}-expanded-row`]: {
[`${rowCellCls}${rowCellCls}-fixed`]: {
position: 'sticky',
insetInlineStart: 0,
overflow: 'hidden',
width: `calc(var(--virtual-width) - ${(0, _cssinjs.unit)(lineWidth)})`,
borderInlineEnd: 'none'
}
}
},
// ======================== Border =========================
[`${componentCls}-bordered`]: {
[`${componentCls}-tbody-virtual`]: {
'&:after': {
content: '""',
insetInline: 0,
bottom: 0,
borderBottom: tableBorder,
position: 'absolute'
},
[`${componentCls}-cell`]: {
borderInlineEnd: tableBorder,
[`&${componentCls}-cell-fix-right-first:before`]: {
content: '""',
position: 'absolute',
insetBlock: 0,
insetInlineStart: calc(lineWidth).mul(-1).equal(),
borderInlineStart: tableBorder
}
}
},
// Empty placeholder
[`&${componentCls}-virtual`]: {
[`${componentCls}-placeholder ${componentCls}-cell`]: {
borderInlineEnd: tableBorder,
borderBottom: tableBorder
}
}
}
}
};
};
var _default = exports.default = genVirtualStyle;
+13
View File
@@ -0,0 +1,13 @@
import type { AnyObject } from '../_util/type';
import type { ColumnTitle, ColumnTitleProps, ColumnType } from './interface';
export declare const getColumnKey: <RecordType extends AnyObject = AnyObject>(column: ColumnType<RecordType>, defaultKey: string) => string | number | bigint;
export declare function getColumnPos(index: number, pos?: string): string;
export declare const renderColumnTitle: <RecordType extends AnyObject = AnyObject>(title: ColumnTitle<RecordType>, props: ColumnTitleProps<RecordType>) => import("react").ReactNode;
/**
* Safe get column title
*
* Should filter [object Object]
*
* @param title
*/
export declare const safeColumnTitle: <RecordType extends AnyObject = AnyObject>(title: ColumnTitle<RecordType>, props: ColumnTitleProps<RecordType>) => import("react").ReactNode;
+44
View File
@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getColumnKey = void 0;
exports.getColumnPos = getColumnPos;
exports.safeColumnTitle = exports.renderColumnTitle = void 0;
var _is = require("../_util/is");
const getColumnKey = (column, defaultKey) => {
if ('key' in column && (0, _is.isNonNullable)(column.key)) {
return column.key;
}
if (column.dataIndex) {
return Array.isArray(column.dataIndex) ? column.dataIndex.join('.') : column.dataIndex;
}
return defaultKey;
};
exports.getColumnKey = getColumnKey;
function getColumnPos(index, pos) {
return pos ? `${pos}-${index}` : `${index}`;
}
const renderColumnTitle = (title, props) => {
if (typeof title === 'function') {
return title(props);
}
return title;
};
/**
* Safe get column title
*
* Should filter [object Object]
*
* @param title
*/
exports.renderColumnTitle = renderColumnTitle;
const safeColumnTitle = (title, props) => {
const res = renderColumnTitle(title, props);
if (Object.prototype.toString.call(res) === '[object Object]') {
return '';
}
return res;
};
exports.safeColumnTitle = safeColumnTitle;