Transfer
穿梭框,双栏列表间移动条目,支持多选、移动按钮、本地搜索过滤、分组(groupList)、树状源面板(treeList)、单向迁移(oneWay)、目标列拖拽重排(draggable)、虚拟化(virtualize)与远程搜索(onSearch)。
如何引入
import { Transfer } from '@chenzy-design/svelte';基础用法
平铺列表穿梭框,支持搜索过滤。
可选城市 3 项
已选城市 1 项
分组数据
type='groupList':源数据按分组渲染分组头与计数。
可选城市 7 项
- 3
- 2
- 2
已选城市 2 项
- 1
- 1
自定义渲染 / 禁用项
renderSourceItem / renderSelectedItem 自定义行内容,disabled 标记不可迁移项,onSelect / onDeselect 跟踪勾选。
可选成员 4 项
已选成员 1 项
- 贝拉 · 前端
树状面板 / 显示路径
type='treeList' 树状源面板,勾父连带勾叶;showPath 让已选项显示完整路径。
地区树 5 项
已选(含路径) 1 项
分页 / 自定义空态
pagination 让源面板分页,emptyContent 自定义两侧空态文案。
可选(28 项 / 分页) 28 项
已选 0 项
- 尚未选择任何项
命令式搜索
通过 bind:this 获取实例,调用 search(value) 过滤左侧。
可选水果 5 项
已选水果 0 项
- 暂无数据
树默认收起
treeProps.expandAll=false 初始收起子节点。
地区树(默认收起) 5 项
已选 0 项
- 暂无数据
树自定义搜索
treeProps.filterTreeNode 自定义树搜索逻辑。
地区树 4 项
已选 0 项
- 暂无数据
完整示例
分组、树状面板、单向迁移、虚拟化、拖拽重排、远程搜索等高级用法。
可选城市 3 项
已选城市 1 项
可选城市 4 项
- 2
- 2
已选城市 1 项
- 1
可选城市 5 项
已选城市 1 项
可选城市 3 项
已选城市 1 项
- 上海
可选(2000) 2000 项
已选 0 项
- 暂无数据
可选城市 0 项
- 暂无数据
已选(可拖拽) 4 项
远程结果 8 项
已选 0 项
- 暂无数据
API 参考
Transfer
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
value | 受控已选 key 数组;提供则为受控 | (string|number)[] | undefined |
defaultValue | 非受控初始已选 key | (string|number)[] | [] |
dataSource | 平铺条目(key/label/disabled/group)、分组结构 {title, items}[],或树结构 {key,label,children}[](treeList);树模式下源面板按树渲染,仅叶子可迁移到平铺目标面板,已迁移叶子在源树置灰 | TransferItem[] | TransferGroup[] | TransferTreeNode[] | [] |
filter | 是否显示本地搜索框 | boolean | true |
searchPlaceholder | — | string | '搜索' |
size | — | 'small'|'default'|'large' | default |
status | — | 'default'|'warning'|'error' | default |
disabled | — | boolean | false |
showPanelTitle | 是否显示面板标题与计数 | boolean | true |
titles | — | [string, string] | ['源', '已选'] |
oneWay | 单向迁移:仅左→右;目标项各带「移除」按钮移回左侧,不显示右→左批量按钮 | boolean | false |
draggable | 目标(已选)列项可鼠标拖拽重排(HTML5 DnD);新顺序经 reorder 纯函数算出仅通过 onChange 通知,受控 value 不回写 | boolean | false |
virtualize | 虚拟化两侧平铺面板:大数据下仅渲染视口内项(复用 core fixedRange);分组/树源面板回退全量渲染 | boolean | false |
itemHeight | 虚拟化行高(px),需与实际行高一致 | number | 32 |
onSearch | 远程搜索:提供后切换远程模式,输入防抖(searchDebounce ms)回调并由外部更新 dataSource,本地不再过滤 | (query: string, direction: 'left'|'right') => void | undefined |
loading | 远程加载中:每侧列表顶部显示 spinner 行 | boolean | false |
searchDebounce | onSearch 防抖毫秒 | number | 300 |
onChange | — | (targetKeys: (string|number)[]) => void | undefined |
type | 数据形态:平铺/分组/树 | 'list'|'groupList'|'treeList' | 'list' |
emptyContent | 自定义空态 | { left?: Snippet|string; right?: Snippet|string; search?: Snippet|string } | undefined |
inputProps | 透传给搜索框 Input 的额外参数 | object | undefined |
treeProps | type=treeList 时透传给内部树:filterTreeNode 自定义搜索、defaultExpandedKeys 初始展开、expandAll 默认全展开 | { filterTreeNode?; defaultExpandedKeys?; expandAll? } | undefined |
showPath | type=treeList 时右侧已选项显示完整路径 | boolean | false |
pagination | 左侧面板分页(仅 list/groupList) | { pageSize?: number; currentPage?: number; defaultCurrentPage?: number; onPageChange?: (page) => void } | undefined |
onSelect | 勾选单项时回调 | (item: TransferItem) => void | undefined |
onDeselect | 取消勾选单项时回调 | (item: TransferItem) => void | undefined |
renderSourceItem | 自定义左侧条目渲染 | Snippet<[{item, onChange, checked}]> | undefined |
renderSelectedItem | 自定义右侧条目渲染 | Snippet<[{item, onRemove, sortableHandle}]> | undefined |
renderSourceHeader | 自定义左侧面板头部 | Snippet<[SourceHeaderProps]> | undefined |
renderSelectedHeader | 自定义右侧面板头部 | Snippet<[SelectedHeaderProps]> | undefined |
renderSourcePanel | 完全自定义左侧面板 | Snippet<[SourcePanelProps]> | undefined |
renderSelectedPanel | 完全自定义右侧面板 | Snippet<[SelectedPanelProps]> | undefined |
Methods
| 属性 | 类型 | 说明 |
|---|---|---|
search(value) | — | 命令式搜索:把值置给左侧搜索框并触发过滤(对齐 Semi) |
Accessibility
| ARIA role | group |
| APG | dual-listbox |
- 容器 role=group;每侧平铺列表 role=listbox + aria-multiselectable,aria-labelledby 指向栏标题
- 条目 role=option + aria-selected + aria-disabled,roving tabindex(每个 listbox 单一 Tab 停靠点)
- 列内键盘:↑↓ 漫游、Home/End 跳首末、Space 切换勾选、Shift+↑↓/Shift+Click 范围选择、Enter 移动到对侧
- 移动后焦点保留在源列表相邻 option;移动经 useLiveAnnouncer 播报
- 移动按钮有 aria-label;分组/树面板保留原 Checkbox 语义
设计变量
| 变量 | 默认值 | 用法 |
|---|---|---|
--cd-color-transfer-close-icon-icon | var(--cd-color-text-2) | 穿梭框关闭按钮颜色 |
--cd-color-transfer-empty-text | var(--cd-color-text-2) | 穿梭框空状态文字颜色 |
--cd-color-transfer-group-title-text | var(--cd-color-text-2) | 穿梭框分组标题文字颜色 |
--cd-color-transfer-header-text | var(--cd-color-text-2) | 穿梭框 header 文字颜色 |
--cd-transfer-item-bg-checked | var(--cd-color-primary-light-default) | 选项行 aria-selected 背景(组件消费) |
--cd-transfer-item-bg-hover | var(--cd-color-fill-0) | 条目悬浮背景(组件消费) |
--cd-transfer-item-disabled-text | var(--cd-color-disabled-text) | 禁用选项行文字(组件消费) |
--cd-transfer-panel-border | var(--cd-color-border) | 面板描边(组件消费) |
--cd-transfer-panel-header-bg | var(--cd-color-fill-0) | 面板头部背景(组件消费) |