@sanity/form-builder
Version:
Sanity form builder
69 lines (67 loc) • 2.81 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useScrollSelectionIntoView = useScrollSelectionIntoView;
var _portableTextEditor = require("@sanity/portable-text-editor");
var _react = require("react");
var _scrollIntoViewIfNeeded = _interopRequireDefault(require("scroll-into-view-if-needed"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// This hook is used to scroll the editor selection into place when actively editing the document.
function useScrollSelectionIntoView(scrollElement) {
return (0, _react.useMemo)(() => (editor, domRange) => {
var selection = _portableTextEditor.PortableTextEditor.getSelection(editor);
if (selection) {
var leafEl = domRange.startContainer.parentElement;
if (!leafEl) {
return;
}
var originalGetBoundingClientRect = leafEl.getBoundingClientRect;
leafEl.getBoundingClientRect = domRange.getBoundingClientRect.bind(domRange);
var voidOffset = 0;
var voidIsVisible = false;
try {
var block = _portableTextEditor.PortableTextEditor.focusBlock(editor);
var blockType = _portableTextEditor.PortableTextEditor.getPortableTextFeatures(editor).types.block;
var isVoid = block._type !== blockType.name;
if (block && isVoid && scrollElement) {
var element = _portableTextEditor.PortableTextEditor.findDOMNode(editor, block);
var boundingRect = element.getBoundingClientRect();
voidOffset = boundingRect.height;
// Get container properties
var cTop = scrollElement.scrollTop;
var cBottom = cTop + scrollElement.clientHeight;
// Get element properties
var eTop = element.offsetTop;
var eBottom = eTop + element.clientHeight;
// Check if in view
var isTotal = eTop >= cTop && eBottom <= cBottom;
var isPartial = eTop < cTop && eBottom > cTop || eBottom > cBottom && eTop < cBottom;
voidIsVisible = isTotal || isPartial;
}
} catch (err) {
// Nothing
}
(0, _scrollIntoViewIfNeeded.default)(leafEl, {
scrollMode: 'if-needed',
behavior: actions => {
if (voidIsVisible) {
return;
}
actions.forEach(_ref => {
var el = _ref.el,
top = _ref.top,
left = _ref.left;
el.scrollTop = top - (voidOffset ? voidOffset + 5 : 0);
el.scrollLeft = left;
});
},
boundary: scrollElement,
block: voidOffset ? 'start' : 'center',
inline: 'nearest'
});
// restore original method
leafEl.getBoundingClientRect = originalGetBoundingClientRect;
}
}, [scrollElement]);
}