Advanced data table and list components with search, filtering, editing, drag-and-drop sorting, and comprehensive data management capabilities built on Ant Design's table foundation.
Advanced table component with built-in search, filtering, pagination, and data management capabilities.
/**
* Enhanced data table with advanced features
* @param props - ProTable configuration props
* @returns JSX.Element
*/
function ProTable<T = any>(props: ProTableProps<T>): JSX.Element;
interface ProTableProps<T = any> {
/** Table columns configuration */
columns: ProColumns<T>;
/** Data request function for remote data loading */
request?: (params: ParamsType & {
pageSize?: number;
current?: number;
keyword?: string;
}) => Promise<RequestData<T>>;
/** Static data source */
dataSource?: T[];
/** Table loading state */
loading?: boolean;
/** Row key field name */
rowKey?: string | ((record: T) => string);
/** Search form configuration */
search?: SearchConfig | false;
/** Pagination configuration */
pagination?: PaginationProps | false;
/** Toolbar render function */
toolBarRender?: (action: ActionType, rows: { selectedRowKeys?: Key[]; selectedRows?: T[] }) => React.ReactNode[];
/** Table header title */
headerTitle?: React.ReactNode;
/** Table options configuration */
options?: OptionsType | false;
/** Row selection configuration */
rowSelection?: TableRowSelection<T> | false;
/** Table size */
size?: SizeType;
/** Scroll configuration */
scroll?: { x?: string | number; y?: string | number };
/** Table properties passed to Ant Design Table */
tableProps?: TableProps<T>;
/** Form properties for search form */
form?: FormProps;
/** Date formatting */
dateFormatter?: 'string' | 'number' | false;
/** Column state management */
columnEmptyText?: string;
/** Table style */
tableStyle?: React.CSSProperties;
/** Table class name */
tableClassName?: string;
/** Card container properties */
cardBordered?: boolean;
/** Ghost mode styling */
ghost?: boolean;
}
interface RequestData<T> {
/** Table data array */
data: T[];
/** Request success status */
success: boolean;
/** Total number of records */
total?: number;
/** Current page number */
current?: number;
/** Page size */
pageSize?: number;
}
interface ActionType {
/** Reload table data */
reload: () => void;
/** Reload and reset to first page */
reloadAndRest: () => void;
/** Reset search form */
reset: () => void;
/** Clear selected rows */
clearSelected?: () => void;
/** Get current data source */
getDataSource?: () => T[];
/** Get loading state */
getLoading?: () => boolean;
}
type ProColumns<T> = ProColumnType<T>[];
interface ProColumnType<T> extends Omit<ColumnType<T>, 'render'> {
/** Field value type for automatic rendering */
valueType?: ProFieldValueType;
/** Value enumeration for select-type fields */
valueEnum?: ProSchemaValueEnumType;
/** Custom render function */
render?: (text: any, record: T, index: number, action: ActionType) => React.ReactNode;
/** Hide column in search form */
hideInSearch?: boolean;
/** Hide column in table */
hideInTable?: boolean;
/** Hide column in form */
hideInForm?: boolean;
/** Column display order */
order?: number;
/** Field properties for form inputs */
fieldProps?: any;
/** Form item properties */
formItemProps?: FormItemProps;
/** Search form configuration */
search?: false | SearchTransformKeyFn | { transform: SearchTransformKeyFn };
/** Column group configuration */
children?: ProColumnType<T>[];
/** Disable column in settings */
disable?: boolean;
/** Column tooltip */
tooltip?: string;
/** Copy functionality */
copyable?: boolean;
/** Ellipsis configuration */
ellipsis?: boolean | { showTitle: boolean };
}Usage Examples:
import { ProTable, ActionType } from "@ant-design/pro-components";
import { Button, Space } from "antd";
// Basic ProTable usage
const UserTable = () => {
const columns: ProColumns<User> = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
valueType: 'text',
copyable: true,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
valueType: 'digit',
hideInSearch: true,
},
{
title: 'Email',
dataIndex: 'email',
key: 'email',
valueType: 'text',
copyable: true,
},
{
title: 'Status',
dataIndex: 'status',
key: 'status',
valueType: 'select',
valueEnum: {
active: { text: 'Active', status: 'Success' },
inactive: { text: 'Inactive', status: 'Error' },
},
},
{
title: 'Actions',
key: 'actions',
hideInSearch: true,
render: (_, record, __, action) => (
<Space>
<Button size="small">Edit</Button>
<Button size="small" danger>Delete</Button>
</Space>
),
},
];
return (
<ProTable<User>
columns={columns}
request={async (params, sorter, filter) => {
// Fetch data from API
const response = await fetch(`/api/users?${new URLSearchParams({
page: params.current?.toString() || '1',
size: params.pageSize?.toString() || '10',
...params,
})}`);
const data = await response.json();
return {
data: data.users,
success: true,
total: data.total,
};
}}
rowKey="id"
search={{
labelWidth: 'auto',
collapsed: false,
}}
pagination={{
pageSize: 10,
showSizeChanger: true,
}}
toolBarRender={(action, { selectedRowKeys, selectedRows }) => [
<Button key="add" type="primary">Add User</Button>,
selectedRowKeys && selectedRowKeys.length > 0 && (
<Button key="delete" danger>
Delete Selected ({selectedRowKeys.length})
</Button>
),
]}
rowSelection={{
type: 'checkbox',
}}
options={{
setting: true,
fullScreen: true,
reload: true,
density: true,
}}
/>
);
};
// Table with custom search
const ProductTable = () => {
return (
<ProTable<Product>
columns={productColumns}
request={async (params) => {
// Custom search logic
return fetchProducts(params);
}}
search={{
filterType: 'light',
collapsed: false,
collapseRender: (collapsed) =>
collapsed ? 'Expand' : 'Collapse',
optionRender: (searchConfig, formProps, dom) => [
...dom,
<Button key="export">Export</Button>,
],
}}
/>
);
};Table component with inline editing capabilities for rows and cells.
/**
* Table component with inline editing capabilities
* @param props - EditableProTable configuration props
* @returns JSX.Element
*/
function EditableProTable<T = any>(props: EditableProTableProps<T>): JSX.Element;
interface EditableProTableProps<T> extends Omit<ProTableProps<T>, 'editable'> {
/** Editable configuration */
editable?: TableRowEditable<T>;
/** Controlled editing keys */
editableKeys?: Key[];
/** Editing keys change handler */
onEditableKeysChange?: (keys: Key[]) => void;
/** Save handler for edited rows */
onSave?: (key: Key, record: T, originRow: T, newLine?: boolean) => Promise<boolean | void>;
/** Delete handler for rows */
onDelete?: (key: Key, record: T) => Promise<boolean | void>;
/** Cancel handler for editing */
onCancel?: (key: Key, record: T, originRow: T, newLine?: boolean) => Promise<boolean | void>;
/** Editable form instance */
editorType?: 'single' | 'multiple';
/** Save on blur */
saveTimeout?: number;
}
interface TableRowEditable<T> {
/** Editing type */
type?: 'single' | 'multiple';
/** Editable form properties */
form?: FormProps;
/** Editable form instance */
editableKeys?: Key[];
/** Save handler */
onSave?: (key: Key, record: T, originRow: T, newLine?: boolean) => Promise<boolean | void>;
/** Delete handler */
onDelete?: (key: Key, record: T) => Promise<boolean | void>;
/** Cancel edit handler */
onCancel?: (key: Key, record: T, originRow: T, newLine?: boolean) => Promise<boolean | void>;
/** Change handler for editable keys */
onChange?: (editableKeys: Key[], editableRows: T[]) => void;
/** Action render function */
actionRender?: (row: T, config: ActionRenderConfig<T>) => React.ReactNode[];
/** Delete confirmation */
onlyOneLineEditorAlertMessage?: string;
/** Delete popconfirm */
deletePopconfirmMessage?: string;
/** Only add on first line */
onlyAddOneLineAlertMessage?: string;
}
interface ActionRenderConfig<T> {
/** Save function */
save: () => void;
/** Cancel function */
cancel: () => void;
/** Delete function */
delete: () => void;
/** Current record */
record: T;
/** Record index */
index: number;
}Usage Examples:
import { EditableProTable } from "@ant-design/pro-components";
const EditableTable = () => {
const [editableKeys, setEditableRowKeys] = useState<Key[]>([]);
const [dataSource, setDataSource] = useState<DataItem[]>([]);
const columns: ProColumns<DataItem> = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
formItemProps: {
rules: [{ required: true, message: 'Name is required' }],
},
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
valueType: 'digit',
},
{
title: 'Actions',
valueType: 'option',
render: (_, record, __, action) => [
<a key="edit" onClick={() => action?.startEditable?.(record.id)}>
Edit
</a>,
<a key="delete" onClick={() => {
setDataSource(dataSource.filter(item => item.id !== record.id));
}}>
Delete
</a>,
],
},
];
return (
<EditableProTable<DataItem>
rowKey="id"
columns={columns}
value={dataSource}
onChange={setDataSource}
editable={{
type: 'multiple',
editableKeys,
onSave: async (key, record, originRow) => {
// Save logic
return true;
},
onChange: setEditableRowKeys,
actionRender: (row, config) => [
<a key="save" onClick={config.save}>Save</a>,
<a key="cancel" onClick={config.cancel}>Cancel</a>,
],
}}
recordCreatorProps={{
position: 'bottom',
record: () => ({ id: Date.now(), name: '', age: 0 }),
}}
/>
);
};Table component with drag-and-drop row sorting capabilities.
/**
* Table component with drag-and-drop sorting
* @param props - DragSortTable configuration props
* @returns JSX.Element
*/
function DragSortTable<T = any>(props: DragTableProps<T>): JSX.Element;
interface DragTableProps<T> extends Omit<ProTableProps<T>, 'rowSelection'> {
/** Drag sort handler */
onDragSortEnd?: (newDataSource: T[]) => Promise<void> | void;
/** Drag handle column configuration */
dragSortKey?: string;
/** Drag sort disabled */
dragSortHandlerRender?: (rowData: T, idx: number) => React.ReactNode;
}Advanced list component with ProTable features for card-style data display.
/**
* Enhanced list component with ProTable features
* @param props - ProList configuration props
* @returns JSX.Element
*/
function ProList<T = any>(props: ProListProps<T>): JSX.Element;
interface ProListProps<T> {
/** List data request function */
request?: (params: any) => Promise<RequestData<T>>;
/** Static data source */
dataSource?: T[];
/** List metadata configuration */
metas?: ProListMetas<T>;
/** Row key field */
rowKey?: string | ((record: T) => string);
/** Loading state */
loading?: boolean;
/** Search configuration */
search?: SearchConfig | false;
/** Pagination configuration */
pagination?: PaginationProps | false;
/** Toolbar render function */
toolBarRender?: (action: ActionType) => React.ReactNode[];
/** List header title */
headerTitle?: React.ReactNode;
/** List item layout */
itemLayout?: 'horizontal' | 'vertical';
/** List size */
size?: 'default' | 'large' | 'small';
/** List split configuration */
split?: boolean;
/** Grid configuration for card layout */
grid?: { gutter?: number; column?: number; xs?: number; sm?: number; md?: number; lg?: number; xl?: number; xxl?: number };
/** Card layout properties */
cardProps?: any;
/** Show actions */
showActions?: 'hover' | 'always';
/** Show extra */
showExtra?: 'hover' | 'always';
}
interface ProListMetas<T> {
/** Item title */
title?: {
dataIndex?: string;
render?: (text: any, record: T) => React.ReactNode;
};
/** Item description */
description?: {
dataIndex?: string;
render?: (text: any, record: T) => React.ReactNode;
};
/** Item avatar */
avatar?: {
dataIndex?: string;
render?: (text: any, record: T) => React.ReactNode;
};
/** Item actions */
actions?: {
render?: (text: any, record: T) => React.ReactNode[];
};
/** Item extra content */
extra?: {
dataIndex?: string;
render?: (text: any, record: T) => React.ReactNode;
};
/** Item content */
content?: {
dataIndex?: string;
render?: (text: any, record: T) => React.ReactNode;
};
/** Custom metadata fields */
[key: string]: {
dataIndex?: string;
render?: (text: any, record: T) => React.ReactNode;
};
}Specialized table components for granular editing control and enhanced functionality.
/**
* Cell-level editable table with individual cell editing
* @param props - CellEditorTable configuration props
* @returns JSX.Element
*/
function CellEditorTable<T = any>(props: CellEditorTableProps<T>): JSX.Element;
/**
* Row-level editable table with entire row editing
* @param props - RowEditorTable configuration props
* @returns JSX.Element
*/
function RowEditorTable<T = any>(props: RowEditorTableProps<T>): JSX.Element;
/**
* Internationalization consumer for table components
* @param props - IntlConsumer configuration props
* @returns JSX.Element
*/
function IntlConsumer(props: IntlConsumerProps): JSX.Element;
interface CellEditorTableProps<T> extends Omit<ProTableProps<T>, 'editable'> {
/** Cell editing configuration */
editable?: {
/** Editable cell types */
type?: 'single' | 'multiple';
/** Form instance for editing */
form?: FormInstance;
/** Save handler for cell changes */
onSave?: (key: React.Key, record: T, newRecord: T) => Promise<boolean | void>;
/** Cancel handler */
onCancel?: (key: React.Key, record: T) => void;
/** Editable keys */
editableKeys?: React.Key[];
/** Change handler for editable keys */
onChange?: (editableKeys: React.Key[]) => void;
/** Action column render */
actionRender?: (row: T, config: any) => React.ReactNode[];
};
/** Cell click handler */
onCellClick?: (record: T, rowIndex: number) => void;
}
interface RowEditorTableProps<T> extends Omit<ProTableProps<T>, 'editable'> {
/** Row editing configuration */
editable?: {
/** Editing type */
type?: 'single' | 'multiple';
/** Form instance */
form?: FormInstance;
/** Save handler for row changes */
onSave?: (key: React.Key, record: T, newRecord: T) => Promise<boolean | void>;
/** Delete handler */
onDelete?: (key: React.Key, record: T) => Promise<boolean | void>;
/** Cancel handler */
onCancel?: (key: React.Key, record: T) => void;
/** Add new row handler */
onlyAddOneLineAlertMessage?: string;
/** Create new record */
createRecord?: () => T;
};
/** Row selection configuration */
rowSelection?: TableRowSelection<T>;
}
interface IntlConsumerProps {
/** Consumer children function */
children: (intl: IntlType, localeMap: Record<string, any>) => React.ReactNode;
}Usage Examples:
import { CellEditorTable, RowEditorTable, IntlConsumer } from "@ant-design/pro-components";
// Cell-level editing table
const CellEditExample = () => {
const [editableKeys, setEditableKeys] = useState<React.Key[]>([]);
return (
<CellEditorTable
columns={[
{
title: 'Name',
dataIndex: 'name',
editable: (text, record, index) => true,
},
{
title: 'Age',
dataIndex: 'age',
valueType: 'digit',
editable: (text, record, index) => true,
}
]}
request={fetchUsers}
editable={{
type: 'multiple',
editableKeys,
onSave: async (key, record, newRecord) => {
await updateUser(newRecord);
return true;
},
onChange: setEditableKeys,
actionRender: (row, config) => [
<a key="edit" onClick={() => config.startEditable?.(row.id)}>
Edit
</a>,
],
}}
onCellClick={(record, index) => {
// Handle cell click to start editing
setEditableKeys([record.id]);
}}
/>
);
};
// Row-level editing table
const RowEditExample = () => {
return (
<RowEditorTable
columns={columns}
request={fetchUsers}
editable={{
type: 'single',
onSave: async (key, record, newRecord) => {
await updateUser(newRecord);
return true;
},
onDelete: async (key, record) => {
await deleteUser(record.id);
return true;
},
createRecord: () => ({
id: Date.now(),
name: '',
age: 0,
email: ''
}),
}}
rowKey="id"
/>
);
};
// Internationalization example
const InternationalizedTable = () => (
<IntlConsumer>
{(intl, localeMap) => (
<ProTable
columns={[
{
title: intl.getMessage('table.name', 'Name'),
dataIndex: 'name',
},
{
title: intl.getMessage('table.actions', 'Actions'),
valueType: 'option',
render: () => [
<a key="edit">{intl.getMessage('common.edit', 'Edit')}</a>,
<a key="delete">{intl.getMessage('common.delete', 'Delete')}</a>,
],
},
]}
request={fetchUsers}
search={{
submitText: intl.getMessage('common.search', 'Search'),
resetText: intl.getMessage('common.reset', 'Reset'),
}}
/>
)}
</IntlConsumer>
);Supporting components for enhanced table functionality.
/**
* Table dropdown component for action menus
* @param props - TableDropdown configuration props
* @returns JSX.Element
*/
function TableDropdown(props: TableDropdownProps): JSX.Element;
/**
* List toolbar component
* @param props - ListToolBar configuration props
* @returns JSX.Element
*/
function ListToolBar(props: ListToolBarProps): JSX.Element;
/**
* Table search component
* @param props - Search configuration props
* @returns JSX.Element
*/
function Search(props: SearchProps): JSX.Element;
interface TableDropdownProps {
/** Dropdown key */
key?: string;
/** Dropdown menu items */
menus?: {
key: string;
name: React.ReactNode;
disabled?: boolean;
}[];
/** Click handler */
onSelect?: (key: string) => void;
/** Dropdown properties */
overlay?: React.ReactNode;
}
interface ListToolBarProps {
/** Toolbar title */
title?: React.ReactNode;
/** Toolbar subtitle */
subTitle?: React.ReactNode;
/** Toolbar description */
description?: React.ReactNode;
/** Action buttons */
actions?: React.ReactNode[];
/** Settings dropdown */
settings?: React.ReactNode[];
/** Filter component */
filter?: React.ReactNode;
/** Multiplier for spacing */
multipleLine?: boolean;
/** Tabs configuration */
tabs?: {
activeKey?: string;
onChange?: (activeKey: string) => void;
items?: {
key: string;
tab: React.ReactNode;
}[];
};
}interface SearchConfig {
/** Search form label width */
labelWidth?: number | 'auto';
/** Number of form fields per row */
span?: number;
/** Default collapsed state */
collapsed?: boolean;
/** Collapse render function */
collapseRender?: (collapsed: boolean) => React.ReactNode;
/** Default collapse state */
defaultCollapsed?: boolean;
/** Search button text */
searchText?: string;
/** Reset button text */
resetText?: string;
/** Custom submit button props */
submitButtonProps?: ButtonProps;
/** Custom reset button props */
resetButtonProps?: ButtonProps;
/** Custom option render */
optionRender?: (searchConfig: SearchConfig, formProps: any, dom: React.ReactNode[]) => React.ReactNode[];
/** Filter type */
filterType?: 'query' | 'light';
}
interface OptionsType {
/** Show search */
search?: boolean;
/** Show density selector */
density?: boolean;
/** Show fullscreen toggle */
fullScreen?: boolean;
/** Show column settings */
setting?: boolean;
/** Show reload button */
reload?: boolean;
}ProTable supports automatic rendering based on column value types:
type ProFieldValueType =
| 'text' | 'textarea' | 'password' | 'money' | 'percent' | 'digit'
| 'digitRange' | 'date' | 'dateTime' | 'dateRange' | 'dateTimeRange'
| 'time' | 'timeRange' | 'select' | 'checkbox' | 'radio' | 'radioButton'
| 'switch' | 'slider' | 'rate' | 'progress' | 'color' | 'image'
| 'code' | 'jsonCode' | 'avatar' | 'option' | 'index' | 'indexBorder';
interface ProSchemaValueEnumType {
[key: string]: {
/** Display text */
text: React.ReactNode;
/** Status for badge rendering */
status?: 'Success' | 'Error' | 'Processing' | 'Warning' | 'Default';
/** Custom color */
color?: string;
/** Disabled state */
disabled?: boolean;
};
}// Built-in locale objects
const zhCNIntl: IntlType;
const enUSIntl: IntlType;
const jaJPIntl: IntlType;
const arEGIntl: IntlType;
const itITIntl: IntlType;
const frFRIntl: IntlType;
const ptBRIntl: IntlType;
const ruRUIntl: IntlType;
/**
* Create internationalization instance
* @param locale - Locale identifier
* @param localeMap - Custom locale mappings
* @returns IntlType instance
*/
function createIntl(locale: string, localeMap?: Record<string, string>): IntlType;
interface IntlType {
/** Get localized message */
getMessage: (id: string, defaultMessage?: string) => string;
/** Current locale */
locale: string;
}