UNPKG

emoji-mart

Version:

Customizable Slack-like emoji picker for React

277 lines (240 loc) 8.89 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; 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; } 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'; var Category = /*#__PURE__*/ function (_React$Component) { _inherits(Category, _React$Component); function Category(props) { var _this; _classCallCheck(this, Category); _this = _possibleConstructorReturn(this, _getPrototypeOf(Category).call(this, props)); _this.data = props.data; _this.setContainerRef = _this.setContainerRef.bind(_assertThisInitialized(_this)); _this.setLabelRef = _this.setLabelRef.bind(_assertThisInitialized(_this)); return _this; } _createClass(Category, [{ key: "componentDidMount", value: function componentDidMount() { this.margin = 0; this.minMargin = 0; this.memoizeSize(); } }, { 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); } 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: "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 _this2 = 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, _this2.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 _this3 = 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 React.createElement("section", { ref: this.setContainerRef, className: "emoji-mart-category", "aria-label": label, style: containerStyles }, React.createElement("div", { style: labelStyles, "data-name": name, className: "emoji-mart-category-label" }, React.createElement("span", { style: labelSpanStyles, ref: this.setLabelRef, "aria-hidden": true /* already labeled by the section aria-label */ }, label)), React.createElement("ul", { className: "emoji-mart-category-list" }, emojis && emojis.map(function (emoji) { return React.createElement("li", { key: emoji.short_names && emoji.short_names.join('_') || emoji }, NimbleEmoji(_objectSpread({ emoji: emoji, data: _this3.data }, emojiProps))); })), emojis && !emojis.length && 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 };