ToolJet/frontend/src/Editor/EditorSelecto.jsx

115 lines
3.4 KiB
JavaScript

import React, { useCallback, memo } from 'react';
import Selecto from 'react-selecto';
import { useEditorStore } from '@/_stores/editorStore';
import { shallow } from 'zustand/shallow';
import { setMultipleComponentsSelected } from '@/_helpers/appUtils';
const EditorSelecto = ({ selectionRef, canvasContainerRef, setSelectedComponent, selectionDragRef }) => {
const { setSelectionInProgress, currentPageId, appDefinition } = useEditorStore(
(state) => ({
setSelectionInProgress: state?.actions?.setSelectionInProgress,
currentPageId: state?.currentPageId,
appDefinition: state?.appDefinition,
}),
shallow
);
const scrollOptions = {
container: canvasContainerRef.current,
throttleTime: 30,
threshold: 0,
};
const onAreaSelectionStart = useCallback(() => {
setSelectionInProgress(true);
}, [setSelectionInProgress]);
const onAreaSelection = useCallback((e) => {
e.added.forEach((el) => {
el.classList.add('resizer-select');
});
if (useEditorStore.getState().selectionInProgress) {
e.removed.forEach((el) => {
el.classList.remove('resizer-select');
});
}
e.removed.forEach((el) => {
el.classList.remove('resizer-select');
});
}, []);
const onAreaSelectionEnd = useCallback(
(e) => {
setSelectionInProgress(false);
const selectedItems = [];
e.selected.forEach((el, index) => {
const id = el.getAttribute('widgetid');
const component = appDefinition.pages[currentPageId].components[id].component;
const isMultiSelect = e.inputEvent.shiftKey || (!e.isClick && index != 0);
if (e.selected.length > 0 && !e.isClick) {
selectedItems.push({
id,
component,
});
} else {
setSelectedComponent(id, component, isMultiSelect);
}
});
if (selectedItems.length > 0) {
setMultipleComponentsSelected(selectedItems);
}
},
[appDefinition, currentPageId, setSelectedComponent, setSelectionInProgress]
);
const onAreaSelectionDragStart = useCallback(
(e) => {
if (e.inputEvent.target.getAttribute('id') !== 'real-canvas') {
selectionDragRef.current = true;
} else {
selectionDragRef.current = false;
}
},
[selectionDragRef]
);
const onAreaSelectionDrag = useCallback(
(e) => {
if (selectionDragRef.current) {
e.stop();
useEditorStore.getState().selectionInProgress && setSelectionInProgress(false);
}
},
[setSelectionInProgress, selectionDragRef]
);
const onAreaSelectionDragEnd = () => {
selectionDragRef.current = false;
useEditorStore.getState().selectionInProgress && setSelectionInProgress(false);
};
return (
<>
<Selecto
dragContainer={'.canvas-container'}
selectableTargets={['.moveable-box']}
hitRate={0}
selectByClick={true}
toggleContinueSelect={['shift']}
ref={selectionRef}
scrollOptions={scrollOptions}
onSelectStart={onAreaSelectionStart}
onSelectEnd={onAreaSelectionEnd}
onSelect={onAreaSelection}
onDragStart={onAreaSelectionDragStart}
onDrag={onAreaSelectionDrag}
onDragEnd={onAreaSelectionDragEnd}
onScroll={(e) => {
canvasContainerRef.current.scrollBy(e.direction[0] * 10, e.direction[1] * 10);
}}
/>
</>
);
};
export default memo(EditorSelecto);