selecto
selecto copied to clipboard
Not working with CSS modules
Environments
- Framework name: React
- Framework version: 18.2.0
- Component name: Selecto
- Component version: 1.26.1
Description
I cannot seem to get Selecto working when class names are populated from a CSS module using Vite. Maybe I am missing something obvious? Thanks!
Also, I am still learning how to use your libraries. They are great! If you have a moment, could you please answer these questions?
- I noticed that the selected border and circle do not move with the target when the canvas scrolls. Any idea why?
- How can I disable the border and/or circle on selected targets?
- If I have content above or left of the viewer, I noticed that the blue drag selection is offset. How can I fix this? I fixed it with
rootContainer={viewerRef.current?.getElement() || document.body}
, but this feels messy. - Is it possible to implement a coordinate system in Infinite Viewer?
import classes from './Canvas.module.scss';
const Canvas = ((): React.ReactNode => {
const moveableRef: React.RefObject<Moveable> = useRef<Moveable>(null);
const selectoRef: React.RefObject<Selecto> = useRef<Selecto>(null);
const viewerRef: React.RefObject<InfiniteViewer> = useRef<InfiniteViewer>(null);
const [targets, setTargets] = useState<(HTMLElement | SVGElement)[]>([]);
useEffect((): void => {
viewerRef.current!.scrollCenter();
}, []);
return (
<div className={classes['Canvas']}>
<Moveable
ref={moveableRef}
target={targets}
draggable
onClickGroup={(event: OnClickGroup): void => {
selectoRef.current!.clickTarget(event.inputEvent, event.inputTarget);
}}
onRender={(event: OnRender): void => {
event.target.style.cssText += event.cssText;
}}
onRenderGroup={(event: OnRenderGroup): void => {
for(const subEvent of event.events) {
subEvent.target.style.cssText += subEvent.cssText;
}
}}/>
<Selecto
ref={selectoRef}
dragContainer={classes['Canvas__viewer']}
selectableTargets={[`.${classes['viewport']} > .${classes['target']}`]}
hitRate={0}
selectByClick
selectFromInside={false}
toggleContinueSelect="shift"
ratio={0}
keyContainer={window}
scrollOptions={{
container: ((): HTMLElement => viewerRef.current!.getElement()),
getScrollPosition: ((): [number, number] => [viewerRef.current!.getScrollLeft(), viewerRef.current!.getScrollTop()]),
throttleTime: 30,
threshold: 0
}}
onSelect={(event: OnSelect): void => {
console.log(event);
for(const added of event.added) {
added.classList.add('selected');
}
for(const removed of event.removed) {
removed.classList.remove('selected');
}
}}
onScroll={(event: OnScroll): void => {
viewerRef.current!.scrollBy((event.direction[0]! * 10), (event.direction[1]! * 10));
}}
onDragStart={(event: OnDragStart): void => {
const target: any = event.inputEvent.target;
if(moveableRef.current!.isMoveableElement(target) || targets.some((existingTarget: (HTMLElement | SVGElement)): boolean =>
((existingTarget === target) || (existingTarget.contains(target))))) {
event.stop();
}
}}
onSelectEnd={(event: OnSelectEnd): void => {
if(event.isDragStartEnd) {
event.inputEvent.preventDefault();
moveableRef.current!.waitToChangeTarget()
.then((): void => {
moveableRef.current!.dragStart(event.inputEvent);
});
}
setTargets(event.selected);
}}/>
<InfiniteViewer
ref={viewerRef}
className={classes['Canvas__viewer']!}
displayHorizontalScroll
displayVerticalScroll
onScroll={(): void => {
selectoRef.current!.checkScroll();
}}>
<div className={classes['viewport']}>
<div className={classes['target']}>Target</div>
</div>
</InfiniteViewer>
</div>
);
});
.Canvas {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
> .Canvas__viewer {
position: relative;
width: 100%;
height: 100%;
.viewport {
> .target {
width: 100px;
height: 100px;
box-sizing: border-box;
line-height: 100px;
text-align: center;
background-color: #ee8;
&.selected {
background-color: #4af;
}
}
}
}
}
Hi, it is common to put a moveable in the viewport.
The reason it doesn't follow the scroll is because the moveable is not within the scroll area. The following structure is recommended.
https://daybrush.com/moveable/storybook/?path=/story/combination-with-other-components--components-infinite-viewer
-
<Canvas>
- =>
<Selector />
- =>
<InfiniteViewer>
- ==>
<div class="viewport">
- ===>
<Moveable />
if you hide target rect line (blue line) or origin dot (red circle)
hideDefaultLines={true}
origin={false}
rootContainer is the correct way to use it in general.
rootContainer={() => viewerRef.current?.getElement() || document.body}