append react custom component to div with contentEditable

18 views Asked by At

Hi I am creating rich text editor in react. if you guyz have used Notion. I am just try to build it by my own with some upgrade feature of allowing using custom component with use that custom component in one line. But I have stuck with with approach. In below code In div contenteditable I am able to write text and mount custom component. I am storing this data in json. I am stuck at how can I get to know where I am tryping so basically when I am typing or editing Block1, Block2, Block3 I can get something index 0-1-2 so that accordingly I can update that in json for that index. For custom component I am able to get it with react logic, but I am not to get it with html div writing. similarly looking for appraoch to show default value or predefined value and allowing them to edit

my json look like this, if you see below HTML code and json code "this is block two code" should come at 3rd position in array

[
    {
        "value": "this is block one code this is block two code"
    },
    {
        "id": "c06bb118-a5ad-4e4b-a620-ce8f798880d4",
        "version": 1,
        "type": "select",
        "selectType": "",
        "value": "",
        "selectedValue": "",
        "selectedValueId": "",
        "created_time": 1710479700322,
        "last_edited_time": "",
        "parent_id": "f4976070-8945-49dd-b753-960ce59b7341",
        "created_by_id": "",
        "last_edited_by_id": ""
    }
]

html snippet

<div contenteditable="true" class="input__style" placeholder="Press ‘space’ for AI, ‘/’ for commands…">
**Block1** this is block one code

**Block2** <span class="select__style" contenteditable="false" id="c06bb118-a5ad-4e4b-a620-ce8f798880d4" data-id="c06bb118-a5ad-4e4b-a620-ce8f798880d4"><select><option value='check'>check</option><select></span>

**Block3**this is block one two

</div>

react code

const InputBlock = (props) => {
    const { id, parentId, renderArray, updateParentState, addBlock } = props;
    const inputBlockRef = useRef(null);

    useEffect(() => {
        // Focus on the contentEditable div when the component mounts
        inputBlockRef.current.focus();
    }, []);

    const handleInput = () => {
        // Update the parent state when the input changes
        const inputValue = inputBlockRef.current.textContent;            
        
        // how to get index to update exact postion in renderArray
    
        // Update the parent state with the modified renderArray
        updateParentState(id, renderArray);
    }    

    const handleKeyDown = (e) => {
        // Prevent the default behavior for the left arrow key
        if (e.key === 'Enter') {
            // Enter key pressed, add a new block (for now, let's assume it's a text block)
            addBlock('input', parentId);
        }
    };

    return (
        <div
            contentEditable
            suppressContentEditableWarning
            className='input__style'
            onClick={(event) => {
                event.stopPropagation();
                console.log("second div clicked");
            }}
            ref={inputBlockRef}
            onBlur={handleInput}
            onKeyDown={handleKeyDown}
            placeholder={'start typing...'}
        >
            {renderData?.properties?.title?.map((data, key) => {
                if(data?.type === 'select') {
                    return <SelectBlock 
                                id={data?.id}
                                parentId={id}
                                key={key} 
                                data={data} 
                                renderArray={renderArray}
                                updateParentState={updateParentState}
                            />;
                }else {
                    return data?.value
                }
            })}
        </div>
    );
};
0

There are 0 answers