---
nav:
  title: 组件
  order: 1
group:
  title: 数据操作
  order: 3
title: PisellBatchActionBar
order: 1
category: pro
---

# PisellBatchActionBar 批量操作栏

选择感知型的批量操作组件，用于承载基于选中对象的批量行为操作。提供固定的四个基础操作按钮（全选、反选、取消选择、删除），并支持自定义操作按钮、多种布局模式、溢出处理、确认弹窗等功能。

## 何时使用

- 需要对表格、列表、卡片等组件中的多个选中项进行批量操作时
- 需要提供全选、反选、清空选择等基础选择操作时
- 需要提供删除、导出、分享等批量操作时
- 需要在不同布局场景下使用批量操作栏（悬浮、吸顶、吸底、内嵌）
- 需要在选中项较多时收纳操作按钮到"更多"菜单

## 代码演示

### 基础用法

最简单的用法，传入 `selectedKeys` 即可。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys, setSelectedKeys] = useState(['1', '2']);

  return (
    <PisellBatchActionBar
      selectedKeys={selectedKeys}
      position="inline"
      onSelectAll={() => {
        // 全选逻辑
        setSelectedKeys(['1', '2', '3', '4', '5']);
      }}
      onInvert={() => {
        // 反选逻辑
        console.log('反选');
      }}
      onClear={() => {
        // 清空选择
        setSelectedKeys([]);
      }}
      onDelete={(keys, rows) => {
        // 删除选中项
        console.log('删除', keys, rows);
      }}
    />
  );
};
```

### 与 Table 组件集成

配合 Ant Design Table 的 `rowSelection` 使用。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {Table} from 'antd';
import {useState} from 'react';

export default () => {
    const [selectedRowKeys, setSelectedRowKeys] = useState([]);
    const [selectedRows, setSelectedRows] = useState([]);

    const dataSource = [
        {id: '1', name: '商品 1', price: 99},
        {id: '2', name: '商品 2', price: 199},
        {id: '3', name: '商品 3', price: 299},
        {id: '4', name: '商品 4', price: 399},
        {id: '5', name: '商品 5', price: 499},
    ];

    const columns = [
        {title: '商品名称', dataIndex: 'name', key: 'name'},
        {title: '价格', dataIndex: 'price', key: 'price'},
    ];

    return (
        <>
            <Table
                dataSource={dataSource}
                columns={columns}
                rowKey="id"
                rowSelection={{
                    selectedRowKeys,
                    onChange: (keys, rows) => {
                        setSelectedRowKeys(keys);
                        setSelectedRows(rows);
                    },
                }}
            />

      {selectedRowKeys.length > 0 && (
        <PisellBatchActionBar
          selectedKeys={selectedRowKeys}
          selectedRows={selectedRows}
          total={dataSource.length}
          position="inline"
          onSelectAll={() => {
                        const allKeys = dataSource.map((item) => item.id);
                        setSelectedRowKeys(allKeys);
                        setSelectedRows(dataSource);
                    }}
                    onClear={() => {
                        setSelectedRowKeys([]);
                        setSelectedRows([]);
                    }}
                    onDelete={(keys, rows) => {
                        console.log('删除选中项', keys, rows);
                        setSelectedRowKeys([]);
                        setSelectedRows([]);
                    }}
                />
            )}
        </>
    );
};
```

### 自定义操作按钮

通过 `actions` 属性添加自定义操作按钮。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {message} from 'antd';
import {useState} from 'react';

export default () => {
    const [selectedKeys, setSelectedKeys] = useState(['1', '2', '3']);

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            actions={[
                {
                    key: 'export',
                    label: '导出',
                    icon: 'pisell2-download-cloud-02',
                    onClick: (keys, rows) => {
                        message.success(`导出 ${keys.length} 项`);
                    },
                },
                {
                    key: 'share',
                    label: '分享',
                    icon: 'pisell2-share-07',
                    onClick: (keys, rows) => {
                        message.success(`分享 ${keys.length} 项`);
                    },
                },
                {
                    key: 'move',
                    label: '移动到',
                    icon: 'pisell2-folder',
                    onClick: (keys, rows) => {
                        console.log('移动到', keys, rows);
                    },
                },
            ]}
            onClear={() => setSelectedKeys([])}
        />
    );
};
```

### 按钮显隐控制

支持动态控制按钮的显示隐藏。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys, setSelectedKeys] = useState(['1']);

  return (
    <PisellBatchActionBar
      selectedKeys={selectedKeys}
      position="inline"
      defaultActions={{
        showDelete: false, // 隐藏删除按钮
      }}
      actions={[
                {
                    key: 'export',
                    label: '导出',
                    icon: 'pisell2-download-cloud-02',
                    // 只有选中多项时才显示
                    visible: (keys) => keys.length > 1,
                },
                {
                    key: 'edit',
                    label: '编辑',
                    icon: 'pisell2-edit-05',
                    // 只有选中单项时才显示
                    visible: (keys) => keys.length === 1,
                },
            ]}
            onClear={() => setSelectedKeys([])}
        />
    );
};
```

