Figma 穿梭框与双向数据转移系统(Transfer & Dual Listbox Architecture)组件架构实战:从左右双列表响应式布局、穿梭操作控制栏、搜索过滤与分页联动到 Variables 状态机与 Dev Mode 前端 Ant Design / Element Plus 代码交付
一、引言与架构全景:为什么企业级复杂权限系统必须依赖穿梭框(Transfer)? #
在企业级中后台管理系统、SaaS 多租户平台以及安全合规中控台中,管理员经常需要处理大规模对象集合的双向划分与授权。典型场景包括:
- RBAC 角色权限分配:为某个业务角色分配几十甚至上百个系统操作权限节点;
- 用户群组/部门调动:将多名员工批量从一个协作部门移动至另一个跨职能项目组;
- 数据报表自定义分析列挑选:从上百个业务度量与维度字段中,挑选出 10 个作为核心大盘展示列,并调整呈现顺序;
- 云资产与主机分配:为特定虚拟私有云(VPC)划分绑定的弹性计算实例(ECS)。
面对多达几十到上百个候选对象的交互场景,普通的下拉选择框(Select)或多选复选框组(Checkbox Group)会瞬间遭遇严重的可用性瓶颈:用户无法直观对比“哪些已选、哪些未选”,且长列表滚动极易遗漏已选状态。
穿梭框(Transfer / Dual Listbox) 通过直观的左右双列并排结构,将“待选数据源(Source Pool)”与“已选目标池(Target Pool)”彻底物理隔离,中间配以双向移动控制按钮,成为解决海量复杂多选与数据转移的工业级标准解法。
为了构建严谨高可用、在设计端与前端研发端完全同构的 Transfer 组件,我们需要建立清晰的四层架构模型:
+------------------------------------------------------------------------+
| Figma 穿梭框系统(Transfer Architecture)四层拓扑结构 |
+------------------------------------------------------------------------+
| 1. 左右双列表容器层 (Dual List Containers & Viewport Layer) |
| - 左右等宽等高响应式布局 (Auto Layout Fill / Min-Width 240px) |
| - 列表头部汇总条 (Header: Select All Checkbox + Item Counter N/Total)|
| - 列表搜索插槽 (Search Input Slot: 关键字即时过滤与高亮) |
| - 列表内容视口 (Scrollable Body: 虚拟滚动/分页导轨/空状态提示) |
+------------------------------------------------------------------------+
| 2. 中央穿梭控制器层 (Transfer Action Control Column) |
| - 双向转移操作按钮组 (To Right >, To Left <, Move All >> / <<) |
| - 动态激活/禁用状态机 (根据左右 Checked 数量动态开关交互) |
| - 垂直居中吸附微架构 (Auto Layout Center Alignment) |
+------------------------------------------------------------------------+
| 3. 穿梭项目与勾选状态机层 (Transfer Item & Selection State Layer) |
| - 项目原子组件 (Checkbox + Icon/Avatar + Text + Subtext + Drag Handle)|
| - 4 种交互状态 (Default / Hover / Checked / Disabled 锁定态) |
| - 目标池排序手柄 (Sortable Handle: 已选结果集的自定义排序) |
+------------------------------------------------------------------------+
| 4. 变量驱动与 Dev Mode 交付层 (Variables & Engineering Handoff Layer) |
| - Figma Variables 状态机 (sourceChecked, targetChecked 响应式联动) |
| - 语义化 Tokens (border-transfer, bg-header, item-hover-bg) |
| - Ant Design Transfer / Element Plus el-transfer 生产级组件交付 |
+------------------------------------------------------------------------+
二、左右双列表与中央控制器的 Auto Layout 几何与对齐模型 #
穿梭框是一个典型的三栏复合组件(左列表 + 中间控制器 + 右列表)。在 Figma 中运用 Auto Layout 自动布局 搭建时,必须精准掌控尺寸约束与对齐规则。
1. 三栏响应式栅格布局(Three-Column Layout) #
- 外层容器约束:创建一个横向排列的 Auto Layout Frame,
Direction: Horizontal,Gap: 16px,Alignment: Center(垂直居中对齐); - 左右列表面板(Source & Target Panels):
- 宽度策略:在固定宽度设计中设为
Fixed: 260px或280px;在响应式布局中设为Fill container,并配置最小宽度约束(Min-width: 200px),确保左右两列等宽伸缩; - 高度策略:通常采用固定视口高度(如
Fixed: 320px或360px),内部列表项超出时开启滚动裁剪(Figma 勾选Clip content,原型配置Vertical scrolling); - 边框与圆角:绑定标准边框颜色(
border-subtle),配置1px实线边框与radius-md: 6px圆角;
- 宽度策略:在固定宽度设计中设为
- 中央控制器操作栏(Action Column):
- 设为纵向排列的 Auto Layout Frame,
Direction: Vertical,Gap: 8px,Alignment: Center,尺寸设为Hug contents; - 默认包含两个主按钮:右移按钮(
>)与左移按钮(<),采用小号紧凑型图标按钮(32px * 32px正方形,详见专文 Figma 企业级通用按钮系统架构实战)。
- 设为纵向排列的 Auto Layout Frame,
2. 列表面板内部垂直架构(Panel Vertical Breakdown) #
每个列表面板内部自上而下严格划分为 4 个块级区域:
- 列表头部汇总条(Header Bar):
- 包含全选复选框(Checkbox,详见专文 Figma 开关复选框单选框原子组件架构实战)、标题文本(如“待选用户列表”/“已选人员”)以及计数器标牌(如
0/18 项或3/18 项); - 底部配置
1px水平分割线,背景填充中性弱对比浅底色(bg-subtle);
- 包含全选复选框(Checkbox,详见专文 Figma 开关复选框单选框原子组件架构实战)、标题文本(如“待选用户列表”/“已选人员”)以及计数器标牌(如
- 搜索输入框插槽(Search Input Slot):
- 采用紧凑型输入框(高度
28px或32px),带放大镜搜索图标与一键清空按钮,方便在海量条目中快速检索关键字;
- 采用紧凑型输入框(高度
- 列表滚动主体(List Scroll Body):
- 垂直排列穿梭项目(Transfer Item),设为
Fill container宽度与Fill container剩余高度;当数据为空时切换为 空状态反馈组件;
- 垂直排列穿梭项目(Transfer Item),设为
- 底部自定义操作栏(Footer Slot - 可选):
- 用于放置“一键全选”、“批量刷新”或数据同步分页控件。
三、穿梭项目(Transfer Item)状态拓扑与交互矩阵 #
穿梭列表项(Transfer Item)是承载实体数据的基本原子。每个列表项都必须具备完善的状态反馈与边界处理机制。
1. 列表项原子层级结构 #
列表项采用横向 Auto Layout,Height: 36px,Padding: 0 12px,包含以下组成部分:
- 多选复选框(Checkbox Slot):支持
Unchecked(未选)、Checked(已勾选)与Disabled(已禁用); - 图标/头像槽(Avatar / Icon Slot - 可选):用于展示用户头像、部门图标或系统文件类型标识;
- 主标题文本(Primary Label):文字图层设为
Fill container并开启单行截断(Truncate text with ellipsis),防止长文本撑爆列表面板; - 副文本/描述信息(Description Text - 可选):展示工号、邮箱或所属上级组织信息;
- 拖拽排序手柄(Drag Handle - 仅限右侧已选池):六点拖拽手柄图标,允许用户上下拖动重排已选条目的最终展示顺序。
2. 列表项状态拓扑矩阵 #
| 交互状态 (State) | 背景填充 (Background) | 勾选框状态 (Checkbox) | 文本颜色 (Text Color) | 交互可用性 (Usability) |
|---|---|---|---|---|
| Normal (常规未选) | 透明 transparent | 未选中 Unchecked | 主文本色 text-primary | 鼠标悬停变色,点击勾选 |
| Hover (鼠标悬停) | 弱中性色 bg-hover (#F5F5F5) | 未选中 Unchecked | 主文本色 text-primary | 提示可点击交互热区 |
| Checked (选中激活) | 品牌极浅蓝 bg-brand-soft (#E6F4FF) | 已选中 Checked (带 Check 图标) | 品牌主色 text-brand-primary | 激活中央对应方向移动按钮 |
| Disabled (禁用锁定) | 透明 transparent | 禁用灰 Disabled | 禁用灰 text-disabled (#BFBFBF) | 不可点击、不可移动、忽略全选 |
3. 企业级多选组件选型对比表 #
| 对比维度 | 穿梭框 (Transfer) | 树选择器 (TreeSelect) | 级联选择器 (Cascader) |
|---|---|---|---|
| 核心数据拓扑 | 扁平或轻量分组的两级集合(无深层递归) | 具有无限层级归属的树状逻辑(父子节点) | 线性层级递进链路(如省-市-区-街道) |
| 数据源规模 | 中大数量级(50 ~ 500+ 个候选条目) | 中数量级(10 ~ 200+ 树节点) | 规整多级字典(每级 5 ~ 30 个分支) |
| 待选 vs 已选隔离 | 物理左右双列完全隔离,一目了然 | 依靠顶部输入框内部折叠标签回显 | 依靠单行输入框面包屑回显选中路径 |
| 自定义重排支持 | 目标列表原生支持垂直拖拽调整最终次序 | 不支持已选条目二次排序 | 不支持已选路径重排 |
| 典型代表场景 | 角色权限授权、报表自定义列配置、设备分配 | 跨部门员工树、企业资产类目归属、多选权限 | 快递收发货地址选择、商品三级类目挂载 |
关于树选择器的深度架构实战,可参考专文 Figma 树选择器与多层级下拉树系统架构实战。
四、基于 Figma Variables 的双向数据转移状态机与交互原型 #
为了让设计方案在交互评审中不再只是静态图画,我们需要利用 Figma Variables 变量系统 建立双向数据流联动模型。
1. Variables 变量架构设计 #
在 Figma 文件的 Local Variables 中创建 Components/Transfer 变量集合:
| 变量名称 (Variable Name) | 变量类型 (Type) | 初始值 (Default) | 状态联动语义 |
|---|---|---|---|
transfer/sourceChecked | NUMBER | 0 | 左侧源列表当前被勾选的项目数量 |
transfer/targetChecked | NUMBER | 0 | 右侧目标列表当前被勾选的项目数量 |
transfer/sourceTotal | NUMBER | 8 | 左侧源列表待选项目总数 |
transfer/targetTotal | NUMBER | 3 | 右侧目标列表已选项目总数 |
transfer/isSearching | BOOLEAN | false | 是否处于搜索过滤筛选激活态 |
2. 中央控制按钮的交互状态机绑定 #
中央的转移操作按钮严格依赖数值变量驱动其可用性:
- 向右转移按钮(Move to Right
>):- 属性绑定:当
transfer/sourceChecked > 0时,按钮变体自动切换为State: Primary (Active);当transfer/sourceChecked === 0时,按钮自动切换为State: Disabled;
- 属性绑定:当
- 向左转移按钮(Move to Left
<):- 属性绑定:当
transfer/targetChecked > 0时,按钮切换为State: Primary (Active);当transfer/targetChecked === 0时切换为State: Disabled;
- 属性绑定:当
- 头部计数器动态回显:
- 左侧标题计数文本绑定表达式:
transfer/sourceChecked+"/"+transfer/sourceTotal+" 项"; - 右侧标题计数文本绑定表达式:
transfer/targetChecked+"/"+transfer/targetTotal+" 项"。
- 左侧标题计数文本绑定表达式:
3. 原型交互连线配置实操 #
- 列表项勾选触发:
- 为左侧列表项配置
On click交互事件:- 若当前未选,切换为选中变体,并执行动作 Set variable:
transfer/sourceChecked = transfer/sourceChecked + 1; - 若当前已选,切换为未选变体,并执行动作 Set variable:
transfer/sourceChecked = transfer/sourceChecked - 1;
- 若当前未选,切换为选中变体,并执行动作 Set variable:
- 为左侧列表项配置
- 点击中央右移按钮:
- 配置
On click事件:- 将左侧已选项目瞬间淡出并移至右侧面板;
- 执行动作 Set variable:
transfer/targetTotal = transfer/targetTotal + transfer/sourceChecked; - 执行动作 Set variable:
transfer/sourceTotal = transfer/sourceTotal - transfer/sourceChecked; - 重置计数器 Set variable:
transfer/sourceChecked = 0。
- 配置
通过这种状态机配置,原本繁杂的双向穿梭原型交互能够在 Figma 中如真实代码般行云流水地运行。
五、Design Tokens 规范字典与 Dev Mode 前端工程化交付 #
在 Figma 的 Dev Mode 下,工程师能够清晰查阅穿梭框所有边界约束、对齐参数与语义化 Design Tokens,彻底告别“开局一张图,尺寸全靠猜”的低效交付。
1. DTCG 规范设计令牌对照字典 #
| Token 语义名称 | 浅色模式值 (Light) | 深色模式值 (Dark) | 作用目标与 CSS 属性映射 |
|---|---|---|---|
color.transfer.border | #D9D9D9 | #424242 | border-color: 左右列表外层边框与分割线 |
color.transfer.header.bg | #FAFAFA | #1F1F1F | background-color: 列表头部汇总条背景 |
color.transfer.item.hover | #F5F5F5 | #262626 | background-color: 列表项鼠标悬停浅底色 |
color.transfer.item.active | #E6F4FF | #112A45 | background-color: 列表项选中状态浅蓝高亮底色 |
color.transfer.btn.bg.active | #1677FF | #1668DC | background-color: 中央转移按钮激活态背景 |
size.transfer.panel.minWidth | 240px | 240px | min-width: 列表面板最小保底宽度 |
size.transfer.panel.height | 320px | 320px | height: 列表主体视口固定高度 |
radius.transfer.container | 6px | 6px | border-radius: 列表面板外围圆角 |
2. Dev Mode 前端 React + Ant Design Transfer 规范交付代码 #
在前端工程中,直接对接 Ant Design 5.x 生产级穿梭框的代码范式如下:
import React, { useState } from 'react';
import { Transfer, Tag } from 'antd';
import type { TransferProps, TransferItem } from 'antd/es/transfer';
interface RecordType extends TransferItem {
key: string;
title: string;
description: string;
department: string;
disabled?: boolean;
}
const mockData: RecordType[] = [
{ key: '1', title: '左子祯 (zuozizhen)', description: '体验技术中台架构师', department: '技术部' },
{ key: '2', title: '李设计 (designer_li)', description: '设计系统主理人', department: 'UX团队' },
{ key: '3', title: '王产品 (pm_wang)', description: 'B2B 业务产品专家', department: '产品部' },
{ key: '4', title: '张安全 (sec_zhang)', description: '合规审计管理员', department: '安全部', disabled: true },
{ key: '5', title: '赵前端 (fe_zhao)', description: 'Dev Mode 工程推进者', department: '技术部' },
];
export const EnterpriseTransfer: React.FC = () => {
const [targetKeys, setTargetKeys] = useState<string[]>(['1']);
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
const handleChange: TransferProps<RecordType>['onChange'] = (newTargetKeys, direction, moveKeys) => {
console.log('数据流转方向:', direction, '移动键值:', moveKeys);
setTargetKeys(newTargetKeys);
};
const handleSelectChange: TransferProps<RecordType>['onSelectChange'] = (
sourceSelectedKeys,
targetSelectedKeys
) => {
setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
};
return (
<div className="enterprise-transfer-wrapper p-6 bg-white rounded-lg shadow-sm">
<h3 className="text-base font-semibold text-gray-800 mb-4">项目组协作人员授权分配</h3>
<Transfer
dataSource={mockData}
titles={['待选员工池', '已分配协作组']}
targetKeys={targetKeys}
selectedKeys={selectedKeys}
onChange={handleChange}
onSelectChange={handleSelectChange}
showSearch
filterOption={(inputValue, item) =>
item.title.toLowerCase().includes(inputValue.toLowerCase()) ||
item.description.toLowerCase().includes(inputValue.toLowerCase())
}
render={(item) => (
<div className="flex items-center justify-between py-1">
<span className="font-medium text-gray-700">{item.title}</span>
<Tag color="blue" className="mr-0 text-xs">
{item.department}
</Tag>
</div>
)}
listStyle={{
width: 300,
height: 380,
}}
operations={['加入协作 >', '< 移出协作']}
/>
</div>
);
};
更多关于组件设计系统落地、表格与复杂数据录入体系,可进一步阅读 Figma 复杂数据表格系统架构实战 与 Figma 常见报错排查手册。
核心手册与速查工具
高频手册与实用设计生产力工具直达常见问题与答疑 (FAQ)
高频疑难解析与避坑指南完全不需要。绝大多数核心功能在免费 Starter 计划中均可完整体验与实操练习,无需额外付费购买付费团队版。