Skip to content

Commit d6adde6

Browse files
committed
improvement(home): use pointer events for resize handle (touch + mouse support)
1 parent af49953 commit d6adde6

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

apps/sim/app/workspace/[workspaceId]/home/home.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export function Home({ chatId }: HomeProps = {}) {
138138
useChatHistory(chatId)
139139
const { mutate: markRead } = useMarkTaskRead(workspaceId)
140140

141-
const { mothershipRef, handleResizeMouseDown, clearWidth } = useMothershipResize()
141+
const { mothershipRef, handleResizePointerDown, clearWidth } = useMothershipResize()
142142

143143
const [isResourceCollapsed, setIsResourceCollapsed] = useState(true)
144144
const [isResourceAnimatingIn, setIsResourceAnimatingIn] = useState(false)
@@ -473,7 +473,7 @@ export function Home({ chatId }: HomeProps = {}) {
473473
role='separator'
474474
aria-orientation='vertical'
475475
aria-label='Resize resource panel'
476-
onMouseDown={handleResizeMouseDown}
476+
onPointerDown={handleResizePointerDown}
477477
/>
478478
</div>
479479
)}

apps/sim/app/workspace/[workspaceId]/home/hooks/use-mothership-resize.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,26 @@ import { MOTHERSHIP_WIDTH } from '@/stores/constants'
44
/**
55
* Hook for managing resize of the MothershipView resource panel.
66
*
7-
* Uses imperative DOM manipulation (zero React re-renders during drag).
8-
* Attach `mothershipRef` to the MothershipView root div and call
9-
* `handleResizeMouseDown` from the drag handle's onMouseDown.
7+
* Uses imperative DOM manipulation (zero React re-renders during drag) with
8+
* Pointer Events + setPointerCapture for unified mouse/touch/stylus support.
9+
* Attach `mothershipRef` to the MothershipView root div and bind
10+
* `handleResizePointerDown` to the drag handle's onPointerDown.
1011
* Call `clearWidth` when the panel collapses so the CSS class retakes control.
1112
*/
1213
export function useMothershipResize() {
1314
const mothershipRef = useRef<HTMLDivElement | null>(null)
1415
// Stored so the useEffect cleanup can tear down listeners if the component unmounts mid-drag
1516
const cleanupRef = useRef<(() => void) | null>(null)
1617

17-
const handleResizeMouseDown = useCallback((e: React.MouseEvent) => {
18+
const handleResizePointerDown = useCallback((e: React.PointerEvent) => {
1819
e.preventDefault()
1920

2021
const el = mothershipRef.current
2122
if (!el) return
2223

24+
const handle = e.currentTarget as HTMLElement
25+
handle.setPointerCapture(e.pointerId)
26+
2327
// Pin to current rendered width so drag starts from the visual position
2428
el.style.width = `${el.getBoundingClientRect().width}px`
2529

@@ -29,24 +33,29 @@ export function useMothershipResize() {
2933
document.body.style.cursor = 'ew-resize'
3034
document.body.style.userSelect = 'none'
3135

32-
const handleMouseMove = (moveEvent: MouseEvent) => {
36+
const handlePointerMove = (moveEvent: PointerEvent) => {
3337
const newWidth = window.innerWidth - moveEvent.clientX
3438
const maxWidth = window.innerWidth * MOTHERSHIP_WIDTH.MAX_PERCENTAGE
3539
el.style.width = `${Math.min(Math.max(newWidth, MOTHERSHIP_WIDTH.MIN), maxWidth)}px`
3640
}
3741

38-
const handleMouseUp = () => {
42+
const cleanup = () => {
3943
el.style.transition = prevTransition
4044
document.body.style.cursor = ''
4145
document.body.style.userSelect = ''
42-
document.removeEventListener('mousemove', handleMouseMove)
43-
document.removeEventListener('mouseup', handleMouseUp)
46+
handle.removeEventListener('pointermove', handlePointerMove)
47+
handle.removeEventListener('pointerup', handlePointerUp)
4448
cleanupRef.current = null
4549
}
4650

47-
cleanupRef.current = handleMouseUp
48-
document.addEventListener('mousemove', handleMouseMove)
49-
document.addEventListener('mouseup', handleMouseUp)
51+
const handlePointerUp = (upEvent: PointerEvent) => {
52+
handle.releasePointerCapture(upEvent.pointerId)
53+
cleanup()
54+
}
55+
56+
cleanupRef.current = cleanup
57+
handle.addEventListener('pointermove', handlePointerMove)
58+
handle.addEventListener('pointerup', handlePointerUp)
5059
}, [])
5160

5261
// Tear down any active drag if the component unmounts mid-drag
@@ -76,5 +85,5 @@ export function useMothershipResize() {
7685
mothershipRef.current?.style.removeProperty('width')
7786
}, [])
7887

79-
return { mothershipRef, handleResizeMouseDown, clearWidth }
88+
return { mothershipRef, handleResizePointerDown, clearWidth }
8089
}

0 commit comments

Comments
 (0)