@atlaskit/editor-plugin-width
Version:
Width plugin for @atlaskit/editor-core
74 lines (71 loc) • 3.21 kB
JavaScript
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]);
};