DEV Community

nhtanvir93
nhtanvir93

Posted on

Can't get node index for which overflow happend, always get 0 index as overflow inded

Basically, I want to create next element while overflow happened for a element, here previewNodes is basically html element list array.

Image description

PreviewNode.tsx

import React, { ReactNode, useEffect, useRef, useState } from 'react';
import IPageNode from '../../interfaces/IPageNode';
import IPreviewNode from '../../interfaces/IPreviewNode';
import styles from './PreviewNode.module.css';

interface IProps {
    pageIndex: number;
    pageNode: IPageNode;
    onOverflow: (index: number, pageIndex: number) => void;
}

const PreviewNode = ({ pageIndex, pageNode, onOverflow }: IProps) => {
    const [validPreviewNodes, setValidPreviewNodes] = useState<IPreviewNode[]>([]);

    const pageRef = useRef(null);

    useEffect(() => {
        setValidPreviewNodes([ ...pageNode.containingPreviewNodes ]);
    }, [ pageNode ]);

    const isOverflown = () => {
        if(pageRef.current === null) return false;

        const page = pageRef.current as Element;

        return page.scrollHeight > page.clientHeight || page.scrollWidth > page.clientWidth;
    };

    const checkOverflow = (index: number) => {
        if(pageNode.endPreviewNodeIndex === -1 && isOverflown())
            onOverflow(index, pageIndex);
    };

    return (
        <div ref={ pageRef } className={ styles.previewNode }>
            <div className="ql-snow">
                <div
                    className="ql-editor p-0"
                    dangerouslySetInnerHTML={{ __html: validPreviewNodes.map((node, index) => {
                        checkOverflow(index);
                        return node.nodeContent;
                    }).join('') }}
                />
            </div>
        </div>
    );
};

export default PreviewNode;
Enter fullscreen mode Exit fullscreen mode

PreviewNodes.tsx

import React, { useEffect, useState } from "react";
import IPreviewNode from "../../interfaces/IPreviewNode";
import IPreviewNodeDiff from "../../interfaces/IPreviewNodeDiff";
import PreviewNode from "../PreviewNode";
import IPageNode from "../../interfaces/IPageNode";

interface IProps {
    previewNodes: IPreviewNode[];
    previewNodesDiff: IPreviewNodeDiff;
}

const PreviewNodes = ({ previewNodes, previewNodesDiff }: IProps) => {
    const [pageNodes, setPageNodes] = useState<IPageNode[]>([]);

    const handleOverflow = (endNodeIndex, pageIndex) => {
        console.log('HandleOverflow', 'pageIndex', pageIndex, 'endNodeIndex', endNodeIndex);
        const newPageNodes = pageNodes.map((pageNode, index) => {
            if(index !== pageIndex)
                return pageNode;

            return {
                ...pageNode,
                endPreviewNodeIndex: endNodeIndex,
                containingPreviewNodes:
                    previewNodes.filter(
                        (previewNode, filterIndex) =>
                            filterIndex >= pageNode.startPreviewNodeIndex && filterIndex < endNodeIndex
                    )
            };
        });

        setPageNodes(newPageNodes);
    };

    const checkAndModifyPageNodes = () => {
        if(pageNodes.length === 0 && previewNodes.length > 0) {
            let pageNode: IPageNode = {
                startPreviewNodeIndex: 0,
                endPreviewNodeIndex: -1,
                containingPreviewNodes: [ ...previewNodes ]
            };

            setPageNodes([ pageNode ]);
        } else if(pageNodes.length > 0 && previewNodes.length > 0 && pageNodes[pageNodes.length - 1].endPreviewNodeIndex !== -1) {
            const lastPageNode = pageNodes[pageNodes.length - 1];

            let possibleNodes =
                previewNodes.filter((possibleNode, index) => index >= lastPageNode.startPreviewNodeIndex && index <= lastPageNode.endPreviewNodeIndex);

            let pageNode: IPageNode = {
                ...lastPageNode,
                containingPreviewNodes: possibleNodes
            };

            setPageNodes([ ...pageNodes, pageNode ]);
        }
        else if(pageNodes.length > 0) {
            const lastPageNode = pageNodes[pageNodes.length - 1];

            const currentPossibleNodes
                = previewNodes.filter((previewNode, index) => index >= lastPageNode.startPreviewNodeIndex);

            let modifiedPageNode: IPageNode = {
                ...lastPageNode,
                containingPreviewNodes: currentPossibleNodes
            };

            const possiblePageNodes = pageNodes.map((pageNode, index) => {
                if(index < pageNodes.length - 1)
                    return pageNode;

                return modifiedPageNode;
            });

            setPageNodes(possiblePageNodes);
        }
    };

    useEffect(() => {
        checkAndModifyPageNodes();
    }, [ previewNodes ]);

    return (
        <div>
            { pageNodes.map(
                (pageNode, index) =>
                    <PreviewNode
                        key={ 'preview-' + index }
                        pageIndex={ index }
                        pageNode={ pageNode }
                        onOverflow={ (endNodeIndex, pageIndex) => handleOverflow(endNodeIndex, pageIndex) }
                    />)
            }
        </div>
    );
};

export default PreviewNodes;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)