Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0a147b4

Browse files
fix drag selection in editor
1 parent702a961 commit0a147b4

File tree

2 files changed

+88
-83
lines changed

2 files changed

+88
-83
lines changed

‎client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx‎

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export const CanvasView = React.memo((props: ContainerBaseProps) => {
9898
constisPreviewTheme=useContext(ThemeContext)?.themeId==='preview-theme';
9999
consteditorState=useContext(EditorContext);
100100
const[dragSelectedComps,setDragSelectedComp]=useState<Set<string>>(newSet());
101+
constcurrentSelectionRef=useRef<Set<string>>(newSet());
101102
constscrollContainerRef=useRef<HTMLDivElement>(null);
102103
constmountedRef=useRef(true);
103104
constappSettings=editorState.getAppSettings();
@@ -108,9 +109,15 @@ export const CanvasView = React.memo((props: ContainerBaseProps) => {
108109
return()=>{
109110
mountedRef.current=false;
110111
setDragSelectedComp(newSet());
112+
currentSelectionRef.current=newSet();
111113
};
112114
},[]);
113115

116+
// Keep ref in sync with state
117+
useEffect(()=>{
118+
currentSelectionRef.current=dragSelectedComps;
119+
},[dragSelectedComps]);
120+
114121
// Memoized drag selection handler
115122
consthandleDragSelection=useCallback((checkSelectFunc?:CheckSelectFn)=>{
116123
if(!mountedRef.current)returnnewSet<string>();
@@ -135,6 +142,25 @@ export const CanvasView = React.memo((props: ContainerBaseProps) => {
135142
returnselectedComps;
136143
},[props.items,props.layout]);
137144

145+
consthandleMouseMove=useCallback((checkSelectFunc:CheckSelectFn)=>{
146+
if(mountedRef.current){
147+
constselectedName=handleDragSelection(checkSelectFunc);
148+
setDragSelectedComp(newSet(selectedName));
149+
}
150+
},[handleDragSelection]);
151+
152+
consthandleMouseUp=useCallback(()=>{
153+
if(mountedRef.current){
154+
constcurrentSelection=newSet(currentSelectionRef.current);
155+
setDragSelectedComp(newSet());
156+
editorState.setSelectedCompNames(currentSelection);
157+
}
158+
},[editorState]);
159+
160+
consthandleMouseDown=useCallback(()=>{
161+
setDragSelectedComp(newSet());
162+
},[]);
163+
138164
constmaxWidth=useMemo(
139165
()=>appSettings.maxWidth??maxWidthFromHook,
140166
[appSettings,maxWidthFromHook]
@@ -277,25 +303,6 @@ export const CanvasView = React.memo((props: ContainerBaseProps) => {
277303
rowHeight:parseInt(defaultRowHeight),
278304
}),[props.positionParams,defaultGrid,defaultRowHeight]);
279305

280-
// Memoized mouse event handlers
281-
consthandleMouseDown=useCallback(()=>{
282-
setDragSelectedComp(newSet());
283-
},[]);
284-
285-
consthandleMouseUp=useCallback(()=>{
286-
if(mountedRef.current){
287-
editorState.setSelectedCompNames(dragSelectedComps);
288-
setDragSelectedComp(newSet());
289-
}
290-
},[editorState,dragSelectedComps]);
291-
292-
consthandleMouseMove=useCallback((checkSelectFunc:CheckSelectFn)=>{
293-
if(mountedRef.current){
294-
constselectedName=handleDragSelection(checkSelectFunc);
295-
setDragSelectedComp(selectedName);
296-
}
297-
},[handleDragSelection]);
298-
299306
if(readOnly){
300307
return(
301308
<UICompContainer

‎client/packages/lowcoder/src/comps/comps/gridLayoutComp/dragSelector.tsx‎

Lines changed: 62 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import{Layers}from"constants/Layers";
2-
importReact,{ReactNode,useCallback,useRef,useState,useEffect}from"react";
2+
importReact,{ReactNode,useCallback,useRef,useEffect}from"react";
33

44
exporttypeCheckSelectFn=(
55
item?:HTMLDivElement|null,
@@ -41,7 +41,7 @@ const createInitialState = (): SectionState => ({
4141

4242
exportconstDragSelector=React.memo((props:SectionProps)=>{
4343
constselectAreaRef=useRef<HTMLDivElement>(null);
44-
const[state,setState]=useState<SectionState>(createInitialState());
44+
conststateRef=useRef<SectionState>(createInitialState());
4545
constmountedRef=useRef(true);
4646

4747
// Cleanup on unmount
@@ -54,18 +54,62 @@ export const DragSelector = React.memo((props: SectionProps) => {
5454
};
5555
},[]);
5656

57+
constrectIntersect=useCallback((
58+
selectionBox:Rect|undefined,
59+
item:HTMLElement|null|undefined
60+
):boolean=>{
61+
if(!selectionBox||!item||!selectAreaRef.current)returnfalse;
62+
63+
constcontainerRect=selectAreaRef.current.getBoundingClientRect();
64+
constitemBox={
65+
top:item.getBoundingClientRect().top-containerRect.top,
66+
left:item.getBoundingClientRect().left-containerRect.left,
67+
width:item.getBoundingClientRect().width,
68+
height:item.getBoundingClientRect().height,
69+
};
70+
71+
return(
72+
selectionBox.left<=itemBox.left+itemBox.width&&
73+
selectionBox.left+selectionBox.width>=itemBox.left&&
74+
selectionBox.top<=itemBox.top+itemBox.height&&
75+
selectionBox.top+selectionBox.height>=itemBox.top
76+
);
77+
},[]);
78+
79+
constcalculateSelectionBox=useCallback((startPoint:Point|undefined,endPoint:Point)=>{
80+
if(!stateRef.current.mouseDown||!startPoint||!endPoint)returnundefined;
81+
82+
return{
83+
left:Math.min(startPoint.x,endPoint.x),
84+
top:Math.min(startPoint.y,endPoint.y),
85+
width:Math.abs(startPoint.x-endPoint.x),
86+
height:Math.abs(startPoint.y-endPoint.y),
87+
};
88+
},[]);
89+
90+
constchildrenViewCheckFunc=useCallback((
91+
item?:HTMLDivElement|null,
92+
afterCheck?:(checkResult:boolean)=>void
93+
)=>{
94+
constresult=rectIntersect(stateRef.current.selectionBox,item);
95+
if(afterCheck){
96+
afterCheck(result);
97+
}
98+
returnresult;
99+
},[rectIntersect]);
100+
57101
consthandleMouseMove=useCallback((e:MouseEvent)=>{
58-
if(!mountedRef.current||!state.mouseDown)return;
102+
if(!mountedRef.current||!stateRef.current.mouseDown)return;
59103

60104
constendPoint={
61105
x:e.pageX-(selectAreaRef.current?.getBoundingClientRect().left??0),
62106
y:e.pageY-(selectAreaRef.current?.getBoundingClientRect().top??0),
63107
};
64108

65-
setState(prevState=>({
66-
...prevState,
67-
selectionBox:calculateSelectionBox(prevState.startPoint,endPoint),
68-
}));
109+
stateRef.current={
110+
...stateRef.current,
111+
selectionBox:calculateSelectionBox(stateRef.current.startPoint,endPoint),
112+
};
69113

70114
// Clean up selection properly
71115
constselection=window.getSelection();
@@ -74,83 +118,37 @@ export const DragSelector = React.memo((props: SectionProps) => {
74118
}
75119

76120
props.onMouseMove(childrenViewCheckFunc);
77-
},[state.mouseDown,state.startPoint,props.onMouseMove]);
121+
},[props.onMouseMove,calculateSelectionBox,childrenViewCheckFunc]);
78122

79123
consthandleMouseUp=useCallback(()=>{
80-
if(!mountedRef.current)return;
81-
82124
window.document.removeEventListener("mousemove",handleMouseMove);
83125
window.document.removeEventListener("mouseup",handleMouseUp);
84126
props.onMouseUp();
85-
setState(createInitialState());
127+
stateRef.current=createInitialState();
86128
},[handleMouseMove,props.onMouseUp]);
87129

88130
consthandleMouseDown=useCallback((e:React.MouseEvent<HTMLDivElement>)=>{
89-
if(!mountedRef.current||e.button===2||e.nativeEvent.which===2)return;
131+
if(e.button===2||e.nativeEvent.which===2)return;
90132

91133
conststartPoint={
92134
x:e.pageX-(selectAreaRef.current?.getBoundingClientRect().left??0),
93135
y:e.pageY-(selectAreaRef.current?.getBoundingClientRect().top??0),
94136
};
95137

96-
setState({
138+
stateRef.current={
97139
mouseDown:true,
98140
startPoint,
99141
selectionBox:undefined,
100142
appendMode:false,
101-
});
143+
};
102144

103145
window.document.addEventListener("mousemove",handleMouseMove);
104146
window.document.addEventListener("mouseup",handleMouseUp);
105147
props.onMouseDown();
106148
},[handleMouseMove,handleMouseUp,props.onMouseDown]);
107149

108-
constrectIntersect=useCallback((
109-
selectionBox:Rect|undefined,
110-
item:HTMLElement|null|undefined
111-
):boolean=>{
112-
if(!selectionBox||!item||!selectAreaRef.current)returnfalse;
113-
114-
constcontainerRect=selectAreaRef.current.getBoundingClientRect();
115-
constitemBox={
116-
top:item.getBoundingClientRect().top-containerRect.top,
117-
left:item.getBoundingClientRect().left-containerRect.left,
118-
width:item.getBoundingClientRect().width,
119-
height:item.getBoundingClientRect().height,
120-
};
121-
122-
return(
123-
selectionBox.left<=itemBox.left+itemBox.width&&
124-
selectionBox.left+selectionBox.width>=itemBox.left&&
125-
selectionBox.top<=itemBox.top+itemBox.height&&
126-
selectionBox.top+selectionBox.height>=itemBox.top
127-
);
128-
},[]);
129-
130-
constchildrenViewCheckFunc=useCallback((
131-
item?:HTMLDivElement|null,
132-
afterCheck?:(checkResult:boolean)=>void
133-
)=>{
134-
constresult=rectIntersect(state.selectionBox,item);
135-
if(afterCheck){
136-
afterCheck(result);
137-
}
138-
returnresult;
139-
},[state.selectionBox,rectIntersect]);
140-
141-
constcalculateSelectionBox=useCallback((startPoint:Point|undefined,endPoint:Point)=>{
142-
if(!state.mouseDown||!startPoint||!endPoint)returnundefined;
143-
144-
return{
145-
left:Math.min(startPoint.x,endPoint.x),
146-
top:Math.min(startPoint.y,endPoint.y),
147-
width:Math.abs(startPoint.x-endPoint.x),
148-
height:Math.abs(startPoint.y-endPoint.y),
149-
};
150-
},[state.mouseDown]);
151-
152150
constrenderSelectionBox=useCallback(()=>{
153-
if(!state.mouseDown||!state.startPoint||!state.selectionBox||!selectAreaRef.current){
151+
if(!stateRef.current.mouseDown||!stateRef.current.startPoint||!stateRef.current.selectionBox||!selectAreaRef.current){
154152
returnnull;
155153
}
156154

@@ -160,14 +158,14 @@ export const DragSelector = React.memo((props: SectionProps) => {
160158
background:"rgba(51, 119, 255, 0.1)",
161159
position:"absolute",
162160
zIndex:Layers.dragSelectBox,
163-
left:state.selectionBox.left,
164-
top:state.selectionBox.top,
165-
height:state.selectionBox.height,
166-
width:state.selectionBox.width,
161+
left:stateRef.current.selectionBox.left,
162+
top:stateRef.current.selectionBox.top,
163+
height:stateRef.current.selectionBox.height,
164+
width:stateRef.current.selectionBox.width,
167165
}}
168166
/>
169167
);
170-
},[state.mouseDown,state.startPoint,state.selectionBox]);
168+
},[]);
171169

172170
return(
173171
<div

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp