@@ -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 */
1213export 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