если условия задачи поменяются и...
Очевидно же - надо сделать отдельный компонент. "Условия" передавать через props, чтобы было как-то так:
<EditorWithTableOfContents tags={[ 'h1' ]} />
<EditorWithTableOfContents tags={[ 'h2', 'h3' ]} />
Сбор информации о заголовках - достаточно получить элементы и сохранить пары тэг-текст. При создании оглавления индексы элементам указываете общие, без разделения по тэгам. Когда надо выполнить прокрутку, берёте внутри редактора элемент с этим индексом:
const EditorWithTableOfContents = ({ tags }) => {
const [headers, setHeaders] = useState([]);
const editorEl = useRef(null);
const onChange = e => {
setHeaders(Array.from(
e.editor.document.$.querySelectorAll(tags.join(', ')),
n => [ n.tagName, n.innerText ]
));
};
const goToAnchor = e => {
const index = e.target.dataset.index;
const d = editorEl.current.editor.document.$;
d.documentElement.scrollTo({
top: d.querySelectorAll(tags.join(', '))[index].offsetTop,
behavior: 'smooth',
});
};
return (
<div>
<CKEditor
data={initData}
onInstanceReady={onChange}
onChange={onChange}
ref={editorEl}
/>
<h2>Содержание</h2>
{headers.map(([Tag, text], index) => (
<Tag key={index} data-index={index} onClick={goToAnchor}>
{text}
</Tag>
))}
</div>
);
};
https://codesandbox.io/s/for-https-qna-habr-com-q-...