### 按钮禁用控制

支持动态控制按钮的禁用状态。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys, setSelectedKeys] = useState(['1', '2']);

  return (
    <PisellBatchActionBar
      selectedKeys={selectedKeys}
      position="inline"
      actions={[
        {
          key: 'export',
          label: '导出',
          icon: 'pisell2-download-cloud-02',
          // 没有选中项时禁用
          disabled: (keys) => keys.length === 0,
        },
                {
                    key: 'batch-edit',
                    label: '批量编辑',
                    icon: 'pisell2-edit-05',
                    // 选中超过 10 项时禁用
                    disabled: (keys) => keys.length > 10,
                },
            ]}
            onClear={() => setSelectedKeys([])}
        />
    );
};
```

### 确认弹窗

为操作按钮添加确认弹窗。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {message} from 'antd';
import {useState} from 'react';

export default () => {
    const [selectedKeys, setSelectedKeys] = useState(['1', '2']);

  return (
    <PisellBatchActionBar
      selectedKeys={selectedKeys}
      position="inline"
      // 删除按钮的确认弹窗配置
      deleteConfirmConfig={{
        title: '确认删除',
        description: '删除后将无法恢复，确定要删除选中的项吗？',
        okText: '确定删除',
        cancelText: '取消',
      }}
            actions={[
                {
                    key: 'archive',
                    label: '归档',
                    icon: 'pisell2-archive',
                    confirm: {
                        title: '确认归档',
                        description: '归档后的项将不再显示在列表中',
                        okText: '确认',
                        cancelText: '取消',
                    },
                    onClick: (keys) => {
                        message.success(`已归档 ${keys.length} 项`);
                    },
                },
            ]}
            onClear={() => setSelectedKeys([])}
            onDelete={(keys) => {
                message.success(`已删除 ${keys.length} 项`);
                setSelectedKeys([]);
            }}
        />
    );
};
```

### 不同布局模式

支持悬浮、吸顶、吸底、内嵌四种布局模式。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {Radio, Space} from 'antd';
import {useState} from 'react';

export default () => {
    const [position, setPosition] = useState('inline');
    const [selectedKeys] = useState(['1', '2', '3']);

    return (
        <Space direction="vertical" style={{width: '100%'}}>
            <Radio.Group value={position} onChange={(e) => setPosition(e.target.value)}>
                <Radio.Button value="inline">内嵌</Radio.Button>
                <Radio.Button value="sticky-top">吸顶</Radio.Button>
                <Radio.Button value="sticky-bottom">吸底</Radio.Button>
                <Radio.Button value="float">悬浮</Radio.Button>
            </Radio.Group>

            <div style={{height: 400, overflow: 'auto', border: '1px solid #d9d9d9', padding: 16}}>
                <PisellBatchActionBar
                    selectedKeys={selectedKeys}
                    position={position}
                    offset={position === 'float' ? 24 : 0}
                    onClear={() => {
                    }}
                />
                <div style={{height: 1000}}>滚动查看效果...</div>
            </div>
        </Space>
    );
};
```

### 溢出处理

当按钮数量超过阈值时，自动收纳到"更多"菜单。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            enableOverflow={true}
            overflowThreshold={5} // 超过5个按钮时收纳
            moreText="查看更多"
            actions={[
                {key: 'export', label: '导出', icon: 'pisell2-download-cloud-02'},
                {key: 'share', label: '分享', icon: 'pisell2-share-07'},
                {key: 'move', label: '移动', icon: 'pisell2-folder'},
                {key: 'copy', label: '复制', icon: 'pisell2-copy-06'},
                {key: 'archive', label: '归档', icon: 'pisell2-archive'},
                {key: 'tag', label: '打标签', icon: 'pisell2-tag-03'},
            ]}
            onClear={() => {
            }}
        />
    );
};
```

### 自定义选中数量文案

支持自定义选中数量的显示文案。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {Radio, Space} from 'antd';
import {useState} from 'react';

export default () => {
    const [textType, setTextType] = useState('default');
    const [selectedKeys] = useState(['1', '2', '3']);

    const getCountText = () => {
        if (textType === 'template') {
            return '共选择了 {count} 个项目';
        }
        if (textType === 'function') {
            return (count) => `您已选中 ${count} 项`;
        }
        return undefined; // 使用默认文案
    };

    return (
        <Space direction="vertical" style={{width: '100%'}}>
            <Radio.Group value={textType} onChange={(e) => setTextType(e.target.value)}>
                <Radio.Button value="default">默认文案</Radio.Button>
                <Radio.Button value="template">模板字符串</Radio.Button>
                <Radio.Button value="function">函数形式</Radio.Button>
            </Radio.Group>

      <PisellBatchActionBar
        selectedKeys={selectedKeys}
        position="inline"
        selectedCountText={getCountText()}
        onClear={() => {
        }}
      />
        </Space>
    );
};
```

### 按钮排序

通过 `actionOrder` 控制按钮的显示顺序。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            actions={[
                {key: 'export', label: '导出'},
                {key: 'share', label: '分享'},
                {key: 'move', label: '移动'},
            ]}
            // 指定按钮顺序
            actionOrder={['move', 'share', 'export']}
            onClear={() => {
            }}
        />
    );
};
```

### 隐藏默认按钮

可以选择性隐藏某些默认按钮。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            defaultActions={{
                showSelectAll: true,  // 显示全选
                showInvert: true,     // 显示反选
                showClear: true,      // 显示取消选择
                showDelete: false,    // 隐藏删除按钮
            }}
            onSelectAll={() => console.log('全选')}
            onInvert={() => console.log('反选')}
            onClear={() => {
            }}
        />
    );
};
```

### 完全隐藏默认按钮

如果只需要自定义操作按钮，可以完全隐藏默认按钮。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {message} from 'antd';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);

  return (
    <PisellBatchActionBar
      selectedKeys={selectedKeys}
      position="inline"
      defaultActions={{
        showDefaultActions: false, // 隐藏所有默认按钮
      }}
      actions={[
                {
                    key: 'export',
                    label: '导出选中项',
                    icon: 'pisell2-download-cloud-02',
                    onClick: (keys) => {
                        message.success(`导出 ${keys.length} 项`);
                    },
                },
                {
                    key: 'batch-edit',
                    label: '批量编辑',
                    icon: 'pisell2-edit-05',
                    onClick: (keys) => {
                        message.info(`编辑 ${keys.length} 项`);
                    },
                },
            ]}
        />
    );
};
```

### 自定义删除确认弹窗

配置删除按钮的确认弹窗内容。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {message} from 'antd';
import {useState} from 'react';

export default () => {
    const [selectedKeys, setSelectedKeys] = useState(['1', '2', '3']);

  return (
    <PisellBatchActionBar
      selectedKeys={selectedKeys}
      position="inline"
            deleteConfirmConfig={{
                title: '确认删除',
                description: '删除后将无法恢复，确定要删除选中的项吗？此操作不可撤销。',
                okText: '确定删除',
                cancelText: '我再想想',
            }}
            onDelete={(keys, rows) => {
                message.success(`已删除 ${keys.length} 项`);
                setSelectedKeys([]);
            }}
            onClear={() => setSelectedKeys([])}
        />
    );
};
```

### 按钮 Loading 状态

支持为操作按钮设置 loading 状态。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {message} from 'antd';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);
    const [loading, setLoading] = useState(false);

  return (
    <PisellBatchActionBar
      selectedKeys={selectedKeys}
      position="inline"
      actions={[
        {
          key: 'export',
          label: '导出',
          icon: 'pisell2-download-cloud-02',
          loading: loading,
          onClick: async (keys) => {
                        setLoading(true);
                        // 模拟异步操作
                        await new Promise((resolve) => setTimeout(resolve, 2000));
                        setLoading(false);
                        message.success(`导出完成`);
                    },
                },
            ]}
            onClear={() => {
            }}
        />
    );
};
```

