feat: table add filterMode...
							parent
							
								
									7a1c6b61ba
								
							
						
					
					
						commit
						ee778a2faa
					
				| 
						 | 
				
			
			@ -158,10 +158,12 @@ export const tableProps = () => {
 | 
			
		|||
      default: undefined,
 | 
			
		||||
    },
 | 
			
		||||
    indentSize: { type: Number as PropType<TableProps['indentSize']>, default: undefined },
 | 
			
		||||
    /** @deprecated Please use `EXPAND_COLUMN` in `columns` directly */
 | 
			
		||||
    expandIconColumnIndex: {
 | 
			
		||||
      type: Number as PropType<TableProps['expandIconColumnIndex']>,
 | 
			
		||||
      default: undefined,
 | 
			
		||||
    },
 | 
			
		||||
    showExpandColumn: { type: Boolean, default: undefined },
 | 
			
		||||
    expandedRowClassName: {
 | 
			
		||||
      type: Function as PropType<TableProps['expandedRowClassName']>,
 | 
			
		||||
      default: undefined,
 | 
			
		||||
| 
						 | 
				
			
			@ -494,6 +496,7 @@ const InteralTable = defineComponent<
 | 
			
		|||
    );
 | 
			
		||||
 | 
			
		||||
    const expandIconColumnIndex = computed(() => {
 | 
			
		||||
      if (props.showExpandColumn === false) return -1;
 | 
			
		||||
      // Adjust expand icon index, no overwrite expandIconColumnIndex if set.
 | 
			
		||||
      if (expandType.value === 'nest' && props.expandIconColumnIndex === undefined) {
 | 
			
		||||
        return props.rowSelection ? 1 : 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,14 +32,10 @@ import { defineComponent } from 'vue';
 | 
			
		|||
import type { TableColumnType } from 'ant-design-vue';
 | 
			
		||||
// In the fifth row, other columns are merged into first column
 | 
			
		||||
// by setting it's colSpan to be 0
 | 
			
		||||
const renderContent = ({ index }: any) => {
 | 
			
		||||
  const obj = {
 | 
			
		||||
    props: {} as any,
 | 
			
		||||
  };
 | 
			
		||||
const sharedOnCell = (_, index) => {
 | 
			
		||||
  if (index === 4) {
 | 
			
		||||
    obj.props.colSpan = 0;
 | 
			
		||||
    return { colSpan: 0 };
 | 
			
		||||
  }
 | 
			
		||||
  return obj;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const data = [
 | 
			
		||||
| 
						 | 
				
			
			@ -91,53 +87,42 @@ export default defineComponent({
 | 
			
		|||
      {
 | 
			
		||||
        title: 'Name',
 | 
			
		||||
        dataIndex: 'name',
 | 
			
		||||
        customRender: ({ index }) => {
 | 
			
		||||
          if (index < 4) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          return {
 | 
			
		||||
            props: {
 | 
			
		||||
              colSpan: 5,
 | 
			
		||||
            },
 | 
			
		||||
          };
 | 
			
		||||
        },
 | 
			
		||||
        customCell: (_, index) => ({
 | 
			
		||||
          colSpan: index < 4 ? 1 : 5,
 | 
			
		||||
        }),
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        title: 'Age',
 | 
			
		||||
        dataIndex: 'age',
 | 
			
		||||
        customRender: renderContent,
 | 
			
		||||
        customCell: sharedOnCell,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        title: 'Home phone',
 | 
			
		||||
        colSpan: 2,
 | 
			
		||||
        dataIndex: 'tel',
 | 
			
		||||
        customRender: ({ index }) => {
 | 
			
		||||
          const obj = {
 | 
			
		||||
            props: {} as any,
 | 
			
		||||
          };
 | 
			
		||||
        customCell: (_, index) => {
 | 
			
		||||
          if (index === 2) {
 | 
			
		||||
            obj.props.rowSpan = 2;
 | 
			
		||||
            return { rowSpan: 2 };
 | 
			
		||||
          }
 | 
			
		||||
          // These two are merged into above cell
 | 
			
		||||
          if (index === 3) {
 | 
			
		||||
            obj.props.rowSpan = 0;
 | 
			
		||||
            return { rowSpan: 0 };
 | 
			
		||||
          }
 | 
			
		||||
          if (index === 4) {
 | 
			
		||||
            obj.props.colSpan = 0;
 | 
			
		||||
            return { colSpan: 0 };
 | 
			
		||||
          }
 | 
			
		||||
          return obj;
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        title: 'Phone',
 | 
			
		||||
        colSpan: 0,
 | 
			
		||||
        dataIndex: 'phone',
 | 
			
		||||
        customRender: renderContent,
 | 
			
		||||
        customCell: sharedOnCell,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        title: 'Address',
 | 
			
		||||
        dataIndex: 'address',
 | 
			
		||||
        customRender: renderContent,
 | 
			
		||||
        customCell: sharedOnCell,
 | 
			
		||||
      },
 | 
			
		||||
    ];
 | 
			
		||||
    return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ Table with editable rows.
 | 
			
		|||
      <template v-else-if="column.dataIndex === 'operation'">
 | 
			
		||||
        <div class="editable-row-operations">
 | 
			
		||||
          <span v-if="editableData[record.key]">
 | 
			
		||||
            <a @click="save(record.key)">Save</a>
 | 
			
		||||
            <a-typography-link @click="save(record.key)">Save</a-typography-link>
 | 
			
		||||
            <a-popconfirm title="Sure to cancel?" @confirm="cancel(record.key)">
 | 
			
		||||
              <a>Cancel</a>
 | 
			
		||||
            </a-popconfirm>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,138 @@
 | 
			
		|||
<docs>
 | 
			
		||||
---
 | 
			
		||||
order: 6.1
 | 
			
		||||
version: 3.0
 | 
			
		||||
title:
 | 
			
		||||
  en-US: Filter in Tree
 | 
			
		||||
  zh-CN: 树型筛选菜单
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## zh-CN
 | 
			
		||||
 | 
			
		||||
可以使用 `filterMode` 来修改筛选菜单的 UI,可选值有 `menu`(默认)和 `tree`。
 | 
			
		||||
 | 
			
		||||
> `filterSearch` 用于开启筛选项的搜索。
 | 
			
		||||
 | 
			
		||||
## en-US
 | 
			
		||||
 | 
			
		||||
You can use `filterMode` to change default filter interface, options: `menu`(default) and `tree`.
 | 
			
		||||
 | 
			
		||||
> `filterSearch` is used for making filter dropdown items searchable.
 | 
			
		||||
 | 
			
		||||
</docs>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <a-table :columns="columns" :data-source="data" @change="onChange"></a-table>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent } from 'vue';
 | 
			
		||||
import type { TableProps } from 'ant-design-vue';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  setup() {
 | 
			
		||||
    const columns: TableProps['columns'] = [
 | 
			
		||||
      {
 | 
			
		||||
        title: 'Name',
 | 
			
		||||
        dataIndex: 'name',
 | 
			
		||||
        filters: [
 | 
			
		||||
          {
 | 
			
		||||
            text: 'Joe',
 | 
			
		||||
            value: 'Joe',
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            text: 'Category 1',
 | 
			
		||||
            value: 'Category 1',
 | 
			
		||||
            children: [
 | 
			
		||||
              {
 | 
			
		||||
                text: 'Yellow',
 | 
			
		||||
                value: 'Yellow',
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                text: 'Pink',
 | 
			
		||||
                value: 'Pink',
 | 
			
		||||
              },
 | 
			
		||||
            ],
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            text: 'Category 2',
 | 
			
		||||
            value: 'Category 2',
 | 
			
		||||
            children: [
 | 
			
		||||
              {
 | 
			
		||||
                text: 'Green',
 | 
			
		||||
                value: 'Green',
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                text: 'Black',
 | 
			
		||||
                value: 'Black',
 | 
			
		||||
              },
 | 
			
		||||
            ],
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
        filterMode: 'tree',
 | 
			
		||||
        filterSearch: true,
 | 
			
		||||
        onFilter: (value, record) => record.name.includes(value),
 | 
			
		||||
        width: '30%',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        title: 'Age',
 | 
			
		||||
        dataIndex: 'age',
 | 
			
		||||
        sorter: (a, b) => a.age - b.age,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        title: 'Address',
 | 
			
		||||
        dataIndex: 'address',
 | 
			
		||||
        filters: [
 | 
			
		||||
          {
 | 
			
		||||
            text: 'London',
 | 
			
		||||
            value: 'London',
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            text: 'New York',
 | 
			
		||||
            value: 'New York',
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
        onFilter: (value, record) => record.address.startsWith(value),
 | 
			
		||||
        filterSearch: true,
 | 
			
		||||
        width: '40%',
 | 
			
		||||
      },
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    const data = [
 | 
			
		||||
      {
 | 
			
		||||
        key: '1',
 | 
			
		||||
        name: 'John Brown',
 | 
			
		||||
        age: 32,
 | 
			
		||||
        address: 'New York No. 1 Lake Park',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        key: '2',
 | 
			
		||||
        name: 'Jim Green',
 | 
			
		||||
        age: 42,
 | 
			
		||||
        address: 'London No. 1 Lake Park',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        key: '3',
 | 
			
		||||
        name: 'Joe Black',
 | 
			
		||||
        age: 32,
 | 
			
		||||
        address: 'Sidney No. 1 Lake Park',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        key: '4',
 | 
			
		||||
        name: 'Jim Red',
 | 
			
		||||
        age: 32,
 | 
			
		||||
        address: 'London No. 2 Lake Park',
 | 
			
		||||
      },
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    function onChange(pagination, filters, sorter, extra) {
 | 
			
		||||
      console.log('params', pagination, filters, sorter, extra);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      data,
 | 
			
		||||
      columns,
 | 
			
		||||
      onChange,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -5,7 +5,6 @@
 | 
			
		|||
    <Bordered />
 | 
			
		||||
    <Ellipsis />
 | 
			
		||||
    <ColspanRowspan />
 | 
			
		||||
    <CustomFilterPanel />
 | 
			
		||||
    <EditCell />
 | 
			
		||||
    <EditRow />
 | 
			
		||||
    <ExpandChildren />
 | 
			
		||||
| 
						 | 
				
			
			@ -14,9 +13,10 @@
 | 
			
		|||
    <FixedColumns />
 | 
			
		||||
    <FixedHeader />
 | 
			
		||||
    <GroupingColumns />
 | 
			
		||||
    <Head />
 | 
			
		||||
    <MultipleSorter />
 | 
			
		||||
    <NestedTable />
 | 
			
		||||
    <Head />
 | 
			
		||||
    <CustomFilterPanel />
 | 
			
		||||
    <ResetFilter />
 | 
			
		||||
    <RowSelectionAndOperation />
 | 
			
		||||
    <RowSelectionCustom />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
<docs>
 | 
			
		||||
---
 | 
			
		||||
order: 14.1
 | 
			
		||||
version: 3.0
 | 
			
		||||
title:
 | 
			
		||||
  en-US: Order Specific Column
 | 
			
		||||
  zh-CN: 特殊列排序
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## zh-CN
 | 
			
		||||
 | 
			
		||||
你可以通过 `Table.EXPAND_COLUMN` 和 `Table.SELECT_COLUMN` 来控制选择和展开列的顺序。
 | 
			
		||||
 | 
			
		||||
## en-US
 | 
			
		||||
 | 
			
		||||
You can control the order of the expand and select columns by using `Table.EXPAND_COLUMN` and `Table.SELECT_COLUMN`.
 | 
			
		||||
 | 
			
		||||
</docs>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <a-table :columns="columns" :data-source="data" :row-selection="{}">
 | 
			
		||||
    <template #expandedRowRender="{ record }">
 | 
			
		||||
      <p style="margin: 0">
 | 
			
		||||
        {{ record.description }}
 | 
			
		||||
      </p>
 | 
			
		||||
    </template>
 | 
			
		||||
  </a-table>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent } from 'vue';
 | 
			
		||||
import { Table } from 'ant-design-vue';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  setup() {
 | 
			
		||||
    const columns = [
 | 
			
		||||
      { title: 'Name', dataIndex: 'name', key: 'name' },
 | 
			
		||||
      Table.EXPAND_COLUMN,
 | 
			
		||||
      { title: 'Age', dataIndex: 'age', key: 'age' },
 | 
			
		||||
      Table.SELECTION_COLUMN,
 | 
			
		||||
      { title: 'Address', dataIndex: 'address', key: 'address' },
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    const data = [
 | 
			
		||||
      {
 | 
			
		||||
        key: 1,
 | 
			
		||||
        name: 'John Brown',
 | 
			
		||||
        age: 32,
 | 
			
		||||
        address: 'New York No. 1 Lake Park',
 | 
			
		||||
        description:
 | 
			
		||||
          'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        key: 2,
 | 
			
		||||
        name: 'Jim Green',
 | 
			
		||||
        age: 42,
 | 
			
		||||
        address: 'London No. 1 Lake Park',
 | 
			
		||||
        description: 'My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park.',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        key: 3,
 | 
			
		||||
        name: 'Not Expandable',
 | 
			
		||||
        age: 29,
 | 
			
		||||
        address: 'Jiangsu No. 1 Lake Park',
 | 
			
		||||
        description: 'This not expandable',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        key: 4,
 | 
			
		||||
        name: 'Joe Black',
 | 
			
		||||
        age: 32,
 | 
			
		||||
        address: 'Sidney No. 1 Lake Park',
 | 
			
		||||
        description: 'My name is Joe Black, I am 32 years old, living in Sidney No. 1 Lake Park.',
 | 
			
		||||
      },
 | 
			
		||||
    ];
 | 
			
		||||
    return {
 | 
			
		||||
      data,
 | 
			
		||||
      columns,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -22,9 +22,15 @@ For long table,need to scroll to view the header and scroll bar,then you can
 | 
			
		|||
      <template v-if="column.key === 'operation'"><a>action</a></template>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #summary>
 | 
			
		||||
      <a-table-summary>
 | 
			
		||||
      <a-table-summary :fixed="fixedTop ? 'top' : 'bottom'">
 | 
			
		||||
        <a-table-summary-row>
 | 
			
		||||
          <a-table-summary-cell :index="0" :col-span="2">Fix Left</a-table-summary-cell>
 | 
			
		||||
          <a-table-summary-cell :index="0" :col-span="2">
 | 
			
		||||
            <a-switch
 | 
			
		||||
              v-model:checked="fixedTop"
 | 
			
		||||
              checked-children="Fixed Top"
 | 
			
		||||
              un-checked-children="Fixed Top"
 | 
			
		||||
            ></a-switch>
 | 
			
		||||
          </a-table-summary-cell>
 | 
			
		||||
          <a-table-summary-cell :index="2" :col-span="8">Scroll Context</a-table-summary-cell>
 | 
			
		||||
          <a-table-summary-cell :index="10">Fix Right</a-table-summary-cell>
 | 
			
		||||
        </a-table-summary-row>
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +123,7 @@ export default defineComponent({
 | 
			
		|||
    return {
 | 
			
		||||
      data,
 | 
			
		||||
      columns,
 | 
			
		||||
      fixedTop: ref(false),
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,10 +3,13 @@ import { renderSlot } from 'vue';
 | 
			
		|||
import type { Ref } from 'vue';
 | 
			
		||||
import type { ContextSlots } from '../context';
 | 
			
		||||
import type { TransformColumns, ColumnsType } from '../interface';
 | 
			
		||||
import { SELECTION_COLUMN } from './useSelection';
 | 
			
		||||
import { EXPAND_COLUMN } from '../../vc-table';
 | 
			
		||||
 | 
			
		||||
function fillSlots<RecordType>(columns: ColumnsType<RecordType>, contextSlots: Ref<ContextSlots>) {
 | 
			
		||||
  const $slots = contextSlots.value;
 | 
			
		||||
  return columns.map(column => {
 | 
			
		||||
    if (column === SELECTION_COLUMN || column === EXPAND_COLUMN) return column;
 | 
			
		||||
    const cloneColumn = { ...column };
 | 
			
		||||
    const { slots = {} } = cloneColumn;
 | 
			
		||||
    cloneColumn.__originColumn__ = column;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ import type {
 | 
			
		|||
  Key,
 | 
			
		||||
  TableLocale,
 | 
			
		||||
  GetPopupContainer,
 | 
			
		||||
  FilterSearchType,
 | 
			
		||||
} from '../../interface';
 | 
			
		||||
import FilterDropdownMenuWrapper from './FilterWrapper';
 | 
			
		||||
import type { FilterState } from '.';
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +26,11 @@ import type { CheckboxChangeEvent, EventHandler } from '../../../_util/EventInte
 | 
			
		|||
import FilterSearch from './FilterSearch';
 | 
			
		||||
import Tree from '../../../tree';
 | 
			
		||||
 | 
			
		||||
interface FilterRestProps {
 | 
			
		||||
  confirm?: Boolean;
 | 
			
		||||
  closeDropdown?: Boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const { SubMenu, Item: MenuItem } = Menu;
 | 
			
		||||
 | 
			
		||||
function hasSubMenu(filters: ColumnFilterItem[]) {
 | 
			
		||||
| 
						 | 
				
			
			@ -44,12 +50,14 @@ function renderFilterItems({
 | 
			
		|||
  filteredKeys,
 | 
			
		||||
  filterMultiple,
 | 
			
		||||
  searchValue,
 | 
			
		||||
  filterSearch,
 | 
			
		||||
}: {
 | 
			
		||||
  filters: ColumnFilterItem[];
 | 
			
		||||
  prefixCls: string;
 | 
			
		||||
  filteredKeys: Key[];
 | 
			
		||||
  filterMultiple: boolean;
 | 
			
		||||
  searchValue: string;
 | 
			
		||||
  filterSearch: FilterSearchType;
 | 
			
		||||
}) {
 | 
			
		||||
  return filters.map((filter, index) => {
 | 
			
		||||
    const key = String(filter.value);
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +75,7 @@ function renderFilterItems({
 | 
			
		|||
            filteredKeys,
 | 
			
		||||
            filterMultiple,
 | 
			
		||||
            searchValue,
 | 
			
		||||
            filterSearch,
 | 
			
		||||
          })}
 | 
			
		||||
        </SubMenu>
 | 
			
		||||
      );
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +90,9 @@ function renderFilterItems({
 | 
			
		|||
      </MenuItem>
 | 
			
		||||
    );
 | 
			
		||||
    if (searchValue.trim()) {
 | 
			
		||||
      if (typeof filterSearch === 'function') {
 | 
			
		||||
        return filterSearch(searchValue, filter) ? item : undefined;
 | 
			
		||||
      }
 | 
			
		||||
      return searchValueMatched(searchValue, filter.text) ? item : undefined;
 | 
			
		||||
    }
 | 
			
		||||
    return item;
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +143,7 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
          (props.filterState.filteredKeys?.length || props.filterState.forceFiltered)
 | 
			
		||||
        ),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const filterFlattenKeys = computed(() => flattenKeys(props.column?.filters));
 | 
			
		||||
    const filterDropdownRef = computed(() => {
 | 
			
		||||
      const { filterDropdown, slots = {}, customFilterDropdown } = props.column;
 | 
			
		||||
      return (
 | 
			
		||||
| 
						 | 
				
			
			@ -188,6 +200,8 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
      { immediate: true },
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // const expandKeys = shallowRef(filterFlattenKeys.value.slice());
 | 
			
		||||
    // const onExpandChange = keys => (expandKeys.value = keys);
 | 
			
		||||
    const openKeys = shallowRef([]);
 | 
			
		||||
 | 
			
		||||
    const openRef = ref();
 | 
			
		||||
| 
						 | 
				
			
			@ -241,7 +255,15 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
      internalTriggerFilter(filteredKeys.value);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const onReset = () => {
 | 
			
		||||
    const onReset = (
 | 
			
		||||
      { confirm, closeDropdown }: FilterRestProps = { confirm: false, closeDropdown: false },
 | 
			
		||||
    ) => {
 | 
			
		||||
      if (confirm) {
 | 
			
		||||
        internalTriggerFilter([]);
 | 
			
		||||
      }
 | 
			
		||||
      if (closeDropdown) {
 | 
			
		||||
        triggerVisible(false);
 | 
			
		||||
      }
 | 
			
		||||
      searchValue.value = '';
 | 
			
		||||
      filteredKeys.value = [];
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +292,7 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
 | 
			
		||||
    const onCheckAll = (e: CheckboxChangeEvent) => {
 | 
			
		||||
      if (e.target.checked) {
 | 
			
		||||
        const allFilterKeys = flattenKeys(props.column?.filters).map(key => String(key));
 | 
			
		||||
        const allFilterKeys = filterFlattenKeys.value;
 | 
			
		||||
        filteredKeys.value = allFilterKeys;
 | 
			
		||||
      } else {
 | 
			
		||||
        filteredKeys.value = [];
 | 
			
		||||
| 
						 | 
				
			
			@ -289,6 +311,8 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
        }
 | 
			
		||||
        return item;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    const treeData = computed(() => getTreeData({ filters: props.column.filters }));
 | 
			
		||||
    // ======================== Style ========================
 | 
			
		||||
    const dropdownMenuClass = computed(() =>
 | 
			
		||||
      classNames({
 | 
			
		||||
| 
						 | 
				
			
			@ -338,6 +362,10 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
                <Checkbox
 | 
			
		||||
                  class={`${tablePrefixCls}-filter-dropdown-checkall`}
 | 
			
		||||
                  onChange={onCheckAll}
 | 
			
		||||
                  checked={selectedKeys.length === filterFlattenKeys.value.length}
 | 
			
		||||
                  indeterminate={
 | 
			
		||||
                    selectedKeys.length > 0 && selectedKeys.length < filterFlattenKeys.value.length
 | 
			
		||||
                  }
 | 
			
		||||
                >
 | 
			
		||||
                  {locale.filterCheckall}
 | 
			
		||||
                </Checkbox>
 | 
			
		||||
| 
						 | 
				
			
			@ -353,9 +381,11 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
                checkedKeys={selectedKeys}
 | 
			
		||||
                selectedKeys={selectedKeys}
 | 
			
		||||
                showIcon={false}
 | 
			
		||||
                treeData={getTreeData({ filters: column.filters })}
 | 
			
		||||
                treeData={treeData.value}
 | 
			
		||||
                autoExpandParent
 | 
			
		||||
                defaultExpandAll
 | 
			
		||||
                // expandedKeys={expandKeys.value as Key[]}
 | 
			
		||||
                // onExpand={onExpandChange}
 | 
			
		||||
                filterTreeNode={
 | 
			
		||||
                  searchValue.value.trim()
 | 
			
		||||
                    ? node => searchValueMatched(searchValue.value, node.title)
 | 
			
		||||
| 
						 | 
				
			
			@ -390,6 +420,7 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
              default: () =>
 | 
			
		||||
                renderFilterItems({
 | 
			
		||||
                  filters: column.filters || [],
 | 
			
		||||
                  filterSearch: filterSearch.value,
 | 
			
		||||
                  prefixCls,
 | 
			
		||||
                  filteredKeys: filteredKeys.value,
 | 
			
		||||
                  filterMultiple,
 | 
			
		||||
| 
						 | 
				
			
			@ -430,7 +461,7 @@ export default defineComponent<FilterDropdownProps<any>>({
 | 
			
		|||
                type="link"
 | 
			
		||||
                size="small"
 | 
			
		||||
                disabled={selectedKeys.length === 0}
 | 
			
		||||
                onClick={onReset}
 | 
			
		||||
                onClick={() => onReset()}
 | 
			
		||||
              >
 | 
			
		||||
                {locale.filterReset}
 | 
			
		||||
              </Button>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ export const SELECTION_COLUMN = {} as const;
 | 
			
		|||
export const SELECTION_ALL = 'SELECT_ALL' as const;
 | 
			
		||||
export const SELECTION_INVERT = 'SELECT_INVERT' as const;
 | 
			
		||||
export const SELECTION_NONE = 'SELECT_NONE' as const;
 | 
			
		||||
 | 
			
		||||
const EMPTY_LIST: Key[] = [];
 | 
			
		||||
interface UseSelectionConfig<RecordType> {
 | 
			
		||||
  prefixCls: Ref<string>;
 | 
			
		||||
  pageData: Ref<RecordType[]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ export default function useSelection<RecordType>(
 | 
			
		|||
  const [mergedSelectedKeys, setMergedSelectedKeys] = useMergedState(
 | 
			
		||||
    mergedRowSelection.value.selectedRowKeys ||
 | 
			
		||||
      mergedRowSelection.value.defaultSelectedRowKeys ||
 | 
			
		||||
      [],
 | 
			
		||||
      EMPTY_LIST,
 | 
			
		||||
    {
 | 
			
		||||
      value: computed(() => mergedRowSelection.value.selectedRowKeys),
 | 
			
		||||
    },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,9 +82,10 @@ Specify `dataSource` of Table as an array of data.
 | 
			
		|||
| expandFixed | Set column to be fixed: `true`(same as left) `'left'` `'right'` | boolean \| string | false | 3.0 |
 | 
			
		||||
| expandIcon | Customize row expand Icon. | Function(props):VNode \| v-slot:expandIcon="props" | - |  |
 | 
			
		||||
| expandRowByClick | Whether to expand row by clicking anywhere in the whole row | boolean | `false` |  |
 | 
			
		||||
| expandIconColumnIndex | Customize expand icon column index. Not render when `-1` | 0 |  |
 | 
			
		||||
| footer | Table footer renderer | Function(currentPageData)\| v-slot:footer="currentPageData" |  |
 | 
			
		||||
| indentSize | Indent size in pixels of tree data | number | 15 |  |
 | 
			
		||||
| rowExpandable | Enable row can be expandable | (record) => boolean | - |  |
 | 
			
		||||
| showExpandColumn | Show expand column | boolean | true | 3.0 |
 | 
			
		||||
| loading | Loading status of table | boolean\|[object](/components/spin) | `false` |
 | 
			
		||||
| locale | i18n text including filter, sort, empty text, etc | object | filterConfirm: 'Ok' <br /> filterReset: 'Reset' <br /> emptyText: 'No Data' |  |
 | 
			
		||||
| pagination | Config of pagination. You can ref table pagination [config](#pagination) or full [`pagination`](/components/pagination/) document, hide it by setting it to `false` | object |  |  |
 | 
			
		||||
| 
						 | 
				
			
			@ -109,10 +110,6 @@ Specify `dataSource` of Table as an array of data.
 | 
			
		|||
| summary | Summary content | v-slot:summary | - | 3.0 |
 | 
			
		||||
| transformCellText | The data can be changed again before rendering, generally used for the default configuration of empty data. You can configured globally through [ConfigProvider](/components/config-provider-cn/) | Function({ text, column, record, index }) => any, The `text` here is the data processed by other defined cell api, and it may be of type VNode \| string \| number | - | 1.5.4 | |
 | 
			
		||||
 | 
			
		||||
- `expandFixed`
 | 
			
		||||
  - When set to true or `left` and `expandIconColumnIndex` is not set or is 0, enable fixed
 | 
			
		||||
  - When set to true or `right` and `expandIconColumnIndex` is set to the number of table columns, enable fixed
 | 
			
		||||
 | 
			
		||||
### Events
 | 
			
		||||
 | 
			
		||||
| Events Name | Description | Arguments |
 | 
			
		||||
| 
						 | 
				
			
			@ -166,10 +163,12 @@ One of the Table `columns` prop for describing the table's columns, Column has t
 | 
			
		|||
| filteredValue | Controlled filtered value, filter icon will highlight | string\[] | - |  |
 | 
			
		||||
| filterIcon | Customized filter icon | ({filtered: boolean, column: Column}) | `false` |  |
 | 
			
		||||
| filterMultiple | Whether multiple filters can be selected | boolean | `true` |  |
 | 
			
		||||
| filterMode | To specify the filter interface | 'menu' \| 'tree' | 'menu' | 3.0 |
 | 
			
		||||
| filterSearch | Whether to be searchable for filter menu | Boolean | false | 3.0 |
 | 
			
		||||
| filters | Filter menu config | object\[] | - |  |
 | 
			
		||||
| fixed | Set column to be fixed: `true`(same as left) `'left'` `'right'` | boolean\|string | `false` |  |
 | 
			
		||||
| key | Unique key of this column, you can ignore this prop if you've set a unique `dataIndex` | string | - |  |
 | 
			
		||||
| customRender | Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config | Function({text, record, index}) {} | - |  |
 | 
			
		||||
| customRender | Renderer of the table cell. The return value should be a VNode | Function({text, record, index}) {} | - |  |
 | 
			
		||||
| responsive | The list of breakpoints at which to display this column. Always visible if not set. | [Breakpoint](#Breakpoint)\[] | - | 3.0 |
 | 
			
		||||
| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | Function\|boolean | - |  |
 | 
			
		||||
| sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - |  |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,7 +86,6 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
 | 
			
		|||
| expandFixed | 控制展开图标是否固定,可选 true `left` `right` | boolean \| string | false | 3.0 |
 | 
			
		||||
| expandIcon | 自定义展开图标 | Function(props):VNode \| v-slot:expandIcon="props" | - |  |
 | 
			
		||||
| expandRowByClick | 通过点击行来展开子行 | boolean | `false` |  |
 | 
			
		||||
| expandIconColumnIndex | 自定义展开按钮的列顺序,`-1` 时不展示 | number | - |  |
 | 
			
		||||
| footer | 表格尾部 | Function(currentPageData)\|v-slot:footer="currentPageData" |  |  |
 | 
			
		||||
| getPopupContainer | 设置表格内各类浮层的渲染节点,如筛选菜单 | (triggerNode) => HTMLElement | `() => TableHtmlElement` | 1.5.0 |
 | 
			
		||||
| loading | 页面是否加载中 | boolean\|[object](/components/spin-cn) | false |  |
 | 
			
		||||
| 
						 | 
				
			
			@ -105,6 +104,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
 | 
			
		|||
| title | 表格标题 | Function(currentPageData)\|v-slot:title="currentPageData" |  |  |
 | 
			
		||||
| indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 |  |
 | 
			
		||||
| rowExpandable | 设置是否允许行展开 | (record) => boolean | - | 3.0 |
 | 
			
		||||
| showExpandColumn | 设置是否展示行展开列 | boolean | true | 3.0 |
 | 
			
		||||
| customHeaderRow | 设置头部行属性 | Function(columns, index) | - |  |
 | 
			
		||||
| customRow | 设置行属性 | Function(record, index) | - |  |
 | 
			
		||||
| headerCell | 个性化头部单元格 | v-slot:headerCell="{title, column}" | - | 3.0 |
 | 
			
		||||
| 
						 | 
				
			
			@ -115,10 +115,6 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
 | 
			
		|||
| summary | 总结栏 | v-slot:summary | - | 3.0 |
 | 
			
		||||
| transformCellText | 数据渲染前可以再次改变,一般用于空数据的默认配置,可以通过 [ConfigProvider](/components/config-provider-cn/) 全局统一配置 | Function({ text, column, record, index }) => any,此处的 text 是经过其它定义单元格 api 处理后的数据,有可能是 VNode \| string \| number 类型 | - | 1.5.4 |
 | 
			
		||||
 | 
			
		||||
- `expandFixed`
 | 
			
		||||
  - 当设置为 true 或 `left` 且 `expandIconColumnIndex` 未设置或为 0 时,开启固定
 | 
			
		||||
  - 当设置为 true 或 `right` 且 `expandIconColumnIndex` 设置为表格列数时,开启固定
 | 
			
		||||
 | 
			
		||||
### 事件
 | 
			
		||||
 | 
			
		||||
| 事件名称 | 说明 | 回调参数 |
 | 
			
		||||
| 
						 | 
				
			
			@ -171,10 +167,12 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
 | 
			
		|||
| filteredValue | 筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组 | string\[] | - |  |
 | 
			
		||||
| filterIcon | 自定义 filter 图标。 | VNode \| ({filtered: boolean, column: Column}) => vNode | false |  |
 | 
			
		||||
| filterMultiple | 是否多选 | boolean | true |  |
 | 
			
		||||
| filterMode | 指定筛选菜单的用户界面 | 'menu' \| 'tree' | 'menu' | 3.0 |
 | 
			
		||||
| filterSearch | 筛选菜单项是否可搜索 | Boolean | false | 3.0 |
 | 
			
		||||
| filters | 表头的筛选菜单项 | object\[] | - |  |
 | 
			
		||||
| fixed | 列是否固定,可选 `true`(等效于 left) `'left'` `'right'` | boolean\|string | false |  |
 | 
			
		||||
| key | Vue 需要的 key,如果已经设置了唯一的 `dataIndex`,可以忽略这个属性 | string | - |  |
 | 
			
		||||
| customRender | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return 里面可以设置表格行/列合并,可参考 demo 表格行/列合并 | Function({text, record, index, column}) {} | - |  |
 | 
			
		||||
| customRender | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引 | Function({text, record, index, column}) {} | - |  |
 | 
			
		||||
| responsive | 响应式 breakpoint 配置列表。未设置则始终可见。 | [Breakpoint](#Breakpoint)\[] | - | 3.0 |
 | 
			
		||||
| showSorterTooltip | 表头显示下一次排序的 tooltip 提示, 覆盖 table 中 `showSorterTooltip` | boolean \| [Tooltip props](/components/tooltip/#API) | true |  |
 | 
			
		||||
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - |  |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,7 @@ export type ColumnTitle<RecordType> = VueNode | ((props: ColumnTitleProps<Record
 | 
			
		|||
 | 
			
		||||
export type FilterValue = (Key | boolean)[];
 | 
			
		||||
export type FilterKey = Key[] | null;
 | 
			
		||||
export type FilterSearchType = boolean | ((input: string, record: {}) => boolean);
 | 
			
		||||
export interface FilterConfirmProps {
 | 
			
		||||
  closeDropdown: boolean;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import classNames from '../../_util/classNames';
 | 
			
		||||
import { flattenChildren, isValidElement, parseStyleText } from '../../_util/props-util';
 | 
			
		||||
import type { CSSProperties, TdHTMLAttributes } from 'vue';
 | 
			
		||||
import type { CSSProperties } from 'vue';
 | 
			
		||||
import { computed, defineComponent, isVNode, renderSlot } from 'vue';
 | 
			
		||||
 | 
			
		||||
import type {
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ import type {
 | 
			
		|||
  AlignType,
 | 
			
		||||
  CellEllipsisType,
 | 
			
		||||
  TransformCellText,
 | 
			
		||||
  AdditionalProps,
 | 
			
		||||
} from '../interface';
 | 
			
		||||
import { getPathValue, validateValue } from '../utils/valueUtil';
 | 
			
		||||
import { useInjectSlots } from '../../table/context';
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +62,7 @@ export interface CellProps<RecordType = DefaultRecordType> {
 | 
			
		|||
  /** @private Used for `expandable` with nest tree */
 | 
			
		||||
  appendNode?: any;
 | 
			
		||||
 | 
			
		||||
  additionalProps?: TdHTMLAttributes;
 | 
			
		||||
  additionalProps?: AdditionalProps;
 | 
			
		||||
 | 
			
		||||
  rowType?: 'header' | 'body' | 'footer';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -106,10 +107,18 @@ export default defineComponent<CellProps>({
 | 
			
		|||
    const contextSlots = useInjectSlots();
 | 
			
		||||
    const { onHover, startRow, endRow } = useInjectHover();
 | 
			
		||||
    const colSpan = computed(() => {
 | 
			
		||||
      return props.colSpan ?? (props.additionalProps?.colspan as number);
 | 
			
		||||
      return (
 | 
			
		||||
        props.colSpan ??
 | 
			
		||||
        props.additionalProps?.colSpan ??
 | 
			
		||||
        (props.additionalProps?.colspan as number)
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    const rowSpan = computed(() => {
 | 
			
		||||
      return props.rowSpan ?? (props.additionalProps?.rowspan as number);
 | 
			
		||||
      return (
 | 
			
		||||
        props.rowSpan ??
 | 
			
		||||
        props.additionalProps?.rowSpan ??
 | 
			
		||||
        (props.additionalProps?.rowspan as number)
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    const hovering = computed(() => {
 | 
			
		||||
      const { index } = props;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,9 +43,7 @@ export default defineComponent<SummaryCellProps>({
 | 
			
		|||
          align={align}
 | 
			
		||||
          colSpan={mergedColSpan}
 | 
			
		||||
          rowSpan={rowSpan}
 | 
			
		||||
          customRender={() => ({
 | 
			
		||||
            children: slots.default?.(),
 | 
			
		||||
          })}
 | 
			
		||||
          customRender={() => slots.default?.()}
 | 
			
		||||
          {...fixedInfo}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,6 +109,7 @@ export interface TableProps<RecordType = DefaultRecordType> {
 | 
			
		|||
  defaultExpandAllRows?: boolean;
 | 
			
		||||
  indentSize?: number;
 | 
			
		||||
  expandIconColumnIndex?: number;
 | 
			
		||||
  showExpandColumn?: boolean;
 | 
			
		||||
  expandedRowClassName?: RowClassName<RecordType>;
 | 
			
		||||
  childrenColumnName?: string;
 | 
			
		||||
  rowExpandable?: (record: RecordType) => boolean;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@
 | 
			
		|||
 * - onFilterDropdownVisibleChange
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import type { CSSProperties, HTMLAttributes, Ref, TdHTMLAttributes } from 'vue';
 | 
			
		||||
import type { CSSProperties, Ref, TdHTMLAttributes } from 'vue';
 | 
			
		||||
 | 
			
		||||
export type Key = number | string;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -132,13 +132,16 @@ export interface StickyOffsets {
 | 
			
		|||
  right: readonly number[];
 | 
			
		||||
  isSticky?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type AdditionalProps = TdHTMLAttributes & {
 | 
			
		||||
  colSpan?: number;
 | 
			
		||||
  rowSpan?: number;
 | 
			
		||||
};
 | 
			
		||||
// ================= Customized =================
 | 
			
		||||
export type GetComponentProps<DataType> = (
 | 
			
		||||
  data: DataType,
 | 
			
		||||
  index?: number,
 | 
			
		||||
  column?: ColumnType<any>,
 | 
			
		||||
) => Omit<HTMLAttributes | TdHTMLAttributes, 'style'> & { style?: CSSProperties };
 | 
			
		||||
) => AdditionalProps;
 | 
			
		||||
 | 
			
		||||
// type Component<P> = DefineComponent<P> | FunctionalComponent<P> | string;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -195,9 +198,11 @@ export interface LegacyExpandableProps<RecordType> {
 | 
			
		|||
  defaultExpandAllRows?: boolean;
 | 
			
		||||
 | 
			
		||||
  indentSize?: number;
 | 
			
		||||
 | 
			
		||||
  /** @deprecated Please use `EXPAND_COLUMN` in `columns` directly */
 | 
			
		||||
  expandIconColumnIndex?: number;
 | 
			
		||||
 | 
			
		||||
  showExpandColumn?: boolean;
 | 
			
		||||
 | 
			
		||||
  expandedRowClassName?: RowClassName<RecordType>;
 | 
			
		||||
 | 
			
		||||
  childrenColumnName?: string;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue