prevwong / craft.js

🚀 A React Framework for building extensible drag and drop page editors
https://craft.js.org
MIT License
7.56k stars 736 forks source link

Passing events data with create ref #357

Open nickm89 opened 2 years ago

nickm89 commented 2 years ago

@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

wilhus commented 2 years ago

Hey, I'm trying to do the same thing. Did you get this to work somehow? @nickm89

pittleCheung commented 1 month ago

I want to know if this problem has been solved yet.