1- import { useState , useMemo , useRef , useCallback , useEffect } from 'react' ;
1+ import { useState , useMemo , useEffect } from 'react' ;
22import { useWritableProp } from '@svar-ui/lib-react' ;
3+ import { useDragEngine } from './splitEngine/useDragEngine' ;
34import './Resizer.css' ;
45
56function Resizer ( props ) {
@@ -13,114 +14,48 @@ function Resizer(props) {
1314 containerWidth = 0 ,
1415 leftThreshold = 50 ,
1516 rightThreshold = 50 ,
17+ containerRef,
1618 } = props ;
1719
18- const [ value , setValue ] = useWritableProp ( props . value ?? 0 ) ;
20+ const [ value ] = useWritableProp ( props . value ?? 0 ) ;
1921 const [ display , setDisplay ] = useWritableProp ( props . display ?? 'all' ) ;
2022
21- function getBox ( val ) {
22- let offset = 0 ;
23- if ( position == 'center' ) offset = size / 2 ;
24- else if ( position == 'before' ) offset = size ;
25-
26- const box = {
27- size : [ size + 'px' , 'auto' ] ,
28- p : [ val - offset + 'px' , '0px' ] ,
29- p2 : [ 'auto' , '0px' ] ,
30- } ;
31-
32- if ( dir != 'x' ) {
33- for ( let name in box ) box [ name ] = box [ name ] . reverse ( ) ;
34- }
35- return box ;
36- }
37-
38- const [ active , setActive ] = useState ( false ) ;
3923 const [ initialPosition , setInitialPosition ] = useState ( null ) ;
40-
41- const startRef = useRef ( 0 ) ;
42- const posRef = useRef ( ) ;
43- const timeoutRef = useRef ( ) ;
44- const displayRef = useRef ( display ) ;
45-
46- useEffect ( ( ) => {
47- displayRef . current = display ;
48- } , [ display ] ) ;
24+ const [ fps , setFps ] = useState ( null ) ;
4925
5026 useEffect ( ( ) => {
5127 if ( initialPosition === null && value > 0 ) {
5228 setInitialPosition ( value ) ;
5329 }
5430 } , [ initialPosition , value ] ) ;
5531
56- function getEventPos ( ev ) {
57- return dir == 'x' ? ev . clientX : ev . clientY ;
58- }
59-
60- const move = useCallback (
61- ( ev ) => {
62- const newPos = posRef . current + getEventPos ( ev ) - startRef . current ;
63-
64- setValue ( newPos ) ;
65- let nextDisplay ;
66-
67- if ( newPos <= leftThreshold ) {
68- nextDisplay = 'chart' ;
69- } else if ( containerWidth - newPos <= rightThreshold ) {
70- nextDisplay = 'grid' ;
71- } else {
72- nextDisplay = 'all' ;
73- }
74-
75- if ( displayRef . current !== nextDisplay ) {
76- setDisplay ( nextDisplay ) ;
77- displayRef . current = nextDisplay ;
78- }
79-
80- if ( timeoutRef . current ) clearTimeout ( timeoutRef . current ) ;
81- timeoutRef . current = setTimeout ( ( ) => onMove && onMove ( newPos ) , 100 ) ;
82- } ,
83- [ containerWidth , leftThreshold , rightThreshold , onMove ] ,
84- ) ;
85-
86- const up = useCallback ( ( ) => {
87- document . body . style . cursor = '' ;
88- document . body . style . userSelect = '' ;
89- setActive ( false ) ;
90- window . removeEventListener ( 'mousemove' , move ) ;
91- window . removeEventListener ( 'mouseup' , up ) ;
92- } , [ move ] ) ;
93-
94- const cursor = useMemo (
95- ( ) => ( display !== 'all' ? 'auto' : dir == 'x' ? 'ew-resize' : 'ns-resize' ) ,
96- [ display , dir ] ,
97- ) ;
98-
99- const down = useCallback (
100- ( ev ) => {
101- // Prevent dragging when in normal mode and only one view is visible
102- if ( ! compactMode && ( display === 'grid' || display === 'chart' ) ) {
103- return ;
104- }
105-
106- startRef . current = getEventPos ( ev ) ;
107-
108- posRef . current = value ;
109- setActive ( true ) ;
110-
111- document . body . style . cursor = cursor ;
112- document . body . style . userSelect = 'none' ;
113-
114- window . addEventListener ( 'mousemove' , move ) ;
115- window . addEventListener ( 'mouseup' , up ) ;
32+ // ── New RAF-based drag engine ────────────────────────────────────────
33+ const { active, onPointerDown } = useDragEngine ( {
34+ value,
35+ containerWidth,
36+ leftThreshold,
37+ rightThreshold,
38+ onMove,
39+ onDisplayChange : ( nextDisplay ) => {
40+ setDisplay ( nextDisplay ) ;
41+ onDisplayChange && onDisplayChange ( nextDisplay ) ;
11642 } ,
117- [ cursor , move , up , value , compactMode , display ] ,
118- ) ;
43+ onFps : import . meta. env . DEV ? setFps : undefined ,
44+ containerRef,
45+ } ) ;
46+
47+ // Guard: prevent drag when collapsed in non-compact mode
48+ const handlePointerDown = ( e ) => {
49+ if ( ! compactMode && ( display === 'grid' || display === 'chart' ) ) {
50+ return ;
51+ }
52+ onPointerDown ( e ) ;
53+ } ;
11954
55+ // ── Expand / Collapse button handlers (UNCHANGED) ────────────────────
12056 function resetToInitial ( ) {
12157 setDisplay ( 'all' ) ;
12258 if ( initialPosition !== null ) {
123- setValue ( initialPosition ) ;
12459 if ( onMove ) onMove ( initialPosition ) ;
12560 }
12661 }
@@ -150,8 +85,32 @@ function Resizer(props) {
15085 handleExpand ( 'right' ) ;
15186 }
15287
88+ // ── Sizing / cursor (UNCHANGED) ──────────────────────────────────────
89+ function getBox ( val ) {
90+ let offset = 0 ;
91+ if ( position == 'center' ) offset = size / 2 ;
92+ else if ( position == 'before' ) offset = size ;
93+
94+ const box = {
95+ size : [ size + 'px' , 'auto' ] ,
96+ p : [ val - offset + 'px' , '0px' ] ,
97+ p2 : [ 'auto' , '0px' ] ,
98+ } ;
99+
100+ if ( dir != 'x' ) {
101+ for ( let name in box ) box [ name ] = box [ name ] . reverse ( ) ;
102+ }
103+ return box ;
104+ }
105+
106+ const cursor = useMemo (
107+ ( ) => ( display !== 'all' ? 'auto' : dir == 'x' ? 'ew-resize' : 'ns-resize' ) ,
108+ [ display , dir ] ,
109+ ) ;
110+
153111 const b = useMemo ( ( ) => getBox ( value ) , [ value , position , size , dir ] ) ;
154112
113+ // ── Render (UNCHANGED JSX structure) ────────────────────────────────
155114 const rootClassName = [
156115 'wx-resizer' ,
157116 `wx-resizer-${ dir } ` ,
@@ -164,7 +123,7 @@ function Resizer(props) {
164123 return (
165124 < div
166125 className = { 'wx-pFykzMlT ' + rootClassName }
167- onMouseDown = { down }
126+ onPointerDown = { handlePointerDown }
168127 style = { { width : b . size [ 0 ] , height : b . size [ 1 ] , cursor } }
169128 >
170129 < div className = "wx-pFykzMlT wx-button-expand-box" >
@@ -182,6 +141,24 @@ function Resizer(props) {
182141 </ div >
183142 </ div >
184143 < div className = "wx-pFykzMlT wx-resizer-line" > </ div >
144+ { import . meta. env . DEV && active && fps !== null && (
145+ < div style = { {
146+ position : 'fixed' ,
147+ bottom : 8 ,
148+ right : 8 ,
149+ background : 'rgba(0,0,0,0.75)' ,
150+ color : '#0f0' ,
151+ fontSize : 11 ,
152+ fontFamily : 'monospace' ,
153+ padding : '2px 6px' ,
154+ borderRadius : 4 ,
155+ pointerEvents : 'none' ,
156+ whiteSpace : 'nowrap' ,
157+ zIndex : 9999 ,
158+ } } >
159+ { fps } fps
160+ </ div >
161+ ) }
185162 </ div >
186163 ) ;
187164}
0 commit comments