@chayns-components/emoji-input
Version:
Input field that supports HTML elements and emojis
145 lines (144 loc) • 5.77 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = require("motion/react");
var _react2 = _interopRequireWildcard(require("react"));
var _alignment = require("../../../../constants/alignment");
var _Emoji = require("./Emoji.styles");
var _SkinTonePopup = _interopRequireDefault(require("./skin-tone-popup/SkinTonePopup"));
var _SkinTonePopup2 = require("./skin-tone-popup/SkinTonePopup.styles");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const Emoji = ({
emoji,
isSelected,
name,
isSkinToneSupported,
onPopupVisibilityChange,
onSelect,
shouldShowSkinTonePopup,
onRightClick,
index,
emojiList
}) => {
const [shouldShowPopup, setShouldShowPopup] = (0, _react2.useState)(false);
const [skinTonePopupAnchorAlignment, setSkinTonePopupAnchorAlignment] = (0, _react2.useState)(_alignment.AnchorAlignment.Top);
const [skinTonePopupAnchorOffset, setSkinTonePopupAnchorOffset] = (0, _react2.useState)(0);
const [skinTonePopupOverlayPosition, setSkinTonePopupOverlayPosition] = (0, _react2.useState)({
top: 0
});
const [skinTonePopupPosition, setSkinTonePopupPosition] = (0, _react2.useState)({
left: 0,
top: 0
});
const emojiRef = (0, _react2.useRef)(null);
const handleClick = (0, _react2.useCallback)(() => {
onSelect(emoji);
}, [emoji, onSelect]);
const calculatePopupPosition = (0, _react2.useCallback)(() => {
if (!emojiRef.current) {
return;
}
const element = emojiRef.current;
const {
parentElement
} = emojiRef.current;
if (parentElement) {
const {
height: elementHeight,
left: elementLeft,
top: elementTop,
width: elementWidth
} = element.getBoundingClientRect();
const {
height: parentHeight,
left: parentLeft,
top: parentTop,
width: parentWidth
} = parentElement.getBoundingClientRect();
const {
scrollTop
} = parentElement;
let anchorAlignment = _alignment.AnchorAlignment.Top;
let anchorOffset = 0;
let left = elementLeft - parentLeft - _SkinTonePopup2.skinTonePopupContentSize.width / 2 + elementWidth / 2;
let top = elementTop - parentTop + elementHeight + scrollTop;
const maxLeft = parentWidth - _SkinTonePopup2.skinTonePopupContentSize.width - 12;
const minLeft = 12;
if (left < minLeft) {
anchorOffset = left - minLeft;
left = minLeft;
} else if (left > maxLeft) {
anchorOffset = left - maxLeft;
left = maxLeft;
}
if (top + _SkinTonePopup2.skinTonePopupContentSize.height > parentHeight + scrollTop) {
anchorAlignment = _alignment.AnchorAlignment.Bottom;
top -= elementHeight + _SkinTonePopup2.skinTonePopupContentSize.height;
}
if (isSkinToneSupported) {
setSkinTonePopupAnchorAlignment(anchorAlignment);
setSkinTonePopupAnchorOffset(anchorOffset);
setSkinTonePopupPosition({
left,
top
});
setSkinTonePopupOverlayPosition({
top: scrollTop
});
setShouldShowPopup(true);
}
}
}, [isSkinToneSupported]);
const handleContextMenu = (0, _react2.useCallback)(event => {
event.preventDefault();
event.stopPropagation();
if (isSkinToneSupported) {
onRightClick(index);
calculatePopupPosition();
}
}, [calculatePopupPosition, index, isSkinToneSupported, onRightClick]);
(0, _react2.useEffect)(() => {
if (emojiRef.current && shouldShowSkinTonePopup && skinTonePopupPosition.top === 0 && skinTonePopupPosition.left === 0) {
calculatePopupPosition();
}
}, [calculatePopupPosition, index, isSkinToneSupported, shouldShowSkinTonePopup, skinTonePopupPosition]);
(0, _react2.useEffect)(() => {
if (shouldShowSkinTonePopup) {
setShouldShowPopup(shouldShowSkinTonePopup);
}
}, [shouldShowSkinTonePopup]);
const handleHidePopup = (0, _react2.useCallback)(() => {
setShouldShowPopup(false);
}, []);
(0, _react2.useEffect)(() => {
onPopupVisibilityChange(shouldShowPopup);
}, [onPopupVisibilityChange, shouldShowPopup]);
return /*#__PURE__*/_react2.default.createElement(_Emoji.StyledEmoji, {
ref: emojiRef,
$isSelected: isSelected,
"data-emoji": emoji,
"data-name": name,
"data-skin-tone-support": isSkinToneSupported,
className: "prevent-lose-focus",
onClick: handleClick,
onContextMenu: handleContextMenu
}, emoji, /*#__PURE__*/_react2.default.createElement(_react.AnimatePresence, {
initial: false
}, shouldShowPopup && /*#__PURE__*/_react2.default.createElement(_SkinTonePopup.default, {
anchorAlignment: skinTonePopupAnchorAlignment,
anchorOffset: skinTonePopupAnchorOffset,
emoji: emoji,
key: emoji,
onHidePopup: handleHidePopup,
onSelect: onSelect,
overlayPosition: skinTonePopupOverlayPosition,
position: skinTonePopupPosition,
emojiList: emojiList
})));
};
Emoji.displayName = 'Emoji';
var _default = exports.default = Emoji;
//# sourceMappingURL=Emoji.js.map