跳转到内容

穿梭框 transfer

数据录入组件。三层同源:无头内核给出解剖与状态机,Vue 组件与自定义元素只是它的两层外壳,行为完全一致。

示例

基础用法

collection 是条目全集的唯一事实源,value 只装落在右侧的那批

待选权限
新建
编辑
删除
导出
审计
已选权限
查看

已选:read

搜索过滤

searchable 给每侧配一个搜索框,筛剩下的才参与方向键、全选与搬运

待选城市
北京
上海
广州
深圳
杭州
成都
武汉
西安
已选城市

条目禁用

禁用写在 items 上:勾不动也搬不动,但仍可聚焦、仍是方向键的起点

待选
查看
新建
删除
已选
所有者(内置)

单向搬运

oneWay 把往回搬那条路整个封死,右侧不再接受勾选,往回的按钮也就不必写

可订阅指标
CPU 用量
内存用量
磁盘 IO
网络吞吐
请求量
已订阅

条目自定义内容

条目里长什么样归作者:勾选格与文本各就各位,前后再各加一段自己的标记

候选成员
林可前端工程师
周宁服务端工程师
秦朗测试工程师
许知产品经理
项目组
何雨交互设计

列表分组

面板插槽给出本侧此刻看得见的条目,据此分组渲染;小标题是普通节点,不入方向键也不入搬运

可授予
读取
查看详情
导出数据
写入
新建
编辑
删除
管理
授权
审计
已授予
读取
查看列表

一万条只渲可视区

面板插槽给的是本侧此刻看得见的全集,作者按滚动位置切一段挂出来,上下各留一个撑高块;全选、计数与搬运不读 DOM,照样管到窗口外

全部商品
商品 SKU-00001
商品 SKU-00002
商品 SKU-00004
商品 SKU-00005
商品 SKU-00006
商品 SKU-00007
商品 SKU-00008
商品 SKU-00009
商品 SKU-00010
商品 SKU-00011
商品 SKU-00012
商品 SKU-00013
商品 SKU-00014
商品 SKU-00015
本次上架
商品 SKU-00003

已上架 1 件

整块换档

面板高度、表头、条目行、勾选格与搬运按钮各是一个令牌,写在根上整块一起换档

紧凑

待选权限
新建
编辑
删除
导出
审计
已选权限
查看

宽松

待选权限
新建
编辑
删除
导出
审计
已选权限
查看

产物

自定义元素<xh-transfer>
Vue 组件XhTransferItem XhTransferItemCheckbox XhTransferItemText XhTransferList XhTransferPanelCount XhTransferPanelHeader XhTransferPanelTitle XhTransferRoot XhTransferSearch XhTransferSelectAllTrigger XhTransferSourcePanel XhTransferTargetPanel XhTransferToSourceTrigger XhTransferToTargetTrigger
组合式函数useTransfer
状态机transferMachine
皮肤@xihan-ui/styles/transfer.css

解剖

部件名即 data-part 属性值,也是皮肤的选择器。加粗的是必备部件,不渲染它组件不工作(Web Components 适配器会在诊断通道上报 wc.missing-part)。

data-scope="transfer"root · source-panel · target-panel · panel-header · panel-title · panel-count · search · list · item · item-text · item-checkbox · to-target-trigger · to-source-trigger · select-all-trigger

Props

属性类型必填说明
collectionTransferItem[]条目全集,元信息的唯一事实源。缺省为空。
valuestring[]落在 target 侧的值。给定即受控:cell 直读 prop,写只发 onValueChange 不落内部值。
defaultValuestring[]
selectedstring[]两侧合起来被勾中的值(用于搬运)。给定即受控,语义同上。
defaultSelectedstring[]
searchableboolean每侧带一个搜索框;关掉时搜索框仍在 DOM 里但带 hidden,且搜索串一律按空处理。
filterTransferFilter自定义匹配规则;缺省是标签大小写不敏感包含。
disabledboolean整个控件禁用:条目转 aria-disabled,三个按钮与搜索框用原生 disabled。
oneWayboolean只能往右不能往回:往回搬那条路整个封死,target 侧也不再接受勾选。
loopboolean列表内方向键走到尽头是否回绕,默认 true。
dirDirection文字方向,默认 ltr;决定列表内哪个横向方向键是"搬向对面"。
onValueChange(details: TransferValueChangeDetails) => void
onSelectionChange(details: TransferSelectionChangeDetails) => void

