UNPKG

emoji-mart-lazyload

Version:

Customizable Slack-like emoji picker for React

333 lines (290 loc) 11.2 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } import React from 'react'; import PropTypes from 'prop-types'; import frequently from '../utils/frequently'; import { getData } from '../utils'; import NimbleEmoji from './emoji/nimble-emoji'; import NotFound from './not-found'; import 'intersection-observer'; var Category = /*#__PURE__*/function (_React$Component) { _inherits(Category, _React$Component); var _super = _createSuper(Category); function Category(props) { var _this; _classCallCheck(this, Category); _this = _super.call(this, props); _this.data = props.data; _this.setContainerRef = _this.setContainerRef.bind(_assertThisInitialized(_this)); _this.setLabelRef = _this.setLabelRef.bind(_assertThisInitialized(_this)); _this.imageObserver = new window.IntersectionObserver(function (entries, observer) { entries.forEach(function (entry) { if (entry.isIntersecting) { var image = entry.target; image.src = image.dataset.src; image.classList.remove("lazy"); _this.imageObserver.unobserve(image); } }); }); return _this; } _createClass(Category, [{ key: "componentDidMount", value: function componentDidMount() { this.margin = 0; this.minMargin = 0; this.memoizeSize(); this.lazyloadImages = []; this.addLazyloadObserver(); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this.addLazyloadObserver(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.removeLazyloadObserver(); } }, { key: "shouldComponentUpdate", value: function shouldComponentUpdate(nextProps, nextState) { var _this$props = this.props, name = _this$props.name, perLine = _this$props.perLine, _native = _this$props["native"], hasStickyPosition = _this$props.hasStickyPosition, emojis = _this$props.emojis, emojiProps = _this$props.emojiProps, skin = emojiProps.skin, size = emojiProps.size, set = emojiProps.set, nextPerLine = nextProps.perLine, nextNative = nextProps["native"], nextHasStickyPosition = nextProps.hasStickyPosition, nextEmojis = nextProps.emojis, nextEmojiProps = nextProps.emojiProps, nextSkin = nextEmojiProps.skin, nextSize = nextEmojiProps.size, nextSet = nextEmojiProps.set, shouldUpdate = false; if (name == 'Recent' && perLine != nextPerLine) { shouldUpdate = true; } if (name == 'Search') { // shouldUpdate = !(emojis == nextEmojis) shouldUpdate = true; } if (skin != nextSkin || size != nextSize || _native != nextNative || set != nextSet || hasStickyPosition != nextHasStickyPosition) { shouldUpdate = true; } return shouldUpdate; } }, { key: "memoizeSize", value: function memoizeSize() { if (!this.container) { // probably this is a test environment, e.g. jest this.top = 0; this.maxMargin = 0; return; } var parent = this.container.parentElement; var _this$container$getBo = this.container.getBoundingClientRect(), top = _this$container$getBo.top, height = _this$container$getBo.height; var _parent$getBoundingCl = parent.getBoundingClientRect(), parentTop = _parent$getBoundingCl.top; var _this$label$getBoundi = this.label.getBoundingClientRect(), labelHeight = _this$label$getBoundi.height; this.top = top - parentTop + parent.scrollTop; if (height == 0) { this.maxMargin = 0; } else { this.maxMargin = height - labelHeight; } } }, { key: "addLazyloadObserver", value: function addLazyloadObserver() { var _this2 = this; this.removeLazyloadObserver(); this.lazyloadImages = this.container.querySelectorAll(".lazy"); this.lazyloadImages.forEach(function (image) { _this2.imageObserver.observe(image); }); } }, { key: "removeLazyloadObserver", value: function removeLazyloadObserver() { var _this3 = this; this.lazyloadImages.forEach(function (image) { _this3.imageObserver.unobserve(image); }); } }, { key: "handleOnContextMenu", value: function handleOnContextMenu(e) { e.preventDefault(); } }, { key: "handleScroll", value: function handleScroll(scrollTop) { var margin = scrollTop - this.top; margin = margin < this.minMargin ? this.minMargin : margin; margin = margin > this.maxMargin ? this.maxMargin : margin; if (margin == this.margin) return; if (!this.props.hasStickyPosition) { this.label.style.top = "".concat(margin, "px"); } this.margin = margin; return true; } }, { key: "getEmojis", value: function getEmojis() { var _this4 = this; var _this$props2 = this.props, name = _this$props2.name, emojis = _this$props2.emojis, recent = _this$props2.recent, perLine = _this$props2.perLine; if (name == 'Recent') { var custom = this.props.custom; var frequentlyUsed = recent || frequently.get(perLine); if (frequentlyUsed.length) { emojis = frequentlyUsed.map(function (id) { var emoji = custom.filter(function (e) { return e.id === id; })[0]; if (emoji) { return emoji; } return id; }).filter(function (id) { return !!getData(id, null, null, _this4.data); }); } if (emojis.length === 0 && frequentlyUsed.length > 0) { return null; } } if (emojis) { emojis = emojis.slice(0); } return emojis; } }, { key: "updateDisplay", value: function updateDisplay(display) { var emojis = this.getEmojis(); if (!emojis || !this.container) { return; } this.container.style.display = display; } }, { key: "setContainerRef", value: function setContainerRef(c) { this.container = c; } }, { key: "setLabelRef", value: function setLabelRef(c) { this.label = c; } }, { key: "render", value: function render() { var _this5 = this; var _this$props3 = this.props, id = _this$props3.id, name = _this$props3.name, hasStickyPosition = _this$props3.hasStickyPosition, emojiProps = _this$props3.emojiProps, i18n = _this$props3.i18n, notFound = _this$props3.notFound, notFoundEmoji = _this$props3.notFoundEmoji, emojis = this.getEmojis(), labelStyles = {}, labelSpanStyles = {}, containerStyles = {}; if (!emojis) { containerStyles = { display: 'none' }; } if (!hasStickyPosition) { labelStyles = { height: 28 }; labelSpanStyles = { position: 'absolute' }; } var label = i18n.categories[id] || name; return /*#__PURE__*/React.createElement("section", { ref: this.setContainerRef, className: "emoji-mart-category", "aria-label": label, style: containerStyles }, /*#__PURE__*/React.createElement("div", { style: labelStyles, "data-name": name, className: "emoji-mart-category-label" }, /*#__PURE__*/React.createElement("span", { style: labelSpanStyles, ref: this.setLabelRef, "aria-hidden": true /* already labeled by the section aria-label */ }, label)), /*#__PURE__*/React.createElement("ul", { className: "emoji-mart-category-list" }, emojis && emojis.map(function (emoji) { return /*#__PURE__*/React.createElement("li", { key: emoji.short_names && emoji.short_names.join('_') || emoji }, NimbleEmoji(_objectSpread(_objectSpread({ emoji: emoji, data: _this5.data }, emojiProps), {}, { lazy: true }))); })), emojis && !emojis.length && /*#__PURE__*/React.createElement(NotFound, { i18n: i18n, notFound: notFound, notFoundEmoji: notFoundEmoji, data: this.data, emojiProps: emojiProps })); } }]); return Category; }(React.Component); export { Category as default }; Category.propTypes /* remove-proptypes */ = { emojis: PropTypes.array, hasStickyPosition: PropTypes.bool, name: PropTypes.string.isRequired, "native": PropTypes.bool.isRequired, perLine: PropTypes.number.isRequired, emojiProps: PropTypes.object.isRequired, recent: PropTypes.arrayOf(PropTypes.string), notFound: PropTypes.func, notFoundEmoji: PropTypes.string.isRequired }; Category.defaultProps = { emojis: [], hasStickyPosition: true };