react-simple-drag-selection
一个小的React拖拽选择库,具有鼠标,笔和触摸输入,帧批量更新和连续边缘滚动。React是它唯一的运行时依赖项。
安装
npm install @badasukerubin/react-simple-drag-selection
支持React 16.8, 17, 18和19在浏览器中的指针事件,DOMRect和requestAnimationFrame。在服务器上导入和呈现不访问DOM;手势在安装后附加。
使用
import { useContext, useRef } from "react";
import {
DragSelectionContext,
SelectionBox,
useDragSelected,
useDragSelection,
} from "@badasukerubin/react-simple-drag-selection";
function Item() {
const elementRef = useRef<HTMLDivElement>(null);
const selection = useContext(DragSelectionContext);
const selected = useDragSelected({ elementRef, selection });
return (
<div ref={elementRef} style={{ background: selected ? "#aac4ff" : "#eee" }}>
Select me
</div>
);
}
export function Example() {
const containerRef = useRef<HTMLDivElement>(null);
const boxRef = useRef<HTMLDivElement>(null);
const selection = useDragSelection({ containerRef, boxRef });
return (
<DragSelectionContext.Provider value={selection}>
<div ref={containerRef} style={{ height: 300, overflow: "auto" }}>
<SelectionBox ref={boxRef} />
<Item />
</div>
</DragSelectionContext.Provider>
);
}
渲染 SelectionBox 在同一文档中,通常在可选内容旁边或在React门户中。React在整个手势过程中保留元素的所有权。保持布局样式在容器上,视觉样式在盒子上。几何图形、显示、指针事件和定位由钩子管理。
useDragSelection
返回一个视图坐标 DOMRect | null,匹配 getBoundingClientRect().
| 选项 | 默认的 | 目的 |
|---|---|---|
containerRef | 要求 | 选择界面,包括其可滚动内容。支持可空引用。 |
scrollContainerRef | 无 | 当选择图面本身不滚动时,可选滚动祖先。 |
boxRef | 要求 | 裁判, SelectionBox 或同一文档中的等效div。 |
mouseMoveThreshold | 5 | 在绘制之前,运动必须在任何一个轴上超过这个距离。适用于鼠标,笔和触摸。 |
disabled | false | 禁用手势并清除矩形。 |
touch | true | 启用触摸选择并临时应用 touch-action: none 到集装箱。使用 false 保持原生触摸滚动。 |
autoScroll | true | 滚动容器的边缘。使用 false 或者 { edgeSize: 24, speed: 600 }. 距离以CSS像素为单位;速度是像素每秒。 |
ignoreSelector | 无 | 为不能启动手势的目标添加有效的CSS选择器。 |
shouldStartSelection | 无 | 返回 false 拒绝印刷拒绝印刷收到它 PointerEvent,包括修饰符键。 |
onSelectionStart | 无 | 在跨过门槛之前,在一个可以接受的媒体上打过一次电话。接收 PointerEvent. |
onSelection | 无 | 接收每个改变的矩形,每个动画帧最多一次,并在需要时释放最后一次刷新。 |
onSelectionEnd | 无 | 接收 { selection, cancelled, event } 发布或取消。 |
成功的释放会隐藏方框并保留最后的矩形。下一个被接受的媒体清除了它。低于移动阈值的普通点击保持原生点击行为。转义、指针取消、捕获丢失、第二个指针、窗口模糊、页面隐藏或原生HTML拖动都会取消手势并恢复之前的矩形。禁用、替换refs或卸载会在不调用应用程序回调的情况下删除手势。
回调使用最新提交的props。移动和滚动事件共享一个动画帧。当指针停留在某条边缘并在滚动限制处停止时,自动滚动继续;它只滚动配置的容器(或其显式的 scrollContainerRef 祖先)及其启用的溢出轴。祖先/窗口滚动更新锚。滚动偏移,边界,平移和正轴对齐缩放被考虑在内。
本地控件和拖放
输入、文本区、选择、按钮、链接、标签、摘要、可编辑内容和原生可拖动元素不能启动选择。的后裔 .ignore-drag-selection 和 [data-ignore-drag-selection] 也不包括SVG目标和打开阴影DOM事件路径。嵌套选择曲面将手势传递给最内层的接受曲面。
<div className="ignore-drag-selection">
<div draggable onDragStart={startNativeDrag}>
Drag this item
</div>
</div>
只有属于已完成拖动的单击被抑制。键盘单击、随后的指针按压和不相关的控件保持其正常行为。
修饰符和选择所有权
图书馆是长方形的;您的应用程序拥有项目标识,键盘导航,添加选择和范围选择。例如,使用 shouldStartSelection: event => !event.altKey 为其他交互保留Alt-drag。读 shiftKey, ctrlKey 和 metaKey 在 onSelectionStart 选择应用程序如何将手势的匹配与其现有选择组合在一起。使用按钮或其他键盘可访问的控件进行非指针选择;拖动选择不能是选择项的唯一方法。
useDragSelected
| 选项 | 默认的 | 目的 |
|---|---|---|
elementRef | 要求 | 可空引用item元素。在DOM提交之后读取。 |
selection | 要求 | 来自钩子/上下文的矩形,或者 null. |
collision | "intersect" | 使用 "contain" 要求矩形内的整个项目。 |
onSelected | 无 | 仅在成员关系发生变化(包括取消选择)时接收新的布尔值。 |
返回一个布尔值。隐藏的、零大小的元素和零面积的选择矩形不匹配。接触矩形边算作交集。保持项目ref在表示实际可选择区域的元素上。
虚拟列表只能测量挂载的项。当选择跨虚拟页面时,将选定的id存储在应用程序中,并对未挂载的项目使用列表的几何/模型。保留的矩形是几何形状,而不是持久的基于id的选择。旋转/倾斜坐标系统和跨原点iframe手势不在矩形命中测试模型中。 对于CSS油漆容器或堆叠上下文中的未剪切的覆盖,通过React门户将框渲染到该文档的主体中。
SelectionBox
接受普通的div props和转发ref。默认为一个隐藏的,固定的,非交互式的, aria-hidden 矩形。定制 className,背景,边框和z-index;保持钩子的定位和大小属性不受CSS影响 !important 覆盖。
主持人主题及色彩
主机提供它的解析 "light" 或者 "dark" 主题。两者都使用中性灰色:在浅色表面上使用深色填充/轮廓,在深色表面上使用浅色填充/轮廓。省略 theme 保留原有的光亮外观。该包不读取系统首选项、持久化主题或添加主题提供程序。
<SelectionBox ref={boxRef} theme={isDark ? "dark" : "light"} />
// Optional custom colors, independent of the theme:
<SelectionBox
ref={boxRef}
theme="dark"
backgroundColor="rgba(59, 130, 246, 0.2)"
accentColor="var(--selection-accent, #60a5fa)"
/>
| 道具 | 默认的 | 目的 |
|---|---|---|
theme | "light" | Host-resolved外观。传递主机的系统主题设置的已解析模式。 |
backgroundColor | 主题半透明中性 | 填充颜色。为透明度提供alpha; transparent 禁用填充。 |
accentColor | 主题的中性轮廓 | 轮廓的颜色;不对填充或选定项着色。 |
颜色道具接受CSS颜色,包括CSS变量。每个覆盖都是可选的;删除它将恢复主题默认值。显式的 style 重写优先(color 也覆盖了默认的大纲 currentColor). 在拖动过程中应用主题/颜色更改而无需重置所选内容。项目突出显示仍然由应用程序拥有。公共 SelectionBoxProps 和 SelectionBoxTheme 导出类型。
开发
使用Node.js 22.12或更新版本。
npm ci
npm run typecheck
npm test
npx playwright install chromium firefox webkit
npm run test:browser
npm pack
该浏览器套件在桌面版、平板纵向版、平板横向版和移动版以及Firefox和WebKit上都使用了Chromium内置的分布。触摸拖动是通过Chromium的实际输入协议来实现的。 BROWSER_CHANNEL=chrome npm run test:browser 为Chromium项目使用已安装的Chrome。 npm pack 在生成可分发tarball文件之前构建并检查类型。
这个 例子 使用本地包via file:... 先构建包,然后运行 npm ci 和 npm run dev 在 example. 在编辑包的源代码时重新生成包。
1.5版的变化
原始的hook、context、React peer range和final-rectangle行为仍然存在。指针事件取代了单独的鼠标/触摸监听器。交互式目标会被自动忽略,end回调只会对接受的手势触发 onSelected 报告转换的新值。看到 CHANGELOG.md 修复。