Passing events data with create ref
@ankri @unloved
Hi guys, I followed a similar approach to make the user components dragged with an absolute position inside the editor. It works really well, but I am facing problems with setting a dynamic initial position as opposed to a static one when dragged from the left sidebar.
I tried various things including passing the pageX, pageY props from the toolbar component, something like:
<div onDragEnd={(event) => setPosition({ x: event.clientX, y: event.clientY})} ref={(ref) => create(ref, <SimpleCheckBox pageX={position.x} pageY={position.y} />)}>
<Tooltip title="Checkbox" placement="right">
<Item className="m-2 pb-2 cursor-pointer block" move>
<Check />
</Item>
</Tooltip>
</div>
This sets the state correctly, but the component gets dropped first in the editor. This causes the next component to be dropped to use the position set by the state earlier, but not the current one. What I want is that I could pass the dragend event data to the ref so that the current component could be loaded with a dynamic positioning as per the mouse pointer.
Here is my code of a simple user component created to drag/drop a checkbox:
import { useNode, useEditor } from '@craftjs/core';
import React, { useContext, useEffect, useState } from 'react';
import { SimpleCheckboxSettings } from './SimpleCheckboxSettings';
import Draggable from 'react-draggable';
import AuthContext from '../../../../../store/AuthContext';
import { Checkbox } from '@material-ui/core';
export type SimpleCheckBoxProps = {
checked: boolean;
pageX: number;
pageY: number;
user_id: number;
className: string;
};
export const SimpleCheckBox = ({
checked,
pageX,
pageY,
user_id,
className,
}: Partial<SimpleCheckBoxProps>) => {
const {
connectors: { connect },
actions,
} = useNode();
const { enabled } = useEditor((state) => ({
enabled: state.options.enabled
}));
const [disable, setDisable] = useState(true);
const [position, setPosition] = useState({ x: pageX, y: pageY });
const authCtx = useContext(AuthContext);
const current_user = authCtx.user()
const handleStop = (event: any, data: any) => {
setPosition({ x: data.x, y: data.y })
actions.setProp((props) => {
props.pageX = data.x;
props.pageY = data.y;
});
};
useEffect(() => {
// actions.setProp((prop) => {
// prop.user_id = user_id; }, 500);
if (user_id == current_user.id) {
setDisable(false)
}
}, [user_id])
return (
<Draggable disabled={!enabled} onStop={handleStop} defaultPosition={position}>
<Checkbox
ref={connect}
checked={checked}
className={`user-${user_id}`}
style={{
cursor: 'move',
position: 'absolute',
zIndex: 3
}}
onChange={(event) => {
if (user_id == current_user.id ) {
actions.setProp((prop) => {
prop.checked = !checked
}, 500)
}
}}
/>
</Draggable>
);
};
SimpleCheckBox.craft = {
displayName: 'CheckBox',
props: {
pageX: 0,
pageY: 0,
user_id: null,
className: 'fillable-textfield',
checked: false
},
rules: {
canDrag: () => true,
},
related: {
toolbar: SimpleCheckboxSettings,
},
};
Originally posted by @nickm89 in https://github.com/prevwong/craft.js/issues/32#issuecomment-1002949758
Hey, I'm trying to do the same thing. Did you get this to work somehow? @nickm89