### 完整示例

一个完整的批量操作场景示例。

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {Table, message} from 'antd';
import {useState} from 'react';

export default () => {
    const [dataSource, setDataSource] = useState([
        {id: '1', name: '商品 1', status: 'active', price: 99},
        {id: '2', name: '商品 2', status: 'active', price: 199},
        {id: '3', name: '商品 3', status: 'inactive', price: 299},
        {id: '4', name: '商品 4', status: 'active', price: 399},
        {id: '5', name: '商品 5', status: 'inactive', price: 499},
    ]);

    const [selectedRowKeys, setSelectedRowKeys] = useState([]);
    const [selectedRows, setSelectedRows] = useState([]);

    const columns = [
        {title: 'ID', dataIndex: 'id', key: 'id'},
        {title: '商品名称', dataIndex: 'name', key: 'name'},
        {
            title: '状态',
            dataIndex: 'status',
            key: 'status',
            render: (status) => (status === 'active' ? '上架' : '下架'),
        },
        {title: '价格', dataIndex: 'price', key: 'price'},
    ];

    return (
        <>
            <Table
                dataSource={dataSource}
                columns={columns}
                rowKey="id"
                rowSelection={{
                    selectedRowKeys,
                    onChange: (keys, rows) => {
                        setSelectedRowKeys(keys);
                        setSelectedRows(rows);
                    },
                }}
            />

            {selectedRowKeys.length > 0 && (
        <PisellBatchActionBar
          selectedKeys={selectedRowKeys}
          selectedRows={selectedRows}
          total={dataSource.length}
          position="inline"
          actions={[
                        {
                            key: 'activate',
                            label: '批量上架',
                            icon: 'pisell2-check-circle',
                            visible: (keys, rows) =>
                                rows?.some((row) => row.status === 'inactive'),
                            onClick: (keys, rows) => {
                                const newData = dataSource.map((item) =>
                                    keys.includes(item.id) ? {...item, status: 'active'} : item
                                );
                                setDataSource(newData);
                                message.success(`已上架 ${keys.length} 个商品`);
                            },
                        },
                        {
                            key: 'deactivate',
                            label: '批量下架',
                            icon: 'pisell2-x-circle',
                            visible: (keys, rows) =>
                                rows?.some((row) => row.status === 'active'),
                            onClick: (keys, rows) => {
                                const newData = dataSource.map((item) =>
                                    keys.includes(item.id) ? {...item, status: 'inactive'} : item
                                );
                                setDataSource(newData);
                                message.success(`已下架 ${keys.length} 个商品`);
                            },
                        },
                        {
                            key: 'export',
                            label: '导出',
                            icon: 'pisell2-download-cloud-02',
                            onClick: (keys, rows) => {
                                console.log('导出数据', rows);
                                message.success(`已导出 ${keys.length} 项`);
                            },
                        },
                    ]}
                    onSelectAll={() => {
                        const allKeys = dataSource.map((item) => item.id);
                        setSelectedRowKeys(allKeys);
                        setSelectedRows(dataSource);
                    }}
                    onInvert={() => {
                        const allKeys = dataSource.map((item) => item.id);
                        const invertedKeys = allKeys.filter((key) => !selectedRowKeys.includes(key));
                        const invertedRows = dataSource.filter((item) =>
                            invertedKeys.includes(item.id)
                        );
                        setSelectedRowKeys(invertedKeys);
                        setSelectedRows(invertedRows);
                    }}
                    onClear={() => {
                        setSelectedRowKeys([]);
                        setSelectedRows([]);
                    }}
                    onDelete={(keys, rows) => {
                        const newData = dataSource.filter((item) => !keys.includes(item.id));
                        setDataSource(newData);
                        setSelectedRowKeys([]);
                        setSelectedRows([]);
                        message.success(`已删除 ${keys.length} 项`);
                    }}
                />
            )}
        </>
    );
};
```

## API

### PisellBatchActionBar

| 参数                  | 说明             | 类型                                                                       | 默认值                 | 版本    |
|---------------------|----------------|--------------------------------------------------------------------------|---------------------|-------|
| selectedKeys        | 选中的 key 数组（必填） | `React.Key[]`                                                            | -                   | 1.0.0 |
| selectedRows        | 选中的行数据数组       | `any[]`                                                                  | -                   | 1.0.0 |
| total               | 总数据量           | `number`                                                                 | -                   | 1.0.0 |
| currentPageTotal    | 当前页数据量         | `number`                                                                 | -                   | 1.0.0 |
| currentPageKeys     | 当前页数据 key 数组   | `React.Key[]`                                                            | -                   | 1.0.0 |
| position            | 布局模式           | `'sticky-top' \| 'sticky-bottom' \| 'float' \| 'inline'`                 | `'float'`           | 1.0.0 |
| offset              | 吸顶/吸底/悬浮时的偏移量  | `number`                                                                 | `0`（吸顶/吸底）、`24`（悬浮） | 1.0.0 |
| showSelectedCount   | 是否显示选中数量提示     | `boolean`                                                                | `true`              | 1.0.0 |
| selectedCountText   | 选中数量提示文案       | `string \| ((count: number) => string)`                                  | 国际化文本               | 1.0.0 |
| defaultActions      | 默认操作按钮配置       | `DefaultActionsConfig`                                                   | 见下方                 | 1.0.0 |
| actions             | 自定义操作按钮配置      | `BatchActionItem[]`                                                      | `[]`                | 1.0.0 |
| actionOrder         | 操作按钮排序         | `string[]`                                                               | -                   | 1.0.0 |
| enableOverflow      | 是否启用溢出折叠       | `boolean`                                                                | `true`              | 1.0.0 |
| overflowThreshold   | 溢出折叠阈值（按钮数量）   | `number`                                                                 | `5`                 | 1.0.0 |
| moreText            | "更多"按钮文案       | `string`                                                                 | 国际化文本 `'更多'`        | 1.0.0 |
| className           | 自定义类名          | `string`                                                                 | -                   | 1.0.0 |
| style               | 自定义样式          | `CSSProperties`                                                          | -                   | 1.0.0 |
| onSelectAll         | 全选回调           | `() => void`                                                             | -                   | 1.0.0 |
| onInvert            | 反选回调           | `() => void`                                                             | -                   | 1.0.0 |
| onClear             | 清空选择回调         | `() => void`                                                             | -                   | 1.0.0 |
| onDelete            | 删除回调           | `(selectedKeys: React.Key[], selectedRows?: any[]) => void`              | -                   | 1.0.0 |
| deleteConfirmConfig | 删除确认弹窗配置       | `BatchActionConfirmConfig`                                               | 见下方                 | 1.0.0 |
| onActionClick       | 自定义操作按钮点击回调    | `(key: string, selectedKeys: React.Key[], selectedRows?: any[]) => void` | -                   | 1.0.0 |

### DefaultActionsConfig

默认操作按钮配置。

| 参数                 | 说明         | 类型        | 默认值    | 版本    |
|--------------------|------------|-----------|--------|-------|
| showDefaultActions | 是否显示所有默认按钮 | `boolean` | `true` | 1.0.0 |
| showSelectAll      | 是否显示全选按钮   | `boolean` | `true` | 1.0.0 |
| showInvert         | 是否显示反选按钮   | `boolean` | `true` | 1.0.0 |
| showClear          | 是否显示取消选择按钮 | `boolean` | `true` | 1.0.0 |
| showDelete         | 是否显示删除按钮   | `boolean` | `true` | 1.0.0 |

### BatchActionItem

自定义操作按钮配置。

| 参数        | 说明                             | 类型                                                                           | 默认值       | 版本    |
|-----------|--------------------------------|------------------------------------------------------------------------------|-----------|-------|
| key       | 操作唯一标识（必填）                     | `string`                                                                     | -         | 1.0.0 |
| label     | 按钮文案（必填）                       | `ReactNode`                                                                  | -         | 1.0.0 |
| icon      | 按钮图标                           | `ReactNode`                                                                  | -         | 1.0.0 |
| size      | 按钮尺寸                           | `'small' \| 'default' \| 'large'`                                            | `'small'` | 1.0.0 |
| disabled  | 是否禁用                           | `boolean \| ((selectedKeys: React.Key[], selectedRows?: any[]) => boolean)`  | `false`   | 1.0.0 |
| visible   | 是否显示                           | `boolean \| ((selectedKeys: React.Key[], selectedRows?: any[]) => boolean)`  | `true`    | 1.0.0 |
| loading   | 是否显示 loading 状态                | `boolean`                                                                    | `false`   | 1.0.0 |
| confirm   | 是否需要确认弹窗                       | `boolean \| BatchActionConfirmConfig`                                        | `false`   | 1.0.0 |
| style     | 自定义样式                          | `CSSProperties`                                                              | -         | 1.0.0 |
| className | 自定义类名                          | `string`                                                                     | -         | 1.0.0 |
| onClick   | 按钮点击回调（优先级高于组件级 onActionClick） | `(selectedKeys: React.Key[], selectedRows?: any[]) => void \| Promise<void>` | -         | 1.0.0 |

### BatchActionConfirmConfig

确认弹窗配置。

| 参数          | 说明     | 类型       | 默认值      | 版本    |
|-------------|--------|----------|----------|-------|
| title       | 弹窗标题   | `string` | `'确认操作'` | 1.0.0 |
| description | 弹窗描述内容 | `string` | -        | 1.0.0 |
| okText      | 确认按钮文案 | `string` | `'确定'`   | 1.0.0 |
| cancelText  | 取消按钮文案 | `string` | `'取消'`   | 1.0.0 |

## 注意事项

1. **selectedKeys 是必填参数**：组件依赖 `selectedKeys` 来感知选择状态，必须传入。

2. **默认按钮的显示控制**：
  - 通过 `defaultActions.showDefaultActions` 可以一次性隐藏所有默认按钮
  - 通过 `defaultActions.showSelectAll`、`showInvert`、`showClear`、`showDelete` 可以单独控制每个按钮的显示

3. **删除按钮的特殊行为**：删除按钮点击后会先弹出 Modal 确认弹窗，用户确认后才触发 `onDelete` 回调。

4. **自定义按钮的事件优先级**：如果 `action` 中配置了 `onClick`，会优先使用 `action.onClick`；否则使用组件级别的
   `onActionClick`。

5. **按钮的显隐和禁用支持动态判断**：`visible` 和 `disabled` 都支持函数形式，可以基于 `selectedKeys` 和 `selectedRows`
   动态判断。

6. **溢出处理逻辑**：当按钮总数（默认按钮 + 自定义按钮）超过 `overflowThreshold` 时，会自动将后面的按钮收纳到"更多"菜单。

7. **布局模式选择**：
  - `float`（悬浮）：固定在页面底部居中，适合全局批量操作
  - `sticky-top`（吸顶）：滚动时吸附在容器顶部
  - `sticky-bottom`（吸底）：滚动时吸附在容器底部
  - `inline`（内嵌）：作为普通元素嵌入文档流

8. **多语言支持**：组件内置国际化支持，会根据当前语言环境自动切换按钮文案。支持简体中文、英文、繁体中文。

9. **图标使用**：按钮图标使用 iconfont 字符串名称，如 `'pisell2-check-square'`。

10. **确认弹窗的两种方式**：
  - 默认删除按钮：使用 `Modal.confirm`，配置通过 `deleteConfirmConfig`
  - 自定义按钮：使用 `Popconfirm`，配置通过 `action.confirm`

## FAQ

### 如何与 Table 组件集成使用？

将 Table 的 `rowSelection.selectedRowKeys` 传递给 BatchActionBar 的 `selectedKeys`：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {Table} from 'antd';
import {useState} from 'react';

export default () => {
    const [selectedRowKeys, setSelectedRowKeys] = useState([]);
    const [selectedRows, setSelectedRows] = useState([]);

    return (
        <>
            <Table
                dataSource={[]}
                columns={[]}
                rowSelection={{
                    selectedRowKeys,
                    onChange: (keys, rows) => {
                        setSelectedRowKeys(keys);
                        setSelectedRows(rows);
                    },
                }}
            />

            <PisellBatchActionBar
                selectedKeys={selectedRowKeys}
                selectedRows={selectedRows}
                position="inline"
                onClear={() => setSelectedRowKeys([])}
            />
        </>
    );
};
```

