@chayns-components/emoji-input
Version:
Input field that supports HTML elements and emojis
110 lines (109 loc) • 3.56 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useCursorPosition = void 0;
var _react = require("react");
var _selection = require("../utils/selection");
const useCursorPosition = (editorRef, onChange, options) => {
const {
isDisabled
} = options || {};
const [position, setPosition] = (0, _react.useState)(null);
const rafIdRef = (0, _react.useRef)(null);
const lastPositionRef = (0, _react.useRef)(null);
const emit = (0, _react.useCallback)(() => {
const el = editorRef.current;
if (!el || isDisabled) return;
const pos = (0, _selection.getCurrentCursorPosition)(el);
if (pos !== null && pos !== lastPositionRef.current) {
lastPositionRef.current = pos;
setPosition(pos);
if (typeof onChange === 'function') onChange(pos);
}
}, [editorRef, onChange, isDisabled]);
const scheduleEmit = (0, _react.useCallback)(() => {
if (rafIdRef.current != null) cancelAnimationFrame(rafIdRef.current);
rafIdRef.current = requestAnimationFrame(() => {
rafIdRef.current = null;
emit();
});
}, [emit]);
const trigger = (0, _react.useCallback)(() => {
scheduleEmit();
}, [scheduleEmit]);
(0, _react.useEffect)(() => {
const el = editorRef.current;
if (!el) return () => {};
const onKeyUp = e => {
const navKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown', 'Backspace', 'Delete'];
if (navKeys.includes(e.key)) scheduleEmit();
};
el.addEventListener('keyup', onKeyUp, {
passive: true
});
return () => el.removeEventListener('keyup', onKeyUp);
}, [editorRef, scheduleEmit]);
(0, _react.useEffect)(() => {
const el = editorRef.current;
if (!el) return () => {};
const onMouseUp = () => scheduleEmit();
const onTouchEnd = () => scheduleEmit();
el.addEventListener('mouseup', onMouseUp, {
passive: true
});
el.addEventListener('touchend', onTouchEnd, {
passive: true
});
return () => {
el.removeEventListener('mouseup', onMouseUp);
el.removeEventListener('touchend', onTouchEnd);
};
}, [editorRef, scheduleEmit]);
(0, _react.useEffect)(() => {
const onSelectionChange = () => {
const el = editorRef.current;
const sel = document.getSelection();
if (!el || !sel) return;
const {
anchorNode
} = sel;
if (anchorNode && el.contains(anchorNode) && document.activeElement === el) {
scheduleEmit();
}
};
document.addEventListener('selectionchange', onSelectionChange, {
passive: true
});
return () => document.removeEventListener('selectionchange', onSelectionChange);
}, [editorRef, scheduleEmit]);
(0, _react.useEffect)(() => {
const el = editorRef.current;
if (!el) return () => {};
const onFocus = () => scheduleEmit();
const onBlur = () => {
lastPositionRef.current = null;
setPosition(null);
};
el.addEventListener('focus', onFocus, {
passive: true
});
el.addEventListener('blur', onBlur, {
passive: true
});
return () => {
el.removeEventListener('focus', onFocus);
el.removeEventListener('blur', onBlur);
};
}, [editorRef, scheduleEmit]);
(0, _react.useEffect)(() => () => {
if (rafIdRef.current != null) cancelAnimationFrame(rafIdRef.current);
}, []);
return {
position,
trigger,
lastPositionRef
};
};
exports.useCursorPosition = useCursorPosition;
//# sourceMappingURL=cursor.js.map