状态机

状态idle

事件VALUE.SET · SELECTED.SET · ITEM.TOGGLE · SIDE.TOGGLE_ALL · ITEMS.MOVE · SEARCH.SET · ITEM.FOCUS · LIST.BLUR

connect API

useTransfer 产出的对象。getXxxProps() 铺到对应部件的宿主元素上,其余是可读状态与操作入口。

成员类型说明
collectionreadonly TransferItem[]条目全集(作者给的那份,原样透出)。
valuestring[]落在 target 侧的值。
selectedstring[]两侧合起来被勾中的值。
disabledboolean
oneWayboolean
searchableboolean
visibleItems(side: TransferSide) => readonly TransferItem[]某一侧当下看得见的条目(分侧 + 搜索之后),顺序恒为 collection 原序。
checkedValues(side: TransferSide) => string[]某一侧此刻真正勾中的值(只算可见且未禁用的那些,与三态、搬运同一口径)。
checkState(side: TransferSide) => TransferCheckState
query(side: TransferSide) => string
canMove(to: TransferSide) => boolean往 to 侧搬此刻可不可行:对面有勾中的可操作条目,且这条路没被 oneWay 封死。
isChecked(value: string) => boolean
sideOf(value: string) => TransferSide
setValue(next: string[]) => void
setSelected(next: string[]) => void
setQuery(side: TransferSide, query: string) => void
toggle(value: string) => void
toggleAll(side: TransferSide) => void
move(to: TransferSide) => void程序化搬运;焦点安排不在这里做,那要知道是哪个节点触发的。
getRootProps() => T['element']
getPanelProps(props: TransferPanelProps) => T['element']
getPanelHeaderProps(props: TransferPanelProps) => T['element']
getPanelTitleProps(props: TransferPanelProps) => T['element']
getPanelCountProps(props: TransferPanelProps) => T['element']
getSearchProps(props: TransferPanelProps) => T['input']
getListProps(props: TransferPanelProps) => T['element']
getSelectAllTriggerProps(props: TransferPanelProps) => T['button']
getItemProps(props: TransferItemProps) => T['element']
getItemTextProps(props: TransferItemProps) => T['element']
getItemCheckboxProps(props: TransferItemProps) => T['element']
getToTargetTriggerProps() => T['button']
getToSourceTriggerProps() => T['button']

键盘

规格出处:W3C APG

按键生效条件行为
Tab / Shift+Tabfocus outside a list每一侧列表只占一个 Tab 位:焦点进入该侧锚点条目,无锚点时先落列表容器再由它转投;两个搬运按钮与两个全选格各自另占一位,禁用时自动退出 Tab 序列
ArrowDownfocus in a list焦点移到本侧下一个可停留条目(禁用项跳过、尽头按 loop 回绕);不会走到对面那一侧去
ArrowUpfocus in a list焦点移到本侧上一个可停留条目
Homefocus in a list焦点移到本侧首个可停留条目
Endfocus in a list焦点移到本侧末个可停留条目
Space / Enter / Ctrl+Spacefocus on item, 本侧可勾选切换焦点条目的勾选态,其余勾选不动;条目禁用、或已被搜索藏起来则不认
Shift+ArrowDown / Shift+ArrowUpfocus in a list, 本侧可勾选焦点移到相邻条目并切换它的勾选态;往回走即把刚扩进来的那个摘掉
Ctrl+A / Cmd+Afocus in a list, 本侧可勾选勾中本侧全部可操作条目(可见且未禁用);已经全勾则一并取消
ArrowRight / ArrowLeftfocus in a list, 该方向指向对面且对面搬得动把本侧勾中的条目搬到对面(dir=rtl 时左右语义对调);搬完焦点落到目的地那一侧的列表上。方向指向本侧、或此刻搬不动时这个键放行给页面
Enter / Spacefocus on to-target-trigger / to-source-trigger把对面勾中的条目搬过来(原生按钮的激活行为);搬完按钮多半随即变禁用,焦点改落到目的地那一侧的列表上
Enter / Spacefocus on select-all-trigger全选/取消全选该侧可操作条目(原生按钮的激活行为);三态经 aria-checked 上报,半选时是 mixed

Released under The MIT License