UNPKG

@atlaskit/editor-plugin-width

Version:

Width plugin for @atlaskit/editor-core

75 lines (72 loc) • 3.08 kB
import { useEffect, useRef } from 'react'; import { setEditorWidth } from './setEditorWidth'; import { useRefreshWidthOnTransitionNext } from './useRefreshOnTransitionNext'; /** * Copy of `useResizeWidthObserver` selected by `platform_editor_reduce_forced_layout`. On cleanup, * rename this over that file. * * The legacy hook keyed the first effect on `editorView.dom.clientWidth`. Dependency arrays are * evaluated during render, so it measured layout on every render rather than when the width * actually changed. It existed to catch `full-width` <-> `full-page`, where `clientWidth` changes * without the container resizing; `widthTransitionCount` detects that without measuring. * * That first effect now runs only for a transition. The observer already reports both values when * it starts observing, so mount needs no measurement of its own. * * The `clientWidth` read below is not usually a forced layout, because ResizeObserver callbacks * run after layout. Another observer's callback can write to the DOM before ours in the same * delivery cycle, in which case it is. */ export const useResizeWidthObserverNext = ({ editorView, containerElement }) => { const widthTransitionCount = useRefreshWidthOnTransitionNext(containerElement); const lastMeasuredTransition = useRef(widthTransitionCount); useEffect(() => { // `apply` spreads meta over state, so dispatching an explicit `undefined` would overwrite // the existing width. if (!containerElement) { return; } // only update editor width state after change editor layout if (lastMeasuredTransition.current === widthTransitionCount) { return; } lastMeasuredTransition.current = widthTransitionCount; const newState = { lineLength: editorView.dom.clientWidth, width: containerElement.offsetWidth }; setEditorWidth(newState)(editorView); }, [editorView, widthTransitionCount, containerElement]); useEffect(() => { if (!containerElement) { return; } const resizeWidth = entries => { var _fullAreaSize$borderB; // A delivery can batch several entries for the observed target; the last is current. const fullAreaSize = entries[entries.length - 1]; if (!fullAreaSize || !Array.isArray(fullAreaSize.borderBoxSize)) { return; } // `Array.isArray` passes for `[]`, which some polyfills produce. Bail rather than // dispatch `undefined`, which would overwrite the width via the spread in `apply`. const width = (_fullAreaSize$borderB = fullAreaSize.borderBoxSize[0]) === null || _fullAreaSize$borderB === void 0 ? void 0 : _fullAreaSize$borderB.inlineSize; if (width === undefined) { return; } const lineLength = editorView.dom.clientWidth; setEditorWidth({ width, lineLength })(editorView); }; const resizeObserver = new ResizeObserver(resizeWidth); resizeObserver.observe(containerElement); return () => { resizeObserver.disconnect(); }; }, [containerElement, editorView]); };