UNPKG

@atlaskit/editor-plugin-width

Version:

Width plugin for @atlaskit/editor-core

74 lines (71 loc) • 3.21 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 var useResizeWidthObserverNext = function useResizeWidthObserverNext(_ref) { var editorView = _ref.editorView, containerElement = _ref.containerElement; var widthTransitionCount = useRefreshWidthOnTransitionNext(containerElement); var lastMeasuredTransition = useRef(widthTransitionCount); useEffect(function () { // `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; var newState = { lineLength: editorView.dom.clientWidth, width: containerElement.offsetWidth }; setEditorWidth(newState)(editorView); }, [editorView, widthTransitionCount, containerElement]); useEffect(function () { if (!containerElement) { return; } var resizeWidth = function resizeWidth(entries) { var _fullAreaSize$borderB; // A delivery can batch several entries for the observed target; the last is current. var 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`. var width = (_fullAreaSize$borderB = fullAreaSize.borderBoxSize[0]) === null || _fullAreaSize$borderB === void 0 ? void 0 : _fullAreaSize$borderB.inlineSize; if (width === undefined) { return; } var lineLength = editorView.dom.clientWidth; setEditorWidth({ width: width, lineLength: lineLength })(editorView); }; var resizeObserver = new ResizeObserver(resizeWidth); resizeObserver.observe(containerElement); return function () { resizeObserver.disconnect(); }; }, [containerElement, editorView]); };