useCollectionSelect
网格 / 列表的多选手势,Finder 与 iOS 相册的合集。CardList 的多选就是它,别的列表(表格行、自写的虚拟列表)也能直接用:项上标 data-select-key,勾选圈标 data-select-toggle。
- 点:选择模式里点一项加减它;Shift 点从锚点连到它;⌘ / Ctrl 点加减它。模式外带修饰键点直接进选择模式,普通点归宿主。模式里项内的按钮也算选这一项,输入框照常用。
- 划选:选择模式里按住一项划过去,起点到当前项按列表次序连成一段,起点原本选中就是取消,划回来恢复。触屏上横着起手才算,竖着起手照常滚动(容器要
touch-action: pan-y)。 - 框选:从容器空白处按下拖出矩形,碰到的都选上并进选择模式;Shift 加选、⌘ / Ctrl 取反。触屏不框选。
- 贴边自动滚动:划选、框选时指针贴近容器上下边就滚,越贴越快。
- 键盘:
onKeydown交给宿主挂在面板上——⌘ / Ctrl + A 全选并进模式,Esc 退出模式。用掉的键只preventDefault,宿主的全局快捷键照样收得到。
退出选择模式清空选中;列表变了(筛选)选中跟着收,批量操作只作用于筛选结果。宿主的原生拖放(draggable)在选择模式里要关掉,否则按住一挪就成了拖放、轮不到划选。
ts
import { useCollectionSelect } from '@xwink/ui'
const { marquee, selectAll, invert, onKeydown } = useCollectionSelect({
container: scroller, // 滚动容器:框选从它的空白处开始,贴边时自动滚它
keys: () => visible.value.map((it) => it.id), // 已渲染的,次序即连选次序
all: () => allIds.value, // 全部可选的(含没加载的),全选 / 反选按它算;缺省同 keys
active: selecting, // Ref<boolean>:选择模式
selected, // Ref<Set<string>>
})
marquee 是框选矩形(容器内容坐标,随内容滚动),在容器里放一个绝对定位的层照它画。
演示
在 XCardList 里:点、划、框选与批量操作栏
点卡片「打开」:无
素材 1
素材 2
素材 3
素材 4
素材 5
素材 6
素材 7
素材 8
素材 9
素材 10
素材 11
素材 12
素材 13
素材 14
素材 15
素材 16
素材 17
素材 18
素材 19
素材 20
没有更多了
选项
| 选项 | 说明 |
|---|---|
container | 滚动容器的 ref |
keys | 已渲染项的键;点选、划选、框选只认它们 |
all | 全部可选的键;全选、反选、清理筛掉的选中按它算,缺省同 keys |
active | 选择模式(Ref<boolean>) |
selected | 选中集合(Ref<Set<string>>) |
attribute | 项元素上标键的属性,缺省 data-select-key |
threshold | 按下后挪多远才算拖(px),缺省 4 |
手势判定的纯逻辑(clickSelect / swipeSelect / marqueeSelect / rangeKeys / invertSelection / edgeScrollSpeed 等)已导出,宿主自写手势时复用同一套。