Basically, I want to create next element while overflow happened for a element, here previewNodes is basically html element list array.
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;
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;
Top comments (0)