@xwink/ui

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 等)已导出,宿主自写手势时复用同一套。