### 如何实现只有选中项时才显示操作栏？

在外层添加条件渲染：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);

    return (
        <>
            {selectedKeys.length > 0 && (
                <PisellBatchActionBar
                    selectedKeys={selectedKeys}
                    position="inline"
                    onClear={() => {
                    }}
                />
            )}
        </>
    );
};
```

### 如何自定义删除确认弹窗的内容？

使用 `deleteConfirmConfig` 属性：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys, setSelectedKeys] = useState(['1', '2']);

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            deleteConfirmConfig={{
                title: '确认删除',
                description: '删除后将无法恢复，确定要删除吗？',
                okText: '确定删除',
                cancelText: '取消',
            }}
            onDelete={(keys) => {
                // 删除逻辑
                console.log('删除', keys);
                setSelectedKeys([]);
            }}
            onClear={() => setSelectedKeys([])}
        />
    );
};
```

### 如何隐藏某些默认按钮？

使用 `defaultActions` 配置：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            defaultActions={{
                showDelete: false, // 隐藏删除按钮
            }}
            onClear={() => {
            }}
        />
    );
};
```

### 如何让某个按钮只在选中单项时显示？

使用 `visible` 函数：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1']);

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            actions={[
                {
                    key: 'edit',
                    label: '编辑',
                    visible: (keys) => keys.length === 1,
                },
            ]}
            onClear={() => {
            }}
        />
    );
};
```

### 如何实现异步操作的 Loading 状态？

使用 `loading` 属性配合 `useState`：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [loading, setLoading] = useState(false);
    const [selectedKeys] = useState(['1', '2']);

    const exportData = async (keys) => {
        // 模拟导出操作
        return new Promise((resolve) => setTimeout(resolve, 2000));
    };

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            actions={[
                {
                    key: 'export',
                    label: '导出',
                    loading: loading,
                    onClick: async (keys) => {
                        setLoading(true);
                        await exportData(keys);
                        setLoading(false);
                    },
                },
            ]}
            onClear={() => {
            }}
        />
    );
};
```

### 如何控制按钮的显示顺序？

使用 `actionOrder` 属性：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            actions={[
                {key: 'export', label: '导出'},
                {key: 'share', label: '分享'},
                {key: 'move', label: '移动'},
            ]}
            actionOrder={['move', 'export', 'share']}
            onClear={() => {
            }}
        />
    );
};
```

### 如何禁用溢出处理？

设置 `enableOverflow={false}`：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys] = useState(['1', '2']);

    const manyActions = [
        {key: 'action1', label: '操作1'},
        {key: 'action2', label: '操作2'},
        {key: 'action3', label: '操作3'},
        {key: 'action4', label: '操作4'},
        {key: 'action5', label: '操作5'},
        {key: 'action6', label: '操作6'},
    ];

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            enableOverflow={false}
            actions={manyActions}
            onClear={() => {
            }}
        />
    );
};
```

### 删除按钮和自定义删除按钮有什么区别？

- **默认删除按钮**：使用 `Modal.confirm`，样式为危险按钮（红色），配置通过 `deleteConfirmConfig`
- **自定义删除按钮**：使用 `Popconfirm`，样式可自定义，配置通过 `action.confirm`

建议使用默认删除按钮，样式更统一。

### 如何实现反选功能？

在 `onInvert` 回调中实现反选逻辑：

```tsx
import {PisellBatchActionBar} from '@pisell/materials';
import {useState} from 'react';

export default () => {
    const [selectedKeys, setSelectedKeys] = useState(['1', '2']);

    const dataSource = [
        {id: '1', name: '商品1'},
        {id: '2', name: '商品2'},
        {id: '3', name: '商品3'},
        {id: '4', name: '商品4'},
    ];

    return (
        <PisellBatchActionBar
            selectedKeys={selectedKeys}
            position="inline"
            onInvert={() => {
                const allKeys = dataSource.map((item) => item.id);
                const invertedKeys = allKeys.filter((key) => !selectedKeys.includes(key));
                setSelectedKeys(invertedKeys);
            }}
            onClear={() => setSelectedKeys([])}
        />
    );
};
```

### 组件支持哪些语言？

组件内置国际化支持，支持：

- 简体中文（zh-CN）
- 英文（en-US）
- 繁体中文（zh-TW、zh-HK）

会根据当前语言环境自动切换按钮文案。
