Skip to content

Commit

Permalink
feat: automatically add position to scrollContainer during frame sele…
Browse files Browse the repository at this point in the history
…ction (#27)
  • Loading branch information
linxianxi authored Feb 1, 2024
1 parent 73a8460 commit b769781
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 16 deletions.
30 changes: 15 additions & 15 deletions docs/guides/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ nav: Get Started

### Selectable

| Property | Description | Type | Default |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | --------------- |
| defaultValue | Initial selected option | any[] | - |
| value | Current selected option | any[] | - |
| disabled | Whether to disable | boolean | false |
| mode | Selection mode | `add` \| `remove` \| `reverse` | `add` |
| items | The collection value of all items, only the virtual list needs to be passed | any[] | - |
| selectStartRange | Where to start with box selection | `all` \| `inside` \| `outside` | `all` |
| scrollContainer | Specify the scrolling container. After setting, the container needs to set `position` because the selection box is `absolute` and needs to be positioned relative to the container. | () => HTMLElement |
| dragContainer | Specify the container that can start dragging. If `scrollContainer` is set, please do not set it because the two should be equal in a scrollable container. | () => HTMLElement | scrollContainer |
| boxStyle | Selection box style | React.CSSProperties | - |
| boxClassName | Selection box className | string | - |
| compareFn | Because value supports any type, you may need to define a custom function for comparison. The default is `===` | (item: any, value: any) => boolean |
| onStart | Called when selection starts | () => void | - |
| onEnd | Called when selection ends | (selectingValue: any[], { added: any[], removed: any[] }) => void | - |
| Property | Description | Type | Default |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | --------------- |
| defaultValue | Initial selected option | any[] | - |
| value | Current selected option | any[] | - |
| disabled | Whether to disable | boolean | false |
| mode | Selection mode | `add` \| `remove` \| `reverse` | `add` |
| items | The collection value of all items, only the virtual list needs to be passed | any[] | - |
| selectStartRange | Where to start with box selection | `all` \| `inside` \| `outside` | `all` |
| scrollContainer | Specify the scrolling container | () => HTMLElement |
| dragContainer | Specify the container that can start dragging. If `scrollContainer` is set, please do not set it because the two should be equal in a scrollable container. | () => HTMLElement | scrollContainer |
| boxStyle | Selection box style | React.CSSProperties | - |
| boxClassName | Selection box className | string | - |
| compareFn | Because value supports any type, you may need to define a custom function for comparison. The default is `===` | (item: any, value: any) => boolean |
| onStart | Called when selection starts | () => void | - |
| onEnd | Called when selection ends | (selectingValue: any[], { added: any[], removed: any[] }) => void | - |

### useSelectable

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/api.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ nav: 快速上手
| mode | 模式 | `add` \| `remove` \| `reverse` | `add` |
| items | 全部 item 的集合值,只有虚拟列表时要传 | any[] | - |
| selectStartRange | 从哪里可以开始进行框选 | `all` \| `inside` \| `outside` | `all` |
| scrollContainer | 指定滚动的容器,设置后,容器需要设置 `position`,因为选择框是 `absolute` 要相对于容器定位 | () => HTMLElement |
| scrollContainer | 指定滚动的容器 | () => HTMLElement |
| dragContainer | 指定可以开始拖拽的容器, 如果设置了 `scrollContainer` 请不要设置,因为在可滚动容器中这两个应该相等 | () => HTMLElement | scrollContainer |
| boxStyle | 框选框的样式 | React.CSSProperties | - |
| boxClassName | 框选框的类名 | string | - |
Expand Down
7 changes: 7 additions & 0 deletions src/Selectable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ function Selectable<T>(

useEffect(() => {
let isMouseDowning = false;
let scrollContainerOriginPosition = '';

const reset = () => {
setIsDragging(false);
Expand Down Expand Up @@ -197,6 +198,10 @@ function Selectable<T>(
// https://github.com/linxianxi/react-selectable-box/issues/5
if (shouldDraggingStart && (boxWidth > 1 || boxHeight > 1)) {
setIsDragging(true);
scrollContainerOriginPosition = scrollContainer.style.position;
if (scrollContainer !== document.body && !scrollContainerOriginPosition) {
scrollContainer.style.position = 'relative';
}
handleStart();
}
}
Expand Down Expand Up @@ -234,6 +239,7 @@ function Selectable<T>(
scrollListenerElement.removeEventListener('scroll', onScroll);

if (isDraggingRef.current) {
scrollContainer.style.position = scrollContainerOriginPosition;
cancelScroll();
setValue(selectingValue.current);
handleEnd();
Expand Down Expand Up @@ -266,6 +272,7 @@ function Selectable<T>(
dragContainer.addEventListener('touchstart', onMouseDown);

return () => {
scrollContainer.style.position = scrollContainerOriginPosition;
cancelScroll();
dragContainer.removeEventListener('mousedown', onMouseDown);
dragContainer.removeEventListener('touchstart', onMouseDown);
Expand Down

0 comments on commit b769781

Please sign in to comment.