or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cards.mddescriptions.mdfield-rendering.mdform-components.mdindex.mdlayout.mdproviders.mdskeleton.mdtable-list.mdutilities.md
tile.json

table-list.mddocs/

Table and List Components

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.

Capabilities

ProTable - Enhanced Data Table

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>,
        ],
      }}
    />
  );
};

EditableProTable - Editable Table

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 }),
      }}
    />
  );
};

DragSortTable - Sortable Table

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;
}

ProList - Enhanced List Component

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;
  };
}

Advanced Table Components

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>
);

Table Utility Components

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;
    }[];
  };
}

Search Configuration Types

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;
}

Column Value Types

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;
  };
}

Internationalization Support

// 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;
}