From 1cae35669e054b292c9d90dae3a0b633acd28026 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sun, 10 Mar 2019 11:03:35 -0700 Subject: [PATCH] build --- dist-es/components/anchors.js | 108 +++ dist-es/components/category.js | 275 ++++++++ dist-es/components/emoji/emoji.js | 23 + dist-es/components/emoji/nimble-emoji.js | 215 ++++++ dist-es/components/not-found.js | 64 ++ dist-es/components/picker/nimble-picker.js | 637 ++++++++++++++++++ dist-es/components/picker/picker.js | 38 ++ dist-es/components/preview.js | 162 +++++ dist-es/components/search.js | 146 ++++ dist-es/components/skins-dot.js | 93 +++ dist-es/components/skins-emoji.js | 99 +++ dist-es/components/skins.js | 61 ++ dist-es/index.js | 10 + dist-es/polyfills/classCallCheck.js | 5 + dist-es/polyfills/createClass.js | 19 + dist-es/polyfills/extends.js | 15 + dist-es/polyfills/inherits.js | 19 + dist-es/polyfills/keys.js | 30 + dist-es/polyfills/objectGetPrototypeOf.js | 11 + .../polyfills/possibleConstructorReturn.js | 7 + dist-es/polyfills/stringFromCodePoint.js | 40 ++ dist-es/svgs/index.js | 192 ++++++ dist-es/utils/data.js | 106 +++ dist-es/utils/emoji-index/emoji-index.js | 13 + .../utils/emoji-index/nimble-emoji-index.js | 224 ++++++ dist-es/utils/frequently.js | 66 ++ dist-es/utils/index.js | 208 ++++++ dist-es/utils/shared-default-props.js | 47 ++ dist-es/utils/shared-props.js | 59 ++ dist-es/utils/store.js | 56 ++ dist-es/vendor/raf-polyfill.js | 33 + dist-modern/components/anchors.js | 75 +++ dist-modern/components/category.js | 222 ++++++ dist-modern/components/emoji/emoji.js | 23 + dist-modern/components/emoji/nimble-emoji.js | 195 ++++++ dist-modern/components/not-found.js | 37 + .../components/picker/nimble-picker.js | 578 ++++++++++++++++ dist-modern/components/picker/picker.js | 17 + dist-modern/components/preview.js | 139 ++++ dist-modern/components/search.js | 116 ++++ dist-modern/components/skins-dot.js | 71 ++ dist-modern/components/skins-emoji.js | 75 +++ dist-modern/components/skins.js | 40 ++ dist-modern/index.js | 10 + dist-modern/polyfills/classCallCheck.js | 5 + dist-modern/polyfills/createClass.js | 19 + dist-modern/polyfills/extends.js | 15 + dist-modern/polyfills/inherits.js | 19 + dist-modern/polyfills/keys.js | 30 + dist-modern/polyfills/objectGetPrototypeOf.js | 11 + .../polyfills/possibleConstructorReturn.js | 7 + dist-modern/polyfills/stringFromCodePoint.js | 40 ++ dist-modern/svgs/index.js | 168 +++++ dist-modern/utils/data.js | 106 +++ dist-modern/utils/emoji-index/emoji-index.js | 11 + .../utils/emoji-index/nimble-emoji-index.js | 180 +++++ dist-modern/utils/frequently.js | 62 ++ dist-modern/utils/index.js | 206 ++++++ dist-modern/utils/shared-default-props.js | 45 ++ dist-modern/utils/shared-props.js | 59 ++ dist-modern/utils/store.js | 56 ++ dist-modern/vendor/raf-polyfill.js | 33 + dist/components/anchors.js | 89 +++ dist/components/category.js | 248 +++++++ dist/components/emoji/emoji.js | 42 ++ dist/components/emoji/nimble-emoji.js | 214 ++++++ dist/components/not-found.js | 56 ++ dist/components/picker/nimble-picker.js | 620 +++++++++++++++++ dist/components/picker/picker.js | 37 + dist/components/preview.js | 165 +++++ dist/components/search.js | 134 ++++ dist/components/skins-dot.js | 87 +++ dist/components/skins-emoji.js | 94 +++ dist/components/skins.js | 56 ++ dist/index.js | 88 +++ dist/polyfills/classCallCheck.js | 11 + dist/polyfills/createClass.js | 24 + dist/polyfills/extends.js | 20 + dist/polyfills/inherits.js | 25 + dist/polyfills/keys.js | 36 + dist/polyfills/objectGetPrototypeOf.js | 16 + dist/polyfills/possibleConstructorReturn.js | 13 + dist/polyfills/stringFromCodePoint.js | 45 ++ dist/svgs/index.js | 180 +++++ dist/utils/data.js | 113 ++++ dist/utils/emoji-index/emoji-index.js | 24 + dist/utils/emoji-index/nimble-emoji-index.js | 188 ++++++ dist/utils/frequently.js | 72 ++ dist/utils/index.js | 228 +++++++ dist/utils/shared-default-props.js | 51 ++ dist/utils/shared-props.js | 71 ++ dist/utils/store.js | 61 ++ dist/vendor/raf-polyfill.js | 35 + 93 files changed, 8894 insertions(+) create mode 100644 dist-es/components/anchors.js create mode 100644 dist-es/components/category.js create mode 100644 dist-es/components/emoji/emoji.js create mode 100644 dist-es/components/emoji/nimble-emoji.js create mode 100644 dist-es/components/not-found.js create mode 100644 dist-es/components/picker/nimble-picker.js create mode 100644 dist-es/components/picker/picker.js create mode 100644 dist-es/components/preview.js create mode 100644 dist-es/components/search.js create mode 100644 dist-es/components/skins-dot.js create mode 100644 dist-es/components/skins-emoji.js create mode 100644 dist-es/components/skins.js create mode 100644 dist-es/index.js create mode 100644 dist-es/polyfills/classCallCheck.js create mode 100644 dist-es/polyfills/createClass.js create mode 100644 dist-es/polyfills/extends.js create mode 100644 dist-es/polyfills/inherits.js create mode 100644 dist-es/polyfills/keys.js create mode 100644 dist-es/polyfills/objectGetPrototypeOf.js create mode 100644 dist-es/polyfills/possibleConstructorReturn.js create mode 100644 dist-es/polyfills/stringFromCodePoint.js create mode 100644 dist-es/svgs/index.js create mode 100644 dist-es/utils/data.js create mode 100644 dist-es/utils/emoji-index/emoji-index.js create mode 100644 dist-es/utils/emoji-index/nimble-emoji-index.js create mode 100644 dist-es/utils/frequently.js create mode 100644 dist-es/utils/index.js create mode 100644 dist-es/utils/shared-default-props.js create mode 100644 dist-es/utils/shared-props.js create mode 100644 dist-es/utils/store.js create mode 100644 dist-es/vendor/raf-polyfill.js create mode 100644 dist-modern/components/anchors.js create mode 100644 dist-modern/components/category.js create mode 100644 dist-modern/components/emoji/emoji.js create mode 100644 dist-modern/components/emoji/nimble-emoji.js create mode 100644 dist-modern/components/not-found.js create mode 100644 dist-modern/components/picker/nimble-picker.js create mode 100644 dist-modern/components/picker/picker.js create mode 100644 dist-modern/components/preview.js create mode 100644 dist-modern/components/search.js create mode 100644 dist-modern/components/skins-dot.js create mode 100644 dist-modern/components/skins-emoji.js create mode 100644 dist-modern/components/skins.js create mode 100644 dist-modern/index.js create mode 100644 dist-modern/polyfills/classCallCheck.js create mode 100644 dist-modern/polyfills/createClass.js create mode 100644 dist-modern/polyfills/extends.js create mode 100644 dist-modern/polyfills/inherits.js create mode 100644 dist-modern/polyfills/keys.js create mode 100644 dist-modern/polyfills/objectGetPrototypeOf.js create mode 100644 dist-modern/polyfills/possibleConstructorReturn.js create mode 100644 dist-modern/polyfills/stringFromCodePoint.js create mode 100644 dist-modern/svgs/index.js create mode 100644 dist-modern/utils/data.js create mode 100644 dist-modern/utils/emoji-index/emoji-index.js create mode 100644 dist-modern/utils/emoji-index/nimble-emoji-index.js create mode 100644 dist-modern/utils/frequently.js create mode 100644 dist-modern/utils/index.js create mode 100644 dist-modern/utils/shared-default-props.js create mode 100644 dist-modern/utils/shared-props.js create mode 100644 dist-modern/utils/store.js create mode 100644 dist-modern/vendor/raf-polyfill.js create mode 100644 dist/components/anchors.js create mode 100644 dist/components/category.js create mode 100644 dist/components/emoji/emoji.js create mode 100644 dist/components/emoji/nimble-emoji.js create mode 100644 dist/components/not-found.js create mode 100644 dist/components/picker/nimble-picker.js create mode 100644 dist/components/picker/picker.js create mode 100644 dist/components/preview.js create mode 100644 dist/components/search.js create mode 100644 dist/components/skins-dot.js create mode 100644 dist/components/skins-emoji.js create mode 100644 dist/components/skins.js create mode 100644 dist/index.js create mode 100644 dist/polyfills/classCallCheck.js create mode 100644 dist/polyfills/createClass.js create mode 100644 dist/polyfills/extends.js create mode 100644 dist/polyfills/inherits.js create mode 100644 dist/polyfills/keys.js create mode 100644 dist/polyfills/objectGetPrototypeOf.js create mode 100644 dist/polyfills/possibleConstructorReturn.js create mode 100644 dist/polyfills/stringFromCodePoint.js create mode 100644 dist/svgs/index.js create mode 100644 dist/utils/data.js create mode 100644 dist/utils/emoji-index/emoji-index.js create mode 100644 dist/utils/emoji-index/nimble-emoji-index.js create mode 100644 dist/utils/frequently.js create mode 100644 dist/utils/index.js create mode 100644 dist/utils/shared-default-props.js create mode 100644 dist/utils/shared-props.js create mode 100644 dist/utils/store.js create mode 100644 dist/vendor/raf-polyfill.js diff --git a/dist-es/components/anchors.js b/dist-es/components/anchors.js new file mode 100644 index 000000000..7a162953d --- /dev/null +++ b/dist-es/components/anchors.js @@ -0,0 +1,108 @@ +import _Object$getPrototypeOf from '../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../polyfills/classCallCheck'; +import _createClass from '../polyfills/createClass'; +import _possibleConstructorReturn from '../polyfills/possibleConstructorReturn'; +import _inherits from '../polyfills/inherits'; +import React from 'react'; +import PropTypes from 'prop-types'; + +var Anchors = function (_React$PureComponent) { + _inherits(Anchors, _React$PureComponent); + + function Anchors(props) { + _classCallCheck(this, Anchors); + + var _this = _possibleConstructorReturn(this, (Anchors.__proto__ || _Object$getPrototypeOf(Anchors)).call(this, props)); + + var defaultCategory = props.categories.filter(function (category) { + return category.first; + })[0]; + + _this.state = { + selected: defaultCategory.name + }; + + _this.handleClick = _this.handleClick.bind(_this); + return _this; + } + + _createClass(Anchors, [{ + key: 'handleClick', + value: function handleClick(e) { + var index = e.currentTarget.getAttribute('data-index'); + var _props = this.props; + var categories = _props.categories; + var onAnchorClick = _props.onAnchorClick; + + + onAnchorClick(categories[index], index); + } + }, { + key: 'render', + value: function render() { + var _this2 = this; + + var _props2 = this.props; + var categories = _props2.categories; + var color = _props2.color; + var i18n = _props2.i18n; + var icons = _props2.icons; + var selected = this.state.selected; + + + return React.createElement( + 'nav', + { className: 'emoji-mart-anchors', 'aria-label': i18n.categorieslabel }, + categories.map(function (category, i) { + var id = category.id; + var name = category.name; + var anchor = category.anchor; + var isSelected = name == selected; + + if (anchor === false) { + return null; + } + + return React.createElement( + 'button', + { + key: id, + 'aria-label': i18n.categories[id], + title: i18n.categories[id], + 'data-index': i, + onClick: _this2.handleClick, + className: 'emoji-mart-anchor ' + (isSelected ? 'emoji-mart-anchor-selected' : ''), + style: { color: isSelected ? color : null } + }, + React.createElement( + 'div', + { className: 'emoji-mart-anchor-icon' }, + icons.categories[id]() + ), + React.createElement('span', { + className: 'emoji-mart-anchor-bar', + style: { backgroundColor: color } + }) + ); + }) + ); + } + }]); + + return Anchors; +}(React.PureComponent); + +export default Anchors; + + +Anchors.propTypes /* remove-proptypes */ = { + categories: PropTypes.array, + onAnchorClick: PropTypes.func, + icons: PropTypes.object +}; + +Anchors.defaultProps = { + categories: [], + onAnchorClick: function onAnchorClick() {}, + icons: {} +}; \ No newline at end of file diff --git a/dist-es/components/category.js b/dist-es/components/category.js new file mode 100644 index 000000000..c17bfd9f4 --- /dev/null +++ b/dist-es/components/category.js @@ -0,0 +1,275 @@ +import _extends from '../polyfills/extends'; +import _Object$getPrototypeOf from '../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../polyfills/classCallCheck'; +import _createClass from '../polyfills/createClass'; +import _possibleConstructorReturn from '../polyfills/possibleConstructorReturn'; +import _inherits from '../polyfills/inherits'; +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 = function (_React$Component) { + _inherits(Category, _React$Component); + + function Category(props) { + _classCallCheck(this, Category); + + var _this = _possibleConstructorReturn(this, (Category.__proto__ || _Object$getPrototypeOf(Category)).call(this, props)); + + _this.data = props.data; + _this.setContainerRef = _this.setContainerRef.bind(_this); + _this.setLabelRef = _this.setLabelRef.bind(_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 _props = this.props; + var name = _props.name; + var perLine = _props.perLine; + var native = _props.native; + var hasStickyPosition = _props.hasStickyPosition; + var emojis = _props.emojis; + var emojiProps = _props.emojiProps; + var skin = emojiProps.skin; + var size = emojiProps.size; + var set = emojiProps.set; + var nextPerLine = nextProps.perLine; + var nextNative = nextProps.native; + var nextHasStickyPosition = nextProps.hasStickyPosition; + var nextEmojis = nextProps.emojis; + var nextEmojiProps = nextProps.emojiProps; + var nextSkin = nextEmojiProps.skin; + var nextSize = nextEmojiProps.size; + var nextSet = nextEmojiProps.set; + var 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() { + var parent = this.container.parentElement; + + var _container$getBoundin = this.container.getBoundingClientRect(); + + var top = _container$getBoundin.top; + var height = _container$getBoundin.height; + + var _parent$getBoundingCl = parent.getBoundingClientRect(); + + var parentTop = _parent$getBoundingCl.top; + + var _label$getBoundingCli = this.label.getBoundingClientRect(); + + var labelHeight = _label$getBoundingCli.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 = margin + 'px'; + } + + this.margin = margin; + return true; + } + }, { + key: 'getEmojis', + value: function getEmojis() { + var _this2 = this; + + var _props2 = this.props; + var name = _props2.name; + var emojis = _props2.emojis; + var recent = _props2.recent; + var perLine = _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) { + 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 _props3 = this.props; + var id = _props3.id; + var name = _props3.name; + var hasStickyPosition = _props3.hasStickyPosition; + var emojiProps = _props3.emojiProps; + var i18n = _props3.i18n; + var notFound = _props3.notFound; + var notFoundEmoji = _props3.notFoundEmoji; + var emojis = this.getEmojis(); + var labelStyles = {}; + var labelSpanStyles = {}; + var containerStyles = {}; + + if (!emojis) { + containerStyles = { + display: 'none' + }; + } + + if (!hasStickyPosition) { + labelStyles = { + height: 28 + }; + + labelSpanStyles = { + position: 'absolute' + }; + } + + return React.createElement( + 'section', + { + ref: this.setContainerRef, + className: 'emoji-mart-category', + 'aria-label': i18n.categories[id], + 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 */ + }, + i18n.categories[id] + ) + ), + emojis && emojis.map(function (emoji) { + return NimbleEmoji(_extends({ 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 default Category; + + +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 +}; \ No newline at end of file diff --git a/dist-es/components/emoji/emoji.js b/dist-es/components/emoji/emoji.js new file mode 100644 index 000000000..f7ba69bd7 --- /dev/null +++ b/dist-es/components/emoji/emoji.js @@ -0,0 +1,23 @@ +import _extends from '../../polyfills/extends'; +import React from 'react'; + +import data from '../../../data/all.json'; +import NimbleEmoji from './nimble-emoji'; + +import { EmojiPropTypes } from '../../utils/shared-props'; +import { EmojiDefaultProps } from '../../utils/shared-default-props'; + +var Emoji = function Emoji(props) { + for (var k in Emoji.defaultProps) { + if (props[k] == undefined && Emoji.defaultProps[k] != undefined) { + props[k] = Emoji.defaultProps[k]; + } + } + + return NimbleEmoji(_extends({}, props)); +}; + +Emoji.propTypes /* remove-proptypes */ = EmojiPropTypes; +Emoji.defaultProps = _extends({}, EmojiDefaultProps, { data: data }); + +export default Emoji; \ No newline at end of file diff --git a/dist-es/components/emoji/nimble-emoji.js b/dist-es/components/emoji/nimble-emoji.js new file mode 100644 index 000000000..a6c3b471a --- /dev/null +++ b/dist-es/components/emoji/nimble-emoji.js @@ -0,0 +1,215 @@ +import _extends from '../../polyfills/extends'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import { getData, getSanitizedData, unifiedToNative } from '../../utils'; +import { uncompress } from '../../utils/data'; +import { EmojiPropTypes } from '../../utils/shared-props'; +import { EmojiDefaultProps } from '../../utils/shared-default-props'; + +var _getData = function _getData(props) { + var emoji = props.emoji; + var skin = props.skin; + var set = props.set; + var data = props.data; + + return getData(emoji, skin, set, data); +}; + +var _getPosition = function _getPosition(props) { + var _getData2 = _getData(props); + + var sheet_x = _getData2.sheet_x; + var sheet_y = _getData2.sheet_y; + var multiplyX = 100 / (props.sheetColumns - 1); + var multiplyY = 100 / (props.sheetRows - 1); + + return multiplyX * sheet_x + '% ' + multiplyY * sheet_y + '%'; +}; + +var _getSanitizedData = function _getSanitizedData(props) { + var emoji = props.emoji; + var skin = props.skin; + var set = props.set; + var data = props.data; + + return getSanitizedData(emoji, skin, set, data); +}; + +var _handleClick = function _handleClick(e, props) { + if (!props.onClick) { + return; + } + var onClick = props.onClick; + var emoji = _getSanitizedData(props); + + onClick(emoji, e); +}; + +var _handleOver = function _handleOver(e, props) { + if (!props.onOver) { + return; + } + var onOver = props.onOver; + var emoji = _getSanitizedData(props); + + onOver(emoji, e); +}; + +var _handleLeave = function _handleLeave(e, props) { + if (!props.onLeave) { + return; + } + var onLeave = props.onLeave; + var emoji = _getSanitizedData(props); + + onLeave(emoji, e); +}; + +var _isNumeric = function _isNumeric(value) { + return !isNaN(value - parseFloat(value)); +}; + +var _convertStyleToCSS = function _convertStyleToCSS(style) { + var div = document.createElement('div'); + + for (var key in style) { + var value = style[key]; + + if (_isNumeric(value)) { + value += 'px'; + } + + div.style[key] = value; + } + + return div.getAttribute('style'); +}; + +var NimbleEmoji = function NimbleEmoji(props) { + if (props.data.compressed) { + uncompress(props.data); + } + + for (var k in NimbleEmoji.defaultProps) { + if (props[k] == undefined && NimbleEmoji.defaultProps[k] != undefined) { + props[k] = NimbleEmoji.defaultProps[k]; + } + } + + var data = _getData(props); + if (!data) { + if (props.fallback) { + return props.fallback(null, props); + } else { + return null; + } + } + + var unified = data.unified; + var custom = data.custom; + var short_names = data.short_names; + var imageUrl = data.imageUrl; + var style = {}; + var children = props.children; + var className = 'emoji-mart-emoji'; + var title = null; + + if (!unified && !custom) { + if (props.fallback) { + return props.fallback(data, props); + } else { + return null; + } + } + + if (props.tooltip) { + title = short_names[0]; + } + + if (props.native && unified) { + className += ' emoji-mart-emoji-native'; + style = { fontSize: props.size }; + children = unifiedToNative(unified); + + if (props.forceSize) { + style.display = 'inline-block'; + style.width = props.size; + style.height = props.size; + style.wordBreak = 'keep-all'; + } + } else if (custom) { + className += ' emoji-mart-emoji-custom'; + style = { + width: props.size, + height: props.size, + display: 'inline-block' + }; + if (data.spriteUrl) { + style = _extends({}, style, { + backgroundImage: 'url(' + data.spriteUrl + ')', + backgroundSize: 100 * props.sheetColumns + '% ' + 100 * props.sheetRows + '%', + backgroundPosition: _getPosition(props) + }); + } else { + style = _extends({}, style, { + backgroundImage: 'url(' + imageUrl + ')', + backgroundSize: 'contain' + }); + } + } else { + var setHasEmoji = data['has_img_' + props.set] == undefined || data['has_img_' + props.set]; + + if (!setHasEmoji) { + if (props.fallback) { + return props.fallback(data, props); + } else { + return null; + } + } else { + style = { + width: props.size, + height: props.size, + display: 'inline-block', + backgroundImage: 'url(' + props.backgroundImageFn(props.set, props.sheetSize) + ')', + backgroundSize: 100 * props.sheetColumns + '% ' + 100 * props.sheetRows + '%', + backgroundPosition: _getPosition(props) + }; + } + } + + if (props.html) { + style = _convertStyleToCSS(style); + return ''; + } else { + return React.createElement( + 'button', + { + key: props.emoji.id || props.emoji, + onClick: function onClick(e) { + return _handleClick(e, props); + }, + onMouseEnter: function onMouseEnter(e) { + return _handleOver(e, props); + }, + onMouseLeave: function onMouseLeave(e) { + return _handleLeave(e, props); + }, + title: title, + className: className + }, + React.createElement( + 'span', + { style: style }, + children + ) + ); + } +}; + +NimbleEmoji.propTypes /* remove-proptypes */ = _extends({}, EmojiPropTypes, { + data: PropTypes.object.isRequired +}); +NimbleEmoji.defaultProps = EmojiDefaultProps; + +export default NimbleEmoji; \ No newline at end of file diff --git a/dist-es/components/not-found.js b/dist-es/components/not-found.js new file mode 100644 index 000000000..96281b346 --- /dev/null +++ b/dist-es/components/not-found.js @@ -0,0 +1,64 @@ +import _extends from '../polyfills/extends'; +import _Object$getPrototypeOf from '../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../polyfills/classCallCheck'; +import _createClass from '../polyfills/createClass'; +import _possibleConstructorReturn from '../polyfills/possibleConstructorReturn'; +import _inherits from '../polyfills/inherits'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import NimbleEmoji from './emoji/nimble-emoji'; + +var NotFound = function (_React$PureComponent) { + _inherits(NotFound, _React$PureComponent); + + function NotFound() { + _classCallCheck(this, NotFound); + + return _possibleConstructorReturn(this, (NotFound.__proto__ || _Object$getPrototypeOf(NotFound)).apply(this, arguments)); + } + + _createClass(NotFound, [{ + key: 'render', + value: function render() { + var _props = this.props; + var data = _props.data; + var emojiProps = _props.emojiProps; + var i18n = _props.i18n; + var notFound = _props.notFound; + var notFoundEmoji = _props.notFoundEmoji; + + + var component = notFound && notFound() || React.createElement( + 'div', + { className: 'emoji-mart-no-results' }, + NimbleEmoji(_extends({ + data: data + }, emojiProps, { + size: 38, + emoji: notFoundEmoji, + onOver: null, + onLeave: null, + onClick: null + })), + React.createElement( + 'div', + { className: 'emoji-mart-no-results-label' }, + i18n.notfound + ) + ); + + return component; + } + }]); + + return NotFound; +}(React.PureComponent); + +export default NotFound; + + +NotFound.propTypes /* remove-proptypes */ = { + notFound: PropTypes.func.isRequired, + emojiProps: PropTypes.object.isRequired +}; \ No newline at end of file diff --git a/dist-es/components/picker/nimble-picker.js b/dist-es/components/picker/nimble-picker.js new file mode 100644 index 000000000..f981ecb51 --- /dev/null +++ b/dist-es/components/picker/nimble-picker.js @@ -0,0 +1,637 @@ +import _extends from '../../polyfills/extends'; +import _Object$getPrototypeOf from '../../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../../polyfills/classCallCheck'; +import _createClass from '../../polyfills/createClass'; +import _possibleConstructorReturn from '../../polyfills/possibleConstructorReturn'; +import _inherits from '../../polyfills/inherits'; +import '../../vendor/raf-polyfill'; + +import React from 'react'; +import PropTypes from 'prop-types'; + +import * as icons from '../../svgs'; +import store from '../../utils/store'; +import frequently from '../../utils/frequently'; +import { deepMerge, measureScrollbar, getSanitizedData } from '../../utils'; +import { uncompress } from '../../utils/data'; +import { PickerPropTypes } from '../../utils/shared-props'; + +import Anchors from '../anchors'; +import Category from '../category'; +import Preview from '../preview'; +import Search from '../search'; +import { PickerDefaultProps } from '../../utils/shared-default-props'; + +var I18N = { + search: 'Search', + clear: 'Clear', // Accessible label on "clear" button + emojilist: 'List of emoji', + notfound: 'No Emoji Found', + skintext: 'Choose your default skin tone', + categories: { + search: 'Search Results', + recent: 'Frequently Used', + people: 'Smileys & People', + nature: 'Animals & Nature', + foods: 'Food & Drink', + activity: 'Activity', + places: 'Travel & Places', + objects: 'Objects', + symbols: 'Symbols', + flags: 'Flags', + custom: 'Custom' + }, + categorieslabel: 'Emoji categories', // Accessible title for the list of categories + skintones: { + 1: 'Default Skin Tone', + 2: 'Light Skin Tone', + 3: 'Medium-Light Skin Tone', + 4: 'Medium Skin Tone', + 5: 'Medium-Dark Skin Tone', + 6: 'Dark Skin Tone' + } +}; + +var NimblePicker = function (_React$PureComponent) { + _inherits(NimblePicker, _React$PureComponent); + + function NimblePicker(props) { + _classCallCheck(this, NimblePicker); + + var _this = _possibleConstructorReturn(this, (NimblePicker.__proto__ || _Object$getPrototypeOf(NimblePicker)).call(this, props)); + + _this.RECENT_CATEGORY = { id: 'recent', name: 'Recent', emojis: null }; + _this.CUSTOM_CATEGORY = { id: 'custom', name: 'Custom', emojis: [] }; + _this.SEARCH_CATEGORY = { + id: 'search', + name: 'Search', + emojis: null, + anchor: false + }; + + if (props.data.compressed) { + uncompress(props.data); + } + + _this.data = props.data; + _this.i18n = deepMerge(I18N, props.i18n); + _this.icons = deepMerge(icons, props.icons); + _this.state = { + skin: props.skin || store.get('skin') || props.defaultSkin, + firstRender: true + }; + + _this.categories = []; + var allCategories = [].concat(_this.data.categories); + + if (props.custom.length > 0) { + _this.CUSTOM_CATEGORY.emojis = props.custom.map(function (emoji) { + return _extends({}, emoji, { + // `` expects emoji to have an `id`. + id: emoji.short_names[0], + custom: true + }); + }); + + allCategories.push(_this.CUSTOM_CATEGORY); + } + + _this.hideRecent = true; + + if (props.include != undefined) { + allCategories.sort(function (a, b) { + if (props.include.indexOf(a.id) > props.include.indexOf(b.id)) { + return 1; + } + + return -1; + }); + } + + for (var categoryIndex = 0; categoryIndex < allCategories.length; categoryIndex++) { + var category = allCategories[categoryIndex]; + var isIncluded = props.include && props.include.length ? props.include.indexOf(category.id) > -1 : true; + var isExcluded = props.exclude && props.exclude.length ? props.exclude.indexOf(category.id) > -1 : false; + if (!isIncluded || isExcluded) { + continue; + } + + if (props.emojisToShowFilter) { + var newEmojis = []; + + var emojis = category.emojis; + + for (var emojiIndex = 0; emojiIndex < emojis.length; emojiIndex++) { + var emoji = emojis[emojiIndex]; + if (props.emojisToShowFilter(_this.data.emojis[emoji] || emoji)) { + newEmojis.push(emoji); + } + } + + if (newEmojis.length) { + var newCategory = { + emojis: newEmojis, + name: category.name, + id: category.id + }; + + _this.categories.push(newCategory); + } + } else { + _this.categories.push(category); + } + } + + var includeRecent = props.include && props.include.length ? props.include.indexOf(_this.RECENT_CATEGORY.id) > -1 : true; + var excludeRecent = props.exclude && props.exclude.length ? props.exclude.indexOf(_this.RECENT_CATEGORY.id) > -1 : false; + if (includeRecent && !excludeRecent) { + _this.hideRecent = false; + _this.categories.unshift(_this.RECENT_CATEGORY); + } + + if (_this.categories[0]) { + _this.categories[0].first = true; + } + + _this.categories.unshift(_this.SEARCH_CATEGORY); + + _this.setAnchorsRef = _this.setAnchorsRef.bind(_this); + _this.handleAnchorClick = _this.handleAnchorClick.bind(_this); + _this.setSearchRef = _this.setSearchRef.bind(_this); + _this.handleSearch = _this.handleSearch.bind(_this); + _this.setScrollRef = _this.setScrollRef.bind(_this); + _this.handleScroll = _this.handleScroll.bind(_this); + _this.handleScrollPaint = _this.handleScrollPaint.bind(_this); + _this.handleEmojiOver = _this.handleEmojiOver.bind(_this); + _this.handleEmojiLeave = _this.handleEmojiLeave.bind(_this); + _this.handleEmojiClick = _this.handleEmojiClick.bind(_this); + _this.handleEmojiSelect = _this.handleEmojiSelect.bind(_this); + _this.setPreviewRef = _this.setPreviewRef.bind(_this); + _this.handleSkinChange = _this.handleSkinChange.bind(_this); + _this.handleKeyDown = _this.handleKeyDown.bind(_this); + return _this; + } + + _createClass(NimblePicker, [{ + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(props) { + if (props.skin) { + this.setState({ skin: props.skin }); + } else if (props.defaultSkin && !store.get('skin')) { + this.setState({ skin: props.defaultSkin }); + } + } + }, { + key: 'componentDidMount', + value: function componentDidMount() { + var _this2 = this; + + if (this.state.firstRender) { + this.testStickyPosition(); + this.firstRenderTimeout = setTimeout(function () { + _this2.setState({ firstRender: false }); + }, 60); + } + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate() { + this.updateCategoriesSize(); + this.handleScroll(); + } + }, { + key: 'componentWillUnmount', + value: function componentWillUnmount() { + this.SEARCH_CATEGORY.emojis = null; + + clearTimeout(this.leaveTimeout); + clearTimeout(this.firstRenderTimeout); + } + }, { + key: 'testStickyPosition', + value: function testStickyPosition() { + var stickyTestElement = document.createElement('div'); + + var prefixes = ['', '-webkit-', '-ms-', '-moz-', '-o-']; + + prefixes.forEach(function (prefix) { + return stickyTestElement.style.position = prefix + 'sticky'; + }); + + this.hasStickyPosition = !!stickyTestElement.style.position.length; + } + }, { + key: 'handleEmojiOver', + value: function handleEmojiOver(emoji) { + var preview = this.preview; + + if (!preview) { + return; + } + + // Use Array.prototype.find() when it is more widely supported. + var emojiData = this.CUSTOM_CATEGORY.emojis.filter(function (customEmoji) { + return customEmoji.id === emoji.id; + })[0]; + for (var key in emojiData) { + if (emojiData.hasOwnProperty(key)) { + emoji[key] = emojiData[key]; + } + } + + preview.setState({ emoji: emoji }); + clearTimeout(this.leaveTimeout); + } + }, { + key: 'handleEmojiLeave', + value: function handleEmojiLeave(emoji) { + var preview = this.preview; + + if (!preview) { + return; + } + + this.leaveTimeout = setTimeout(function () { + preview.setState({ emoji: null }); + }, 16); + } + }, { + key: 'handleEmojiClick', + value: function handleEmojiClick(emoji, e) { + this.props.onClick(emoji, e); + this.handleEmojiSelect(emoji); + } + }, { + key: 'handleEmojiSelect', + value: function handleEmojiSelect(emoji) { + var _this3 = this; + + this.props.onSelect(emoji); + if (!this.hideRecent && !this.props.recent) frequently.add(emoji); + + var component = this.categoryRefs['category-1']; + if (component) { + var maxMargin = component.maxMargin; + component.forceUpdate(); + + window.requestAnimationFrame(function () { + if (!_this3.scroll) return; + component.memoizeSize(); + if (maxMargin == component.maxMargin) return; + + _this3.updateCategoriesSize(); + _this3.handleScrollPaint(); + + if (_this3.SEARCH_CATEGORY.emojis) { + component.updateDisplay('none'); + } + }); + } + } + }, { + key: 'handleScroll', + value: function handleScroll() { + if (!this.waitingForPaint) { + this.waitingForPaint = true; + window.requestAnimationFrame(this.handleScrollPaint); + } + } + }, { + key: 'handleScrollPaint', + value: function handleScrollPaint() { + this.waitingForPaint = false; + + if (!this.scroll) { + return; + } + + var activeCategory = null; + + if (this.SEARCH_CATEGORY.emojis) { + activeCategory = this.SEARCH_CATEGORY; + } else { + var target = this.scroll, + scrollTop = target.scrollTop, + scrollingDown = scrollTop > (this.scrollTop || 0), + minTop = 0; + + for (var i = 0, l = this.categories.length; i < l; i++) { + var ii = scrollingDown ? this.categories.length - 1 - i : i, + category = this.categories[ii], + component = this.categoryRefs['category-' + ii]; + + if (component) { + var active = component.handleScroll(scrollTop); + + if (!minTop || component.top < minTop) { + if (component.top > 0) { + minTop = component.top; + } + } + + if (active && !activeCategory) { + activeCategory = category; + } + } + } + + if (scrollTop < minTop) { + activeCategory = this.categories.filter(function (category) { + return !(category.anchor === false); + })[0]; + } else if (scrollTop + this.clientHeight >= this.scrollHeight) { + activeCategory = this.categories[this.categories.length - 1]; + } + } + + if (activeCategory) { + var anchors = this.anchors; + var _activeCategory = activeCategory; + var categoryName = _activeCategory.name; + + + if (anchors.state.selected != categoryName) { + anchors.setState({ selected: categoryName }); + } + } + + this.scrollTop = scrollTop; + } + }, { + key: 'handleSearch', + value: function handleSearch(emojis) { + this.SEARCH_CATEGORY.emojis = emojis; + + for (var i = 0, l = this.categories.length; i < l; i++) { + var component = this.categoryRefs['category-' + i]; + + if (component && component.props.name != 'Search') { + var display = emojis ? 'none' : 'inherit'; + component.updateDisplay(display); + } + } + + this.forceUpdate(); + this.scroll.scrollTop = 0; + this.handleScroll(); + } + }, { + key: 'handleAnchorClick', + value: function handleAnchorClick(category, i) { + var component = this.categoryRefs['category-' + i]; + var scroll = this.scroll; + var anchors = this.anchors; + var scrollToComponent = null; + + scrollToComponent = function scrollToComponent() { + if (component) { + var top = component.top; + + + if (category.first) { + top = 0; + } else { + top += 1; + } + + scroll.scrollTop = top; + } + }; + + if (this.SEARCH_CATEGORY.emojis) { + this.handleSearch(null); + this.search.clear(); + + window.requestAnimationFrame(scrollToComponent); + } else { + scrollToComponent(); + } + } + }, { + key: 'handleSkinChange', + value: function handleSkinChange(skin) { + var newState = { skin: skin }; + var onSkinChange = this.props.onSkinChange; + + + this.setState(newState); + store.update(newState); + + onSkinChange(skin); + } + }, { + key: 'handleKeyDown', + value: function handleKeyDown(e) { + var handled = false; + + switch (e.keyCode) { + case 13: + var emoji = void 0; + + if (this.SEARCH_CATEGORY.emojis && this.SEARCH_CATEGORY.emojis.length && (emoji = getSanitizedData(this.SEARCH_CATEGORY.emojis[0], this.state.skin, this.props.set, this.props.data))) { + this.handleEmojiSelect(emoji); + } + + handled = true; + break; + } + + if (handled) { + e.preventDefault(); + } + } + }, { + key: 'updateCategoriesSize', + value: function updateCategoriesSize() { + for (var i = 0, l = this.categories.length; i < l; i++) { + var component = this.categoryRefs['category-' + i]; + if (component) component.memoizeSize(); + } + + if (this.scroll) { + var target = this.scroll; + this.scrollHeight = target.scrollHeight; + this.clientHeight = target.clientHeight; + } + } + }, { + key: 'getCategories', + value: function getCategories() { + return this.state.firstRender ? this.categories.slice(0, 3) : this.categories; + } + }, { + key: 'setAnchorsRef', + value: function setAnchorsRef(c) { + this.anchors = c; + } + }, { + key: 'setSearchRef', + value: function setSearchRef(c) { + this.search = c; + } + }, { + key: 'setPreviewRef', + value: function setPreviewRef(c) { + this.preview = c; + } + }, { + key: 'setScrollRef', + value: function setScrollRef(c) { + this.scroll = c; + } + }, { + key: 'setCategoryRef', + value: function setCategoryRef(name, c) { + if (!this.categoryRefs) { + this.categoryRefs = {}; + } + + this.categoryRefs[name] = c; + } + }, { + key: 'render', + value: function render() { + var _this4 = this; + + var _props = this.props; + var perLine = _props.perLine; + var emojiSize = _props.emojiSize; + var set = _props.set; + var sheetSize = _props.sheetSize; + var sheetColumns = _props.sheetColumns; + var sheetRows = _props.sheetRows; + var style = _props.style; + var title = _props.title; + var emoji = _props.emoji; + var color = _props.color; + var native = _props.native; + var backgroundImageFn = _props.backgroundImageFn; + var emojisToShowFilter = _props.emojisToShowFilter; + var showPreview = _props.showPreview; + var showSkinTones = _props.showSkinTones; + var emojiTooltip = _props.emojiTooltip; + var include = _props.include; + var exclude = _props.exclude; + var recent = _props.recent; + var autoFocus = _props.autoFocus; + var skinEmoji = _props.skinEmoji; + var notFound = _props.notFound; + var notFoundEmoji = _props.notFoundEmoji; + var skin = this.state.skin; + var width = perLine * (emojiSize + 12) + 12 + 2 + measureScrollbar(); + + return React.createElement( + 'div', + { + style: _extends({ width: width }, style), + className: 'emoji-mart', + onKeyDown: this.handleKeyDown + }, + React.createElement( + 'div', + { className: 'emoji-mart-bar' }, + React.createElement(Anchors, { + ref: this.setAnchorsRef, + data: this.data, + i18n: this.i18n, + color: color, + categories: this.categories, + onAnchorClick: this.handleAnchorClick, + icons: this.icons + }) + ), + React.createElement(Search, { + ref: this.setSearchRef, + onSearch: this.handleSearch, + data: this.data, + i18n: this.i18n, + emojisToShowFilter: emojisToShowFilter, + include: include, + exclude: exclude, + custom: this.CUSTOM_CATEGORY.emojis, + autoFocus: autoFocus + }), + React.createElement( + 'section', + { + ref: this.setScrollRef, + className: 'emoji-mart-scroll', + 'aria-label': this.i18n.emojilist, + onScroll: this.handleScroll + }, + this.getCategories().map(function (category, i) { + return React.createElement(Category, { + ref: _this4.setCategoryRef.bind(_this4, 'category-' + i), + key: category.name, + id: category.id, + name: category.name, + emojis: category.emojis, + perLine: perLine, + native: native, + hasStickyPosition: _this4.hasStickyPosition, + data: _this4.data, + i18n: _this4.i18n, + recent: category.id == _this4.RECENT_CATEGORY.id ? recent : undefined, + custom: category.id == _this4.RECENT_CATEGORY.id ? _this4.CUSTOM_CATEGORY.emojis : undefined, + emojiProps: { + native: native, + skin: skin, + size: emojiSize, + set: set, + sheetSize: sheetSize, + sheetColumns: sheetColumns, + sheetRows: sheetRows, + forceSize: native, + tooltip: emojiTooltip, + backgroundImageFn: backgroundImageFn, + onOver: _this4.handleEmojiOver, + onLeave: _this4.handleEmojiLeave, + onClick: _this4.handleEmojiClick + }, + notFound: notFound, + notFoundEmoji: notFoundEmoji + }); + }) + ), + (showPreview || showSkinTones) && React.createElement( + 'div', + { className: 'emoji-mart-bar' }, + React.createElement(Preview, { + ref: this.setPreviewRef, + data: this.data, + title: title, + emoji: emoji, + showSkinTones: showSkinTones, + showPreview: showPreview, + emojiProps: { + native: native, + size: 38, + skin: skin, + set: set, + sheetSize: sheetSize, + sheetColumns: sheetColumns, + sheetRows: sheetRows, + backgroundImageFn: backgroundImageFn + }, + skinsProps: { + skin: skin, + onChange: this.handleSkinChange, + skinEmoji: skinEmoji + }, + i18n: this.i18n + }) + ) + ); + } + }]); + + return NimblePicker; +}(React.PureComponent); + +export default NimblePicker; + + +NimblePicker.propTypes /* remove-proptypes */ = _extends({}, PickerPropTypes, { + data: PropTypes.object.isRequired +}); +NimblePicker.defaultProps = _extends({}, PickerDefaultProps); \ No newline at end of file diff --git a/dist-es/components/picker/picker.js b/dist-es/components/picker/picker.js new file mode 100644 index 000000000..60f1d28f2 --- /dev/null +++ b/dist-es/components/picker/picker.js @@ -0,0 +1,38 @@ +import _extends from '../../polyfills/extends'; +import _Object$getPrototypeOf from '../../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../../polyfills/classCallCheck'; +import _createClass from '../../polyfills/createClass'; +import _possibleConstructorReturn from '../../polyfills/possibleConstructorReturn'; +import _inherits from '../../polyfills/inherits'; +import React from 'react'; + +import data from '../../../data/all.json'; +import NimblePicker from './nimble-picker'; + +import { PickerPropTypes } from '../../utils/shared-props'; +import { PickerDefaultProps } from '../../utils/shared-default-props'; + +var Picker = function (_React$PureComponent) { + _inherits(Picker, _React$PureComponent); + + function Picker() { + _classCallCheck(this, Picker); + + return _possibleConstructorReturn(this, (Picker.__proto__ || _Object$getPrototypeOf(Picker)).apply(this, arguments)); + } + + _createClass(Picker, [{ + key: 'render', + value: function render() { + return React.createElement(NimblePicker, _extends({}, this.props, this.state)); + } + }]); + + return Picker; +}(React.PureComponent); + +export default Picker; + + +Picker.propTypes /* remove-proptypes */ = PickerPropTypes; +Picker.defaultProps = _extends({}, PickerDefaultProps, { data: data }); \ No newline at end of file diff --git a/dist-es/components/preview.js b/dist-es/components/preview.js new file mode 100644 index 000000000..73aabddf9 --- /dev/null +++ b/dist-es/components/preview.js @@ -0,0 +1,162 @@ +import _extends from '../polyfills/extends'; +import _Object$getPrototypeOf from '../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../polyfills/classCallCheck'; +import _createClass from '../polyfills/createClass'; +import _possibleConstructorReturn from '../polyfills/possibleConstructorReturn'; +import _inherits from '../polyfills/inherits'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import { getData } from '../utils'; +import NimbleEmoji from './emoji/nimble-emoji'; +import SkinsEmoji from './skins-emoji'; +import SkinsDot from './skins-dot'; + +var Preview = function (_React$PureComponent) { + _inherits(Preview, _React$PureComponent); + + function Preview(props) { + _classCallCheck(this, Preview); + + var _this = _possibleConstructorReturn(this, (Preview.__proto__ || _Object$getPrototypeOf(Preview)).call(this, props)); + + _this.data = props.data; + _this.state = { emoji: null }; + return _this; + } + + _createClass(Preview, [{ + key: 'render', + value: function render() { + var emoji = this.state.emoji; + var _props = this.props; + var emojiProps = _props.emojiProps; + var skinsProps = _props.skinsProps; + var showSkinTones = _props.showSkinTones; + var title = _props.title; + var idleEmoji = _props.emoji; + var i18n = _props.i18n; + var showPreview = _props.showPreview; + + + if (emoji && showPreview) { + var emojiData = getData(emoji, null, null, this.data); + var _emojiData$emoticons = emojiData.emoticons; + var emoticons = _emojiData$emoticons === undefined ? [] : _emojiData$emoticons; + var knownEmoticons = []; + var listedEmoticons = []; + + emoticons.forEach(function (emoticon) { + if (knownEmoticons.indexOf(emoticon.toLowerCase()) >= 0) { + return; + } + + knownEmoticons.push(emoticon.toLowerCase()); + listedEmoticons.push(emoticon); + }); + + return React.createElement( + 'div', + { className: 'emoji-mart-preview' }, + React.createElement( + 'div', + { className: 'emoji-mart-preview-emoji' }, + NimbleEmoji(_extends({ + key: emoji.id, + emoji: emoji, + data: this.data + }, emojiProps)) + ), + React.createElement( + 'div', + { className: 'emoji-mart-preview-data' }, + React.createElement( + 'div', + { className: 'emoji-mart-preview-name' }, + emoji.name + ), + React.createElement( + 'div', + { className: 'emoji-mart-preview-shortnames' }, + emojiData.short_names.map(function (short_name) { + return React.createElement( + 'span', + { key: short_name, className: 'emoji-mart-preview-shortname' }, + ':', + short_name, + ':' + ); + }) + ), + React.createElement( + 'div', + { className: 'emoji-mart-preview-emoticons' }, + listedEmoticons.map(function (emoticon) { + return React.createElement( + 'span', + { key: emoticon, className: 'emoji-mart-preview-emoticon' }, + emoticon + ); + }) + ) + ) + ); + } else { + return React.createElement( + 'div', + { className: 'emoji-mart-preview' }, + React.createElement( + 'div', + { className: 'emoji-mart-preview-emoji' }, + idleEmoji && idleEmoji.length && NimbleEmoji(_extends({ emoji: idleEmoji, data: this.data }, emojiProps)) + ), + React.createElement( + 'div', + { className: 'emoji-mart-preview-data' }, + React.createElement( + 'span', + { className: 'emoji-mart-title-label' }, + title + ) + ), + showSkinTones && React.createElement( + 'div', + { + className: 'emoji-mart-preview-skins' + (skinsProps.skinEmoji ? ' custom' : '') + }, + skinsProps.skinEmoji ? React.createElement(SkinsEmoji, { + skin: skinsProps.skin, + emojiProps: emojiProps, + data: this.data, + skinEmoji: skinsProps.skinEmoji, + i18n: i18n, + onChange: skinsProps.onChange + }) : React.createElement(SkinsDot, { + skin: skinsProps.skin, + i18n: i18n, + onChange: skinsProps.onChange + }) + ) + ); + } + } + }]); + + return Preview; +}(React.PureComponent); + +export default Preview; + + +Preview.propTypes /* remove-proptypes */ = { + showSkinTones: PropTypes.bool, + title: PropTypes.string.isRequired, + emoji: PropTypes.string.isRequired, + emojiProps: PropTypes.object.isRequired, + skinsProps: PropTypes.object.isRequired +}; + +Preview.defaultProps = { + showSkinTones: true, + onChange: function onChange() {} +}; \ No newline at end of file diff --git a/dist-es/components/search.js b/dist-es/components/search.js new file mode 100644 index 000000000..c87fbbb5d --- /dev/null +++ b/dist-es/components/search.js @@ -0,0 +1,146 @@ +import _Object$getPrototypeOf from '../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../polyfills/classCallCheck'; +import _createClass from '../polyfills/createClass'; +import _possibleConstructorReturn from '../polyfills/possibleConstructorReturn'; +import _inherits from '../polyfills/inherits'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import { search as icons } from '../svgs'; +import NimbleEmojiIndex from '../utils/emoji-index/nimble-emoji-index'; +import { throttleIdleTask } from '../utils/index'; + +var id = 0; + +var Search = function (_React$PureComponent) { + _inherits(Search, _React$PureComponent); + + function Search(props) { + _classCallCheck(this, Search); + + var _this = _possibleConstructorReturn(this, (Search.__proto__ || _Object$getPrototypeOf(Search)).call(this, props)); + + _this.state = { + icon: icons.search, + isSearching: false, + id: ++id + }; + + _this.data = props.data; + _this.emojiIndex = new NimbleEmojiIndex(_this.data); + _this.setRef = _this.setRef.bind(_this); + _this.clear = _this.clear.bind(_this); + _this.handleKeyUp = _this.handleKeyUp.bind(_this); + + // throttle keyboard input so that typing isn't delayed + _this.handleChange = throttleIdleTask(_this.handleChange.bind(_this)); + return _this; + } + + _createClass(Search, [{ + key: 'search', + value: function search(value) { + if (value == '') this.setState({ + icon: icons.search, + isSearching: false + });else this.setState({ + icon: icons.delete, + isSearching: true + }); + + this.props.onSearch(this.emojiIndex.search(value, { + emojisToShowFilter: this.props.emojisToShowFilter, + maxResults: this.props.maxResults, + include: this.props.include, + exclude: this.props.exclude, + custom: this.props.custom + })); + } + }, { + key: 'clear', + value: function clear() { + if (this.input.value == '') return; + this.input.value = ''; + this.input.focus(); + this.search(''); + } + }, { + key: 'handleChange', + value: function handleChange() { + this.search(this.input.value); + } + }, { + key: 'handleKeyUp', + value: function handleKeyUp(e) { + if (e.keyCode === 13) { + this.clear(); + } + } + }, { + key: 'setRef', + value: function setRef(c) { + this.input = c; + } + }, { + key: 'render', + value: function render() { + var _props = this.props; + var i18n = _props.i18n; + var autoFocus = _props.autoFocus; + var _state = this.state; + var icon = _state.icon; + var isSearching = _state.isSearching; + var id = _state.id; + + var inputId = 'emoji-mart-search-' + id; + + return React.createElement( + 'div', + { className: 'emoji-mart-search' }, + React.createElement('input', { + id: inputId, + ref: this.setRef, + type: 'search', + onChange: this.handleChange, + placeholder: i18n.search, + autoFocus: autoFocus + }), + React.createElement( + 'label', + { className: 'emoji-mart-sr-only', htmlFor: inputId }, + i18n.search + ), + React.createElement( + 'button', + { + className: 'emoji-mart-search-icon', + onClick: this.clear, + onKeyUp: this.handleKeyUp, + 'aria-label': i18n.clear, + disabled: !isSearching + }, + icon() + ) + ); + } + }]); + + return Search; +}(React.PureComponent); + +export default Search; + + +Search.propTypes /* remove-proptypes */ = { + onSearch: PropTypes.func, + maxResults: PropTypes.number, + emojisToShowFilter: PropTypes.func, + autoFocus: PropTypes.bool +}; + +Search.defaultProps = { + onSearch: function onSearch() {}, + maxResults: 75, + emojisToShowFilter: null, + autoFocus: false +}; \ No newline at end of file diff --git a/dist-es/components/skins-dot.js b/dist-es/components/skins-dot.js new file mode 100644 index 000000000..d9196b337 --- /dev/null +++ b/dist-es/components/skins-dot.js @@ -0,0 +1,93 @@ +import _Object$getPrototypeOf from '../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../polyfills/classCallCheck'; +import _createClass from '../polyfills/createClass'; +import _possibleConstructorReturn from '../polyfills/possibleConstructorReturn'; +import _inherits from '../polyfills/inherits'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import Skins from './skins'; + +var SkinsDot = function (_Skins) { + _inherits(SkinsDot, _Skins); + + function SkinsDot(props) { + _classCallCheck(this, SkinsDot); + + var _this = _possibleConstructorReturn(this, (SkinsDot.__proto__ || _Object$getPrototypeOf(SkinsDot)).call(this, props)); + + _this.handleClick = _this.handleClick.bind(_this); + _this.handleKeyDown = _this.handleKeyDown.bind(_this); + return _this; + } + + _createClass(SkinsDot, [{ + key: 'handleKeyDown', + value: function handleKeyDown(event) { + // if either enter or space is pressed, then execute + if (event.keyCode === 13 || event.keyCode === 32) { + this.handleClick(event); + } + } + }, { + key: 'render', + value: function render() { + var _props = this.props; + var skin = _props.skin; + var i18n = _props.i18n; + var opened = this.state.opened; + + var skinToneNodes = []; + + for (var skinTone = 1; skinTone <= 6; skinTone++) { + var selected = skinTone === skin; + var visible = opened || selected; + skinToneNodes.push(React.createElement( + 'span', + { + key: 'skin-tone-' + skinTone, + className: 'emoji-mart-skin-swatch' + (selected ? ' selected' : '') + }, + React.createElement('span', { + onClick: this.handleClick, + onKeyDown: this.handleKeyDown, + role: 'button', + tabindex: visible ? '0' : '', + 'aria-hidden': !visible, + 'aria-pressed': opened ? !!selected : '', + 'aria-haspopup': !!selected, + 'aria-expanded': selected ? opened : '', + 'aria-label': i18n.skintones[skinTone], + title: i18n.skintones[skinTone], + 'data-skin': skinTone, + className: 'emoji-mart-skin emoji-mart-skin-tone-' + skinTone + }) + )); + } + + return React.createElement( + 'section', + { + className: 'emoji-mart-skin-swatches' + (opened ? ' opened' : ''), + 'aria-label': i18n.skintext + }, + skinToneNodes + ); + } + }]); + + return SkinsDot; +}(Skins); + +export default SkinsDot; + + +SkinsDot.propTypes /* remove-proptypes */ = { + onChange: PropTypes.func, + skin: PropTypes.number.isRequired, + i18n: PropTypes.object +}; + +SkinsDot.defaultProps = { + onChange: function onChange() {} +}; \ No newline at end of file diff --git a/dist-es/components/skins-emoji.js b/dist-es/components/skins-emoji.js new file mode 100644 index 000000000..a0bc6f7e6 --- /dev/null +++ b/dist-es/components/skins-emoji.js @@ -0,0 +1,99 @@ +import _Object$getPrototypeOf from '../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../polyfills/classCallCheck'; +import _createClass from '../polyfills/createClass'; +import _possibleConstructorReturn from '../polyfills/possibleConstructorReturn'; +import _inherits from '../polyfills/inherits'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import NimbleEmoji from './emoji/nimble-emoji'; +import Skins from './skins'; + +var SkinsEmoji = function (_Skins) { + _inherits(SkinsEmoji, _Skins); + + function SkinsEmoji(props) { + _classCallCheck(this, SkinsEmoji); + + var _this = _possibleConstructorReturn(this, (SkinsEmoji.__proto__ || _Object$getPrototypeOf(SkinsEmoji)).call(this, props)); + + _this.handleClick = _this.handleClick.bind(_this); + return _this; + } + + _createClass(SkinsEmoji, [{ + key: 'render', + value: function render() { + var _props = this.props; + var skin = _props.skin; + var emojiProps = _props.emojiProps; + var data = _props.data; + var skinEmoji = _props.skinEmoji; + var i18n = _props.i18n; + var opened = this.state.opened; + + var skinToneNodes = []; + + for (var skinTone = 1; skinTone <= 6; skinTone++) { + var selected = skinTone === skin; + skinToneNodes.push(React.createElement( + 'span', + { + key: 'skin-tone-' + skinTone, + className: 'emoji-mart-skin-swatch custom' + (selected ? ' selected' : '') + }, + React.createElement( + 'span', + { + onClick: this.handleClick, + 'data-skin': skinTone, + className: 'emoji-mart-skin-tone-' + skinTone + }, + NimbleEmoji({ + emoji: skinEmoji, + data: data, + skin: skinTone, + backgroundImageFn: emojiProps.backgroundImageFn, + native: emojiProps.native, + set: emojiProps.set, + sheetSize: emojiProps.sheetSize, + size: 23 + }) + ) + )); + } + + return React.createElement( + 'div', + { + className: 'emoji-mart-skin-swatches custom' + (opened ? ' opened' : '') + }, + React.createElement( + 'div', + { className: 'emoji-mart-skin-text' + (opened ? ' opened' : '') }, + i18n.skintext + ), + skinToneNodes + ); + } + }]); + + return SkinsEmoji; +}(Skins); + +export default SkinsEmoji; + + +SkinsEmoji.propTypes /* remove-proptypes */ = { + onChange: PropTypes.func, + skin: PropTypes.number.isRequired, + emojiProps: PropTypes.object.isRequired, + skinTone: PropTypes.number, + skinEmoji: PropTypes.string.isRequired, + i18n: PropTypes.object +}; + +SkinsEmoji.defaultProps = { + onChange: function onChange() {}, + skinTone: null +}; \ No newline at end of file diff --git a/dist-es/components/skins.js b/dist-es/components/skins.js new file mode 100644 index 000000000..86bebb774 --- /dev/null +++ b/dist-es/components/skins.js @@ -0,0 +1,61 @@ +import _Object$getPrototypeOf from '../polyfills/objectGetPrototypeOf'; +import _classCallCheck from '../polyfills/classCallCheck'; +import _createClass from '../polyfills/createClass'; +import _possibleConstructorReturn from '../polyfills/possibleConstructorReturn'; +import _inherits from '../polyfills/inherits'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import NimbleEmoji from './emoji/nimble-emoji'; + +var Skins = function (_React$PureComponent) { + _inherits(Skins, _React$PureComponent); + + function Skins(props) { + _classCallCheck(this, Skins); + + var _this = _possibleConstructorReturn(this, (Skins.__proto__ || _Object$getPrototypeOf(Skins)).call(this, props)); + + _this.state = { + opened: false + }; + return _this; + } + + _createClass(Skins, [{ + key: 'handleClick', + value: function handleClick(e) { + var skin = parseInt(e.currentTarget.getAttribute('data-skin')); + var onChange = this.props.onChange; + + + if (!this.state.opened) { + this.setState({ opened: true }); + } else { + this.setState({ opened: false }); + if (skin != this.props.skin) { + onChange(skin); + } + } + } + }, { + key: 'render', + value: function render() { + return null; + } + }]); + + return Skins; +}(React.PureComponent); + +export default Skins; + + +Skins.propTypes /* remove-proptypes */ = { + onChange: PropTypes.func, + skin: PropTypes.number.isRequired +}; + +Skins.defaultProps = { + onChange: function onChange() {} +}; \ No newline at end of file diff --git a/dist-es/index.js b/dist-es/index.js new file mode 100644 index 000000000..29c206f59 --- /dev/null +++ b/dist-es/index.js @@ -0,0 +1,10 @@ +export { default as emojiIndex } from './utils/emoji-index/emoji-index'; +export { default as NimbleEmojiIndex } from './utils/emoji-index/nimble-emoji-index'; +export { default as store } from './utils/store'; +export { default as frequently } from './utils/frequently'; + +export { default as Picker } from './components/picker/picker'; +export { default as NimblePicker } from './components/picker/nimble-picker'; +export { default as Emoji } from './components/emoji/emoji'; +export { default as NimbleEmoji } from './components/emoji/nimble-emoji'; +export { default as Category } from './components/category'; \ No newline at end of file diff --git a/dist-es/polyfills/classCallCheck.js b/dist-es/polyfills/classCallCheck.js new file mode 100644 index 000000000..054dcc123 --- /dev/null +++ b/dist-es/polyfills/classCallCheck.js @@ -0,0 +1,5 @@ +export default function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } +} \ No newline at end of file diff --git a/dist-es/polyfills/createClass.js b/dist-es/polyfills/createClass.js new file mode 100644 index 000000000..69ffa034f --- /dev/null +++ b/dist-es/polyfills/createClass.js @@ -0,0 +1,19 @@ +var _Object = Object; + +export default (function createClass() { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) descriptor.writable = true; + _Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +})(); \ No newline at end of file diff --git a/dist-es/polyfills/extends.js b/dist-es/polyfills/extends.js new file mode 100644 index 000000000..e692f27ed --- /dev/null +++ b/dist-es/polyfills/extends.js @@ -0,0 +1,15 @@ +var _Object = Object; + +export default _Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; +}; \ No newline at end of file diff --git a/dist-es/polyfills/inherits.js b/dist-es/polyfills/inherits.js new file mode 100644 index 000000000..1b8b766ee --- /dev/null +++ b/dist-es/polyfills/inherits.js @@ -0,0 +1,19 @@ +var _Object = Object; + +export default function inherits(subClass, superClass) { + if (typeof superClass !== 'function' && superClass !== null) { + throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); + } + + subClass.prototype = _Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) { + _Object.setPrototypeOf ? _Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } +} \ No newline at end of file diff --git a/dist-es/polyfills/keys.js b/dist-es/polyfills/keys.js new file mode 100644 index 000000000..14c25a7c1 --- /dev/null +++ b/dist-es/polyfills/keys.js @@ -0,0 +1,30 @@ +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys +var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !{ toString: null }.propertyIsEnumerable('toString'), + dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'], + dontEnumsLength = dontEnums.length; + +export default function (obj) { + if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) { + throw new TypeError('Object.keys called on non-object'); + } + + var result = [], + prop, + i; + + for (prop in obj) { + if (hasOwnProperty.call(obj, prop)) { + result.push(prop); + } + } + + if (hasDontEnumBug) { + for (i = 0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) { + result.push(dontEnums[i]); + } + } + } + return result; +} \ No newline at end of file diff --git a/dist-es/polyfills/objectGetPrototypeOf.js b/dist-es/polyfills/objectGetPrototypeOf.js new file mode 100644 index 000000000..e4db6faf1 --- /dev/null +++ b/dist-es/polyfills/objectGetPrototypeOf.js @@ -0,0 +1,11 @@ +var _Object = Object; + +export default _Object.getPrototypeOf || function (O) { + O = Object(O); + + if (typeof O.constructor === 'function' && O instanceof O.constructor) { + return O.constructor.prototype; + } + + return O instanceof Object ? Object.prototype : null; +}; \ No newline at end of file diff --git a/dist-es/polyfills/possibleConstructorReturn.js b/dist-es/polyfills/possibleConstructorReturn.js new file mode 100644 index 000000000..a87e72212 --- /dev/null +++ b/dist-es/polyfills/possibleConstructorReturn.js @@ -0,0 +1,7 @@ +export default function possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === 'object' || typeof call === 'function') ? call : self; +} \ No newline at end of file diff --git a/dist-es/polyfills/stringFromCodePoint.js b/dist-es/polyfills/stringFromCodePoint.js new file mode 100644 index 000000000..0bdf20825 --- /dev/null +++ b/dist-es/polyfills/stringFromCodePoint.js @@ -0,0 +1,40 @@ +var _String = String; + +export default _String.fromCodePoint || function stringFromCodePoint() { + var MAX_SIZE = 0x4000; + var codeUnits = []; + var highSurrogate; + var lowSurrogate; + var index = -1; + var length = arguments.length; + if (!length) { + return ''; + } + var result = ''; + while (++index < length) { + var codePoint = Number(arguments[index]); + if (!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity` + codePoint < 0 || // not a valid Unicode code point + codePoint > 0x10ffff || // not a valid Unicode code point + Math.floor(codePoint) != codePoint // not an integer + ) { + throw RangeError('Invalid code point: ' + codePoint); + } + if (codePoint <= 0xffff) { + // BMP code point + codeUnits.push(codePoint); + } else { + // Astral code point; split in surrogate halves + // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + codePoint -= 0x10000; + highSurrogate = (codePoint >> 10) + 0xd800; + lowSurrogate = codePoint % 0x400 + 0xdc00; + codeUnits.push(highSurrogate, lowSurrogate); + } + if (index + 1 === length || codeUnits.length > MAX_SIZE) { + result += String.fromCharCode.apply(null, codeUnits); + codeUnits.length = 0; + } + } + return result; +}; \ No newline at end of file diff --git a/dist-es/svgs/index.js b/dist-es/svgs/index.js new file mode 100644 index 000000000..78b811d92 --- /dev/null +++ b/dist-es/svgs/index.js @@ -0,0 +1,192 @@ +import React from "react"; + +var categories = { + activity: function activity() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M12 0C5.373 0 0 5.372 0 12c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.628-5.372-12-12-12m9.949 11H17.05c.224-2.527 1.232-4.773 1.968-6.113A9.966 9.966 0 0 1 21.949 11M13 11V2.051a9.945 9.945 0 0 1 4.432 1.564c-.858 1.491-2.156 4.22-2.392 7.385H13zm-2 0H8.961c-.238-3.165-1.536-5.894-2.393-7.385A9.95 9.95 0 0 1 11 2.051V11zm0 2v8.949a9.937 9.937 0 0 1-4.432-1.564c.857-1.492 2.155-4.221 2.393-7.385H11zm4.04 0c.236 3.164 1.534 5.893 2.392 7.385A9.92 9.92 0 0 1 13 21.949V13h2.04zM4.982 4.887C5.718 6.227 6.726 8.473 6.951 11h-4.9a9.977 9.977 0 0 1 2.931-6.113M2.051 13h4.9c-.226 2.527-1.233 4.771-1.969 6.113A9.972 9.972 0 0 1 2.051 13m16.967 6.113c-.735-1.342-1.744-3.586-1.968-6.113h4.899a9.961 9.961 0 0 1-2.931 6.113" }) + ); + }, + + custom: function custom() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement( + "g", + { transform: "translate(2.000000, 1.000000)" }, + React.createElement("rect", { id: "Rectangle", x: "8", y: "0", width: "3", height: "21", rx: "1.5" }), + React.createElement("rect", { + id: "Rectangle", + transform: "translate(9.843, 10.549) rotate(60) translate(-9.843, -10.549) ", + x: "8.343", + y: "0.049", + width: "3", + height: "21", + rx: "1.5" + }), + React.createElement("rect", { + id: "Rectangle", + transform: "translate(9.843, 10.549) rotate(-60) translate(-9.843, -10.549) ", + x: "8.343", + y: "0.049", + width: "3", + height: "21", + rx: "1.5" + }) + ) + ); + }, + + flags: function flags() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M0 0l6.084 24H8L1.916 0zM21 5h-4l-1-4H4l3 12h3l1 4h13L21 5zM6.563 3h7.875l2 8H8.563l-2-8zm8.832 10l-2.856 1.904L12.063 13h3.332zM19 13l-1.5-6h1.938l2 8H16l3-2z" }) + ); + }, + + foods: function foods() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M17 4.978c-1.838 0-2.876.396-3.68.934.513-1.172 1.768-2.934 4.68-2.934a1 1 0 0 0 0-2c-2.921 0-4.629 1.365-5.547 2.512-.064.078-.119.162-.18.244C11.73 1.838 10.798.023 9.207.023 8.579.022 7.85.306 7 .978 5.027 2.54 5.329 3.902 6.492 4.999 3.609 5.222 0 7.352 0 12.969c0 4.582 4.961 11.009 9 11.009 1.975 0 2.371-.486 3-1 .629.514 1.025 1 3 1 4.039 0 9-6.418 9-11 0-5.953-4.055-8-7-8M8.242 2.546c.641-.508.943-.523.965-.523.426.169.975 1.405 1.357 3.055-1.527-.629-2.741-1.352-2.98-1.846.059-.112.241-.356.658-.686M15 21.978c-1.08 0-1.21-.109-1.559-.402l-.176-.146c-.367-.302-.816-.452-1.266-.452s-.898.15-1.266.452l-.176.146c-.347.292-.477.402-1.557.402-2.813 0-7-5.389-7-9.009 0-5.823 4.488-5.991 5-5.991 1.939 0 2.484.471 3.387 1.251l.323.276a1.995 1.995 0 0 0 2.58 0l.323-.276c.902-.78 1.447-1.251 3.387-1.251.512 0 5 .168 5 6 0 3.617-4.187 9-7 9" }) + ); + }, + + nature: function nature() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M15.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 15.5 8M8.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 8.5 8" }), + React.createElement("path", { d: "M18.933 0h-.027c-.97 0-2.138.787-3.018 1.497-1.274-.374-2.612-.51-3.887-.51-1.285 0-2.616.133-3.874.517C7.245.79 6.069 0 5.093 0h-.027C3.352 0 .07 2.67.002 7.026c-.039 2.479.276 4.238 1.04 5.013.254.258.882.677 1.295.882.191 3.177.922 5.238 2.536 6.38.897.637 2.187.949 3.2 1.102C8.04 20.6 8 20.795 8 21c0 1.773 2.35 3 4 3 1.648 0 4-1.227 4-3 0-.201-.038-.393-.072-.586 2.573-.385 5.435-1.877 5.925-7.587.396-.22.887-.568 1.104-.788.763-.774 1.079-2.534 1.04-5.013C23.929 2.67 20.646 0 18.933 0M3.223 9.135c-.237.281-.837 1.155-.884 1.238-.15-.41-.368-1.349-.337-3.291.051-3.281 2.478-4.972 3.091-5.031.256.015.731.27 1.265.646-1.11 1.171-2.275 2.915-2.352 5.125-.133.546-.398.858-.783 1.313M12 22c-.901 0-1.954-.693-2-1 0-.654.475-1.236 1-1.602V20a1 1 0 1 0 2 0v-.602c.524.365 1 .947 1 1.602-.046.307-1.099 1-2 1m3-3.48v.02a4.752 4.752 0 0 0-1.262-1.02c1.092-.516 2.239-1.334 2.239-2.217 0-1.842-1.781-2.195-3.977-2.195-2.196 0-3.978.354-3.978 2.195 0 .883 1.148 1.701 2.238 2.217A4.8 4.8 0 0 0 9 18.539v-.025c-1-.076-2.182-.281-2.973-.842-1.301-.92-1.838-3.045-1.853-6.478l.023-.041c.496-.826 1.49-1.45 1.804-3.102 0-2.047 1.357-3.631 2.362-4.522C9.37 3.178 10.555 3 11.948 3c1.447 0 2.685.192 3.733.57 1 .9 2.316 2.465 2.316 4.48.313 1.651 1.307 2.275 1.803 3.102.035.058.068.117.102.178-.059 5.967-1.949 7.01-4.902 7.19m6.628-8.202c-.037-.065-.074-.13-.113-.195a7.587 7.587 0 0 0-.739-.987c-.385-.455-.648-.768-.782-1.313-.076-2.209-1.241-3.954-2.353-5.124.531-.376 1.004-.63 1.261-.647.636.071 3.044 1.764 3.096 5.031.027 1.81-.347 3.218-.37 3.235" }) + ); + }, + + objects: function objects() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M12 0a9 9 0 0 0-5 16.482V21s2.035 3 5 3 5-3 5-3v-4.518A9 9 0 0 0 12 0zm0 2c3.86 0 7 3.141 7 7s-3.14 7-7 7-7-3.141-7-7 3.14-7 7-7zM9 17.477c.94.332 1.946.523 3 .523s2.06-.19 3-.523v.834c-.91.436-1.925.689-3 .689a6.924 6.924 0 0 1-3-.69v-.833zm.236 3.07A8.854 8.854 0 0 0 12 21c.965 0 1.888-.167 2.758-.451C14.155 21.173 13.153 22 12 22c-1.102 0-2.117-.789-2.764-1.453z" }), + React.createElement("path", { d: "M14.745 12.449h-.004c-.852-.024-1.188-.858-1.577-1.824-.421-1.061-.703-1.561-1.182-1.566h-.009c-.481 0-.783.497-1.235 1.537-.436.982-.801 1.811-1.636 1.791l-.276-.043c-.565-.171-.853-.691-1.284-1.794-.125-.313-.202-.632-.27-.913-.051-.213-.127-.53-.195-.634C7.067 9.004 7.039 9 6.99 9A1 1 0 0 1 7 7h.01c1.662.017 2.015 1.373 2.198 2.134.486-.981 1.304-2.058 2.797-2.075 1.531.018 2.28 1.153 2.731 2.141l.002-.008C14.944 8.424 15.327 7 16.979 7h.032A1 1 0 1 1 17 9h-.011c-.149.076-.256.474-.319.709a6.484 6.484 0 0 1-.311.951c-.429.973-.79 1.789-1.614 1.789" }) + ); + }, + + people: function people() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10" }), + React.createElement("path", { d: "M8 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 8 7M16 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 16 7M15.232 15c-.693 1.195-1.87 2-3.349 2-1.477 0-2.655-.805-3.347-2H15m3-2H6a6 6 0 1 0 12 0" }) + ); + }, + + places: function places() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M6.5 12C5.122 12 4 13.121 4 14.5S5.122 17 6.5 17 9 15.879 9 14.5 7.878 12 6.5 12m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5M17.5 12c-1.378 0-2.5 1.121-2.5 2.5s1.122 2.5 2.5 2.5 2.5-1.121 2.5-2.5-1.122-2.5-2.5-2.5m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5" }), + React.createElement("path", { d: "M22.482 9.494l-1.039-.346L21.4 9h.6c.552 0 1-.439 1-.992 0-.006-.003-.008-.003-.008H23c0-1-.889-2-1.984-2h-.642l-.731-1.717C19.262 3.012 18.091 2 16.764 2H7.236C5.909 2 4.738 3.012 4.357 4.283L3.626 6h-.642C1.889 6 1 7 1 8h.003S1 8.002 1 8.008C1 8.561 1.448 9 2 9h.6l-.043.148-1.039.346a2.001 2.001 0 0 0-1.359 2.097l.751 7.508a1 1 0 0 0 .994.901H3v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h6v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h1.096a.999.999 0 0 0 .994-.901l.751-7.508a2.001 2.001 0 0 0-1.359-2.097M6.273 4.857C6.402 4.43 6.788 4 7.236 4h9.527c.448 0 .834.43.963.857L19.313 9H4.688l1.585-4.143zM7 21H5v-1h2v1zm12 0h-2v-1h2v1zm2.189-3H2.811l-.662-6.607L3 11h18l.852.393L21.189 18z" }) + ); + }, + + recent: function recent() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M13 4h-2l-.001 7H9v2h2v2h2v-2h4v-2h-4z" }), + React.createElement("path", { d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10" }) + ); + }, + + symbols: function symbols() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M0 0h11v2H0zM4 11h3V6h4V4H0v2h4zM15.5 17c1.381 0 2.5-1.116 2.5-2.493s-1.119-2.493-2.5-2.493S13 13.13 13 14.507 14.119 17 15.5 17m0-2.986c.276 0 .5.222.5.493 0 .272-.224.493-.5.493s-.5-.221-.5-.493.224-.493.5-.493M21.5 19.014c-1.381 0-2.5 1.116-2.5 2.493S20.119 24 21.5 24s2.5-1.116 2.5-2.493-1.119-2.493-2.5-2.493m0 2.986a.497.497 0 0 1-.5-.493c0-.271.224-.493.5-.493s.5.222.5.493a.497.497 0 0 1-.5.493M22 13l-9 9 1.513 1.5 8.99-9.009zM17 11c2.209 0 4-1.119 4-2.5V2s.985-.161 1.498.949C23.01 4.055 23 6 23 6s1-1.119 1-3.135C24-.02 21 0 21 0h-2v6.347A5.853 5.853 0 0 0 17 6c-2.209 0-4 1.119-4 2.5s1.791 2.5 4 2.5M10.297 20.482l-1.475-1.585a47.54 47.54 0 0 1-1.442 1.129c-.307-.288-.989-1.016-2.045-2.183.902-.836 1.479-1.466 1.729-1.892s.376-.871.376-1.336c0-.592-.273-1.178-.818-1.759-.546-.581-1.329-.871-2.349-.871-1.008 0-1.79.293-2.344.879-.556.587-.832 1.181-.832 1.784 0 .813.419 1.748 1.256 2.805-.847.614-1.444 1.208-1.794 1.784a3.465 3.465 0 0 0-.523 1.833c0 .857.308 1.56.924 2.107.616.549 1.423.823 2.42.823 1.173 0 2.444-.379 3.813-1.137L8.235 24h2.819l-2.09-2.383 1.333-1.135zm-6.736-6.389a1.02 1.02 0 0 1 .73-.286c.31 0 .559.085.747.254a.849.849 0 0 1 .283.659c0 .518-.419 1.112-1.257 1.784-.536-.651-.805-1.231-.805-1.742a.901.901 0 0 1 .302-.669M3.74 22c-.427 0-.778-.116-1.057-.349-.279-.232-.418-.487-.418-.766 0-.594.509-1.288 1.527-2.083.968 1.134 1.717 1.946 2.248 2.438-.921.507-1.686.76-2.3.76" }) + ); + } +}; + +var search = { + search: function search() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "13", + height: "13", + viewBox: "0 0 20 20", + opacity: "0.5" + }, + React.createElement("path", { d: "M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z" }) + ); + }, + + delete: function _delete() { + return React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "13", + height: "13", + viewBox: "0 0 20 20", + opacity: "0.5" + }, + React.createElement("path", { d: "M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z" }) + ); + } +}; + +export { categories, search }; \ No newline at end of file diff --git a/dist-es/utils/data.js b/dist-es/utils/data.js new file mode 100644 index 000000000..c3cbf69b0 --- /dev/null +++ b/dist-es/utils/data.js @@ -0,0 +1,106 @@ +var mapping = { + name: 'a', + unified: 'b', + non_qualified: 'c', + has_img_apple: 'd', + has_img_google: 'e', + has_img_twitter: 'f', + has_img_emojione: 'g', + has_img_facebook: 'h', + has_img_messenger: 'i', + keywords: 'j', + sheet: 'k', + emoticons: 'l', + text: 'm', + short_names: 'n', + added_in: 'o' +}; + +var buildSearch = function buildSearch(emoji) { + var search = []; + + var addToSearch = function addToSearch(strings, split) { + if (!strings) { + return; + } + + ;(Array.isArray(strings) ? strings : [strings]).forEach(function (string) { + ;(split ? string.split(/[-|_|\s]+/) : [string]).forEach(function (s) { + s = s.toLowerCase(); + + if (search.indexOf(s) == -1) { + search.push(s); + } + }); + }); + }; + + addToSearch(emoji.short_names, true); + addToSearch(emoji.name, true); + addToSearch(emoji.keywords, false); + addToSearch(emoji.emoticons, false); + + return search.join(','); +}; + +var compress = function compress(emoji) { + emoji.short_names = emoji.short_names.filter(function (short_name) { + return short_name !== emoji.short_name; + }); + delete emoji.short_name; + + emoji.sheet = [emoji.sheet_x, emoji.sheet_y]; + delete emoji.sheet_x; + delete emoji.sheet_y; + + emoji.added_in = parseInt(emoji.added_in); + if (emoji.added_in === 6) { + delete emoji.added_in; + } + + for (var key in mapping) { + emoji[mapping[key]] = emoji[key]; + delete emoji[key]; + } + + for (var _key in emoji) { + var value = emoji[_key]; + + if (Array.isArray(value) && !value.length) { + delete emoji[_key]; + } else if (typeof value === 'string' && !value.length) { + delete emoji[_key]; + } else if (value === null) { + delete emoji[_key]; + } + } +}; + +var uncompress = function uncompress(data) { + data.compressed = false; + + for (var id in data.emojis) { + var emoji = data.emojis[id]; + + for (var key in mapping) { + emoji[key] = emoji[mapping[key]]; + delete emoji[mapping[key]]; + } + + if (!emoji.short_names) emoji.short_names = []; + emoji.short_names.unshift(id); + + emoji.sheet_x = emoji.sheet[0]; + emoji.sheet_y = emoji.sheet[1]; + delete emoji.sheet; + + if (!emoji.text) emoji.text = ''; + + if (!emoji.added_in) emoji.added_in = 6; + emoji.added_in = emoji.added_in.toFixed(1); + + emoji.search = buildSearch(emoji); + } +}; + +export { buildSearch, compress, uncompress }; \ No newline at end of file diff --git a/dist-es/utils/emoji-index/emoji-index.js b/dist-es/utils/emoji-index/emoji-index.js new file mode 100644 index 000000000..3e4066585 --- /dev/null +++ b/dist-es/utils/emoji-index/emoji-index.js @@ -0,0 +1,13 @@ +import data from '../../../data/all.json'; +import NimbleEmojiIndex from './nimble-emoji-index'; + +var emojiIndex = new NimbleEmojiIndex(data); +var emojis = emojiIndex.emojis; +var emoticons = emojiIndex.emoticons; + + +function search() { + return emojiIndex.search.apply(emojiIndex, arguments); +} + +export default { search: search, emojis: emojis, emoticons: emoticons }; \ No newline at end of file diff --git a/dist-es/utils/emoji-index/nimble-emoji-index.js b/dist-es/utils/emoji-index/nimble-emoji-index.js new file mode 100644 index 000000000..d0dd50d8e --- /dev/null +++ b/dist-es/utils/emoji-index/nimble-emoji-index.js @@ -0,0 +1,224 @@ +import _classCallCheck from '../../polyfills/classCallCheck'; +import _createClass from '../../polyfills/createClass'; +import { getData, getSanitizedData, intersect } from '..'; +import { uncompress } from '../data'; + +var NimbleEmojiIndex = function () { + function NimbleEmojiIndex(data) { + _classCallCheck(this, NimbleEmojiIndex); + + if (data.compressed) { + uncompress(data); + } + + this.data = data || {}; + this.originalPool = {}; + this.index = {}; + this.emojis = {}; + this.emoticons = {}; + this.customEmojisList = []; + + this.buildIndex(); + } + + _createClass(NimbleEmojiIndex, [{ + key: 'buildIndex', + value: function buildIndex() { + var _this = this; + + var _loop = function _loop(emoji) { + var emojiData = _this.data.emojis[emoji]; + var short_names = emojiData.short_names; + var emoticons = emojiData.emoticons; + var id = short_names[0]; + + if (emoticons) { + emoticons.forEach(function (emoticon) { + if (_this.emoticons[emoticon]) { + return; + } + + _this.emoticons[emoticon] = id; + }); + } + + _this.emojis[id] = getSanitizedData(id, null, null, _this.data); + _this.originalPool[id] = emojiData; + }; + + for (var emoji in this.data.emojis) { + _loop(emoji); + } + } + }, { + key: 'clearCustomEmojis', + value: function clearCustomEmojis(pool) { + var _this2 = this; + + this.customEmojisList.forEach(function (emoji) { + var emojiId = emoji.id || emoji.short_names[0]; + + delete pool[emojiId]; + delete _this2.emojis[emojiId]; + }); + } + }, { + key: 'addCustomToPool', + value: function addCustomToPool(custom, pool) { + var _this3 = this; + + if (this.customEmojisList.length) this.clearCustomEmojis(pool); + + custom.forEach(function (emoji) { + var emojiId = emoji.id || emoji.short_names[0]; + + if (emojiId && !pool[emojiId]) { + pool[emojiId] = getData(emoji, null, null, _this3.data); + _this3.emojis[emojiId] = getSanitizedData(emoji, null, null, _this3.data); + } + }); + + this.customEmojisList = custom; + this.index = {}; + } + }, { + key: 'search', + value: function search(value) { + var _this4 = this; + + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var emojisToShowFilter = _ref.emojisToShowFilter; + var maxResults = _ref.maxResults; + var include = _ref.include; + var exclude = _ref.exclude; + var _ref$custom = _ref.custom; + var custom = _ref$custom === undefined ? [] : _ref$custom; + + if (this.customEmojisList != custom) this.addCustomToPool(custom, this.originalPool); + + maxResults || (maxResults = 75); + include || (include = []); + exclude || (exclude = []); + + var results = null, + pool = this.originalPool; + + if (value.length) { + if (value == '-' || value == '-1') { + return [this.emojis['-1']]; + } + + var values = value.toLowerCase().split(/[\s|,|\-|_]+/), + allResults = []; + + if (values.length > 2) { + values = [values[0], values[1]]; + } + + if (include.length || exclude.length) { + pool = {}; + + this.data.categories.forEach(function (category) { + var isIncluded = include && include.length ? include.indexOf(category.id) > -1 : true; + var isExcluded = exclude && exclude.length ? exclude.indexOf(category.id) > -1 : false; + if (!isIncluded || isExcluded) { + return; + } + + category.emojis.forEach(function (emojiId) { + return pool[emojiId] = _this4.data.emojis[emojiId]; + }); + }); + + if (custom.length) { + var customIsIncluded = include && include.length ? include.indexOf('custom') > -1 : true; + var customIsExcluded = exclude && exclude.length ? exclude.indexOf('custom') > -1 : false; + if (customIsIncluded && !customIsExcluded) { + this.addCustomToPool(custom, pool); + } + } + } + + allResults = values.map(function (value) { + var aPool = pool, + aIndex = _this4.index, + length = 0; + + for (var charIndex = 0; charIndex < value.length; charIndex++) { + var char = value[charIndex]; + length++; + + aIndex[char] || (aIndex[char] = {}); + aIndex = aIndex[char]; + + if (!aIndex.results) { + (function () { + var scores = {}; + + aIndex.results = []; + aIndex.pool = {}; + + for (var _id in aPool) { + var emoji = aPool[_id]; + var search = emoji.search; + var sub = value.substr(0, length); + var subIndex = search.indexOf(sub); + + if (subIndex != -1) { + var score = subIndex + 1; + if (sub == _id) score = 0; + + aIndex.results.push(_this4.emojis[_id]); + aIndex.pool[_id] = emoji; + + scores[_id] = score; + } + } + + aIndex.results.sort(function (a, b) { + var aScore = scores[a.id], + bScore = scores[b.id]; + + return aScore - bScore; + }); + })(); + } + + aPool = aIndex.pool; + } + + return aIndex.results; + }).filter(function (a) { + return a; + }); + + if (allResults.length > 1) { + results = intersect.apply(null, allResults); + } else if (allResults.length) { + results = allResults[0]; + } else { + results = []; + } + } + + if (results) { + if (emojisToShowFilter) { + results = results.filter(function (result) { + return emojisToShowFilter(pool[result.id]); + }); + } + + if (results && results.length > maxResults) { + results = results.slice(0, maxResults); + } + } + + return results; + } + }]); + + return NimbleEmojiIndex; +}(); + +export default NimbleEmojiIndex; \ No newline at end of file diff --git a/dist-es/utils/frequently.js b/dist-es/utils/frequently.js new file mode 100644 index 000000000..35d9aafb2 --- /dev/null +++ b/dist-es/utils/frequently.js @@ -0,0 +1,66 @@ +import store from './store'; + +var DEFAULTS = ['+1', 'grinning', 'kissing_heart', 'heart_eyes', 'laughing', 'stuck_out_tongue_winking_eye', 'sweat_smile', 'joy', 'scream', 'disappointed', 'unamused', 'weary', 'sob', 'sunglasses', 'heart', 'poop']; + +var frequently = void 0, + initialized = void 0; +var defaults = {}; + +function init() { + initialized = true; + frequently = store.get('frequently'); +} + +function add(emoji) { + if (!initialized) init(); + var id = emoji.id; + + + frequently || (frequently = defaults); + frequently[id] || (frequently[id] = 0); + frequently[id] += 1; + + store.set('last', id); + store.set('frequently', frequently); +} + +function get(perLine) { + if (!initialized) init(); + if (!frequently) { + defaults = {}; + + var result = []; + + for (var i = 0; i < perLine; i++) { + defaults[DEFAULTS[i]] = perLine - i; + result.push(DEFAULTS[i]); + } + + return result; + } + + var quantity = perLine * 4; + var frequentlyKeys = []; + + for (var key in frequently) { + if (frequently.hasOwnProperty(key)) { + frequentlyKeys.push(key); + } + } + + var sorted = frequentlyKeys.sort(function (a, b) { + return frequently[a] - frequently[b]; + }).reverse(); + var sliced = sorted.slice(0, quantity); + + var last = store.get('last'); + + if (last && sliced.indexOf(last) == -1) { + sliced.pop(); + sliced.push(last); + } + + return sliced; +} + +export default { add: add, get: get }; \ No newline at end of file diff --git a/dist-es/utils/index.js b/dist-es/utils/index.js new file mode 100644 index 000000000..6af62d169 --- /dev/null +++ b/dist-es/utils/index.js @@ -0,0 +1,208 @@ +import _Object$keys from '../polyfills/keys'; +import { buildSearch } from './data'; +import stringFromCodePoint from '../polyfills/stringFromCodePoint'; + +var _JSON = JSON; + +var COLONS_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/; +var SKINS = ['1F3FA', '1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF']; + +function unifiedToNative(unified) { + var unicodes = unified.split('-'), + codePoints = unicodes.map(function (u) { + return '0x' + u; + }); + + return stringFromCodePoint.apply(null, codePoints); +} + +function sanitize(emoji) { + var name = emoji.name; + var short_names = emoji.short_names; + var skin_tone = emoji.skin_tone; + var skin_variations = emoji.skin_variations; + var emoticons = emoji.emoticons; + var unified = emoji.unified; + var custom = emoji.custom; + var imageUrl = emoji.imageUrl; + var id = emoji.id || short_names[0]; + var colons = ':' + id + ':'; + + if (custom) { + return { + id: id, + name: name, + colons: colons, + emoticons: emoticons, + custom: custom, + imageUrl: imageUrl + }; + } + + if (skin_tone) { + colons += ':skin-tone-' + skin_tone + ':'; + } + + return { + id: id, + name: name, + colons: colons, + emoticons: emoticons, + unified: unified.toLowerCase(), + skin: skin_tone || (skin_variations ? 1 : null), + native: unifiedToNative(unified) + }; +} + +function getSanitizedData() { + return sanitize(getData.apply(undefined, arguments)); +} + +function getData(emoji, skin, set, data) { + var emojiData = {}; + + if (typeof emoji == 'string') { + var matches = emoji.match(COLONS_REGEX); + + if (matches) { + emoji = matches[1]; + + if (matches[2]) { + skin = parseInt(matches[2], 10); + } + } + + if (data.aliases.hasOwnProperty(emoji)) { + emoji = data.aliases[emoji]; + } + + if (data.emojis.hasOwnProperty(emoji)) { + emojiData = data.emojis[emoji]; + } else { + return null; + } + } else if (emoji.id) { + if (data.aliases.hasOwnProperty(emoji.id)) { + emoji.id = data.aliases[emoji.id]; + } + + if (data.emojis.hasOwnProperty(emoji.id)) { + emojiData = data.emojis[emoji.id]; + skin || (skin = emoji.skin); + } + } + + if (!_Object$keys(emojiData).length) { + emojiData = emoji; + emojiData.custom = true; + + if (!emojiData.search) { + emojiData.search = buildSearch(emoji); + } + } + + emojiData.emoticons || (emojiData.emoticons = []); + emojiData.variations || (emojiData.variations = []); + + if (emojiData.skin_variations && skin > 1 && set) { + emojiData = JSON.parse(_JSON.stringify(emojiData)); + + var skinKey = SKINS[skin - 1], + variationData = emojiData.skin_variations[skinKey]; + + if (!variationData.variations && emojiData.variations) { + delete emojiData.variations; + } + + if (variationData['has_img_' + set] == undefined || variationData['has_img_' + set]) { + emojiData.skin_tone = skin; + + for (var k in variationData) { + var v = variationData[k]; + emojiData[k] = v; + } + } + } + + if (emojiData.variations && emojiData.variations.length) { + emojiData = JSON.parse(_JSON.stringify(emojiData)); + emojiData.unified = emojiData.variations.shift(); + } + + return emojiData; +} + +function uniq(arr) { + return arr.reduce(function (acc, item) { + if (acc.indexOf(item) === -1) { + acc.push(item); + } + return acc; + }, []); +} + +function intersect(a, b) { + var uniqA = uniq(a); + var uniqB = uniq(b); + + return uniqA.filter(function (item) { + return uniqB.indexOf(item) >= 0; + }); +} + +function deepMerge(a, b) { + var o = {}; + + for (var key in a) { + var originalValue = a[key], + value = originalValue; + + if (b.hasOwnProperty(key)) { + value = b[key]; + } + + if (typeof value === 'object') { + value = deepMerge(originalValue, value); + } + + o[key] = value; + } + + return o; +} + +// https://github.com/sonicdoe/measure-scrollbar +function measureScrollbar() { + if (typeof document == 'undefined') return 0; + var div = document.createElement('div'); + + div.style.width = '100px'; + div.style.height = '100px'; + div.style.overflow = 'scroll'; + div.style.position = 'absolute'; + div.style.top = '-9999px'; + + document.body.appendChild(div); + var scrollbarWidth = div.offsetWidth - div.clientWidth; + document.body.removeChild(div); + + return scrollbarWidth; +} + +// Use requestIdleCallback() if available, else fall back to setTimeout(). +// Throttle so as not to run too frequently. +function throttleIdleTask(func) { + var queue = typeof requestIdleCallback === 'function' ? requestIdleCallback : setTimeout; + var clear = typeof cancelIdleCallback === 'function' ? cancelIdleCallback : clearTimeout; + + var id = void 0; + + return function throttled() { + if (id) { + clear(id); + } + id = queue(func); + }; +} + +export { getData, getSanitizedData, uniq, intersect, deepMerge, unifiedToNative, measureScrollbar, throttleIdleTask }; \ No newline at end of file diff --git a/dist-es/utils/shared-default-props.js b/dist-es/utils/shared-default-props.js new file mode 100644 index 000000000..d825680ac --- /dev/null +++ b/dist-es/utils/shared-default-props.js @@ -0,0 +1,47 @@ +var EmojiDefaultProps = { + skin: 1, + set: 'apple', + sheetSize: 64, + sheetColumns: 52, + sheetRows: 52, + native: false, + forceSize: false, + tooltip: false, + backgroundImageFn: function backgroundImageFn(set, sheetSize) { + return 'https://unpkg.com/emoji-datasource-' + set + '@' + '4.0.4' + '/img/' + set + '/sheets-256/' + sheetSize + '.png'; + }, + onOver: function onOver() {}, + onLeave: function onLeave() {}, + onClick: function onClick() {} +}; + +var PickerDefaultProps = { + onClick: function onClick() {}, + onSelect: function onSelect() {}, + onSkinChange: function onSkinChange() {}, + emojiSize: 24, + perLine: 9, + i18n: {}, + style: {}, + title: 'Emoji Mart™', + emoji: 'department_store', + color: '#ae65c5', + set: EmojiDefaultProps.set, + skin: null, + defaultSkin: EmojiDefaultProps.skin, + native: EmojiDefaultProps.native, + sheetSize: EmojiDefaultProps.sheetSize, + backgroundImageFn: EmojiDefaultProps.backgroundImageFn, + emojisToShowFilter: null, + showPreview: true, + showSkinTones: true, + emojiTooltip: EmojiDefaultProps.tooltip, + autoFocus: false, + custom: [], + skinEmoji: '', + notFound: function notFound() {}, + notFoundEmoji: 'sleuth_or_spy', + icons: {} +}; + +export { PickerDefaultProps, EmojiDefaultProps }; \ No newline at end of file diff --git a/dist-es/utils/shared-props.js b/dist-es/utils/shared-props.js new file mode 100644 index 000000000..f6baf4990 --- /dev/null +++ b/dist-es/utils/shared-props.js @@ -0,0 +1,59 @@ +import PropTypes from 'prop-types'; + +var EmojiPropTypes = { + data: PropTypes.object.isRequired, + onOver: PropTypes.func, + onLeave: PropTypes.func, + onClick: PropTypes.func, + fallback: PropTypes.func, + backgroundImageFn: PropTypes.func, + native: PropTypes.bool, + forceSize: PropTypes.bool, + tooltip: PropTypes.bool, + skin: PropTypes.oneOf([1, 2, 3, 4, 5, 6]), + sheetSize: PropTypes.oneOf([16, 20, 32, 64]), + sheetColumns: PropTypes.number, + sheetRows: PropTypes.number, + set: PropTypes.oneOf(['apple', 'google', 'twitter', 'emojione', 'messenger', 'facebook']), + size: PropTypes.number.isRequired, + emoji: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired +}; + +var PickerPropTypes = { + onClick: PropTypes.func, + onSelect: PropTypes.func, + onSkinChange: PropTypes.func, + perLine: PropTypes.number, + emojiSize: PropTypes.number, + i18n: PropTypes.object, + style: PropTypes.object, + title: PropTypes.string, + emoji: PropTypes.string, + color: PropTypes.string, + set: EmojiPropTypes.set, + skin: EmojiPropTypes.skin, + native: PropTypes.bool, + backgroundImageFn: EmojiPropTypes.backgroundImageFn, + sheetSize: EmojiPropTypes.sheetSize, + emojisToShowFilter: PropTypes.func, + showPreview: PropTypes.bool, + showSkinTones: PropTypes.bool, + emojiTooltip: EmojiPropTypes.tooltip, + include: PropTypes.arrayOf(PropTypes.string), + exclude: PropTypes.arrayOf(PropTypes.string), + recent: PropTypes.arrayOf(PropTypes.string), + autoFocus: PropTypes.bool, + custom: PropTypes.arrayOf(PropTypes.shape({ + name: PropTypes.string.isRequired, + short_names: PropTypes.arrayOf(PropTypes.string).isRequired, + emoticons: PropTypes.arrayOf(PropTypes.string), + keywords: PropTypes.arrayOf(PropTypes.string), + imageUrl: PropTypes.string.isRequired + })), + skinEmoji: PropTypes.string, + notFound: PropTypes.func, + notFoundEmoji: PropTypes.string, + icons: PropTypes.object +}; + +export { EmojiPropTypes, PickerPropTypes }; \ No newline at end of file diff --git a/dist-es/utils/store.js b/dist-es/utils/store.js new file mode 100644 index 000000000..953e9a8dc --- /dev/null +++ b/dist-es/utils/store.js @@ -0,0 +1,56 @@ +var NAMESPACE = 'emoji-mart'; + +var _JSON = JSON; + +var isLocalStorageSupported = typeof window !== 'undefined' && 'localStorage' in window; + +var getter = void 0; +var setter = void 0; + +function setHandlers(handlers) { + handlers || (handlers = {}); + + getter = handlers.getter; + setter = handlers.setter; +} + +function setNamespace(namespace) { + NAMESPACE = namespace; +} + +function update(state) { + for (var key in state) { + var value = state[key]; + set(key, value); + } +} + +function set(key, value) { + if (setter) { + setter(key, value); + } else { + if (!isLocalStorageSupported) return; + try { + window.localStorage[NAMESPACE + '.' + key] = _JSON.stringify(value); + } catch (e) {} + } +} + +function get(key) { + if (getter) { + return getter(key); + } else { + if (!isLocalStorageSupported) return; + try { + var value = window.localStorage[NAMESPACE + '.' + key]; + } catch (e) { + return; + } + + if (value) { + return JSON.parse(value); + } + } +} + +export default { update: update, set: set, get: get, setNamespace: setNamespace, setHandlers: setHandlers }; \ No newline at end of file diff --git a/dist-es/vendor/raf-polyfill.js b/dist-es/vendor/raf-polyfill.js new file mode 100644 index 000000000..e160df618 --- /dev/null +++ b/dist-es/vendor/raf-polyfill.js @@ -0,0 +1,33 @@ +// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + +// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel + +// MIT license + +var isWindowAvailable = typeof window !== 'undefined'; + +isWindowAvailable && function () { + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function () { + callback(currTime + timeToCall); + }, timeToCall); + + lastTime = currTime + timeToCall; + return id; + }; + + if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; +}(); \ No newline at end of file diff --git a/dist-modern/components/anchors.js b/dist-modern/components/anchors.js new file mode 100644 index 000000000..175e8723d --- /dev/null +++ b/dist-modern/components/anchors.js @@ -0,0 +1,75 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +export default class Anchors extends React.PureComponent { + constructor(props) { + super(props); + + let defaultCategory = props.categories.filter(category => category.first)[0]; + + this.state = { + selected: defaultCategory.name + }; + + this.handleClick = this.handleClick.bind(this); + } + + handleClick(e) { + var index = e.currentTarget.getAttribute('data-index'); + var { categories, onAnchorClick } = this.props; + + onAnchorClick(categories[index], index); + } + + render() { + var { categories, color, i18n, icons } = this.props, + { selected } = this.state; + + return React.createElement( + 'nav', + { className: 'emoji-mart-anchors', 'aria-label': i18n.categorieslabel }, + categories.map((category, i) => { + var { id, name, anchor } = category, + isSelected = name == selected; + + if (anchor === false) { + return null; + } + + return React.createElement( + 'button', + { + key: id, + 'aria-label': i18n.categories[id], + title: i18n.categories[id], + 'data-index': i, + onClick: this.handleClick, + className: `emoji-mart-anchor ${isSelected ? 'emoji-mart-anchor-selected' : ''}`, + style: { color: isSelected ? color : null } + }, + React.createElement( + 'div', + { className: 'emoji-mart-anchor-icon' }, + icons.categories[id]() + ), + React.createElement('span', { + className: 'emoji-mart-anchor-bar', + style: { backgroundColor: color } + }) + ); + }) + ); + } +} + +Anchors.propTypes /* remove-proptypes */ = { + categories: PropTypes.array, + onAnchorClick: PropTypes.func, + icons: PropTypes.object +}; + +Anchors.defaultProps = { + categories: [], + onAnchorClick: () => {}, + icons: {} +}; \ No newline at end of file diff --git a/dist-modern/components/category.js b/dist-modern/components/category.js new file mode 100644 index 000000000..c81b01c93 --- /dev/null +++ b/dist-modern/components/category.js @@ -0,0 +1,222 @@ +import _extends from '../polyfills/extends'; +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'; + +export default class Category extends React.Component { + constructor(props) { + super(props); + + this.data = props.data; + this.setContainerRef = this.setContainerRef.bind(this); + this.setLabelRef = this.setLabelRef.bind(this); + } + + componentDidMount() { + this.margin = 0; + this.minMargin = 0; + + this.memoizeSize(); + } + + shouldComponentUpdate(nextProps, nextState) { + var { + name, + perLine, + native, + hasStickyPosition, + emojis, + emojiProps + } = this.props, + { skin, size, set } = emojiProps, + { + perLine: nextPerLine, + native: nextNative, + hasStickyPosition: nextHasStickyPosition, + emojis: nextEmojis, + emojiProps: nextEmojiProps + } = nextProps, + { skin: nextSkin, size: nextSize, set: nextSet } = nextEmojiProps, + 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; + } + + memoizeSize() { + var parent = this.container.parentElement; + var { top, height } = this.container.getBoundingClientRect(); + var { top: parentTop } = parent.getBoundingClientRect(); + var { height: labelHeight } = this.label.getBoundingClientRect(); + + this.top = top - parentTop + parent.scrollTop; + + if (height == 0) { + this.maxMargin = 0; + } else { + this.maxMargin = height - labelHeight; + } + } + + 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 = `${margin}px`; + } + + this.margin = margin; + return true; + } + + getEmojis() { + var { name, emojis, recent, perLine } = this.props; + + if (name == 'Recent') { + let { custom } = this.props; + let frequentlyUsed = recent || frequently.get(perLine); + + if (frequentlyUsed.length) { + emojis = frequentlyUsed.map(id => { + const emoji = custom.filter(e => e.id === id)[0]; + if (emoji) { + return emoji; + } + + return id; + }).filter(id => !!getData(id, null, null, this.data)); + } + + if (emojis.length === 0 && frequentlyUsed.length > 0) { + return null; + } + } + + if (emojis) { + emojis = emojis.slice(0); + } + + return emojis; + } + + updateDisplay(display) { + var emojis = this.getEmojis(); + + if (!emojis) { + return; + } + + this.container.style.display = display; + } + + setContainerRef(c) { + this.container = c; + } + + setLabelRef(c) { + this.label = c; + } + + render() { + var { + id, + name, + hasStickyPosition, + emojiProps, + i18n, + notFound, + notFoundEmoji + } = this.props, + emojis = this.getEmojis(), + labelStyles = {}, + labelSpanStyles = {}, + containerStyles = {}; + + if (!emojis) { + containerStyles = { + display: 'none' + }; + } + + if (!hasStickyPosition) { + labelStyles = { + height: 28 + }; + + labelSpanStyles = { + position: 'absolute' + }; + } + + return React.createElement( + 'section', + { + ref: this.setContainerRef, + className: 'emoji-mart-category', + 'aria-label': i18n.categories[id], + 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 */ + }, + i18n.categories[id] + ) + ), + emojis && emojis.map(emoji => NimbleEmoji(_extends({ emoji: emoji, data: this.data }, emojiProps))), + emojis && !emojis.length && React.createElement(NotFound, { + i18n: i18n, + notFound: notFound, + notFoundEmoji: notFoundEmoji, + data: this.data, + emojiProps: emojiProps + }) + ); + } +} + +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 +}; \ No newline at end of file diff --git a/dist-modern/components/emoji/emoji.js b/dist-modern/components/emoji/emoji.js new file mode 100644 index 000000000..25b679f42 --- /dev/null +++ b/dist-modern/components/emoji/emoji.js @@ -0,0 +1,23 @@ +import _extends from '../../polyfills/extends'; +import React from 'react'; + +import data from '../../../data/all.json'; +import NimbleEmoji from './nimble-emoji'; + +import { EmojiPropTypes } from '../../utils/shared-props'; +import { EmojiDefaultProps } from '../../utils/shared-default-props'; + +const Emoji = props => { + for (let k in Emoji.defaultProps) { + if (props[k] == undefined && Emoji.defaultProps[k] != undefined) { + props[k] = Emoji.defaultProps[k]; + } + } + + return NimbleEmoji(_extends({}, props)); +}; + +Emoji.propTypes /* remove-proptypes */ = EmojiPropTypes; +Emoji.defaultProps = _extends({}, EmojiDefaultProps, { data }); + +export default Emoji; \ No newline at end of file diff --git a/dist-modern/components/emoji/nimble-emoji.js b/dist-modern/components/emoji/nimble-emoji.js new file mode 100644 index 000000000..ce529b964 --- /dev/null +++ b/dist-modern/components/emoji/nimble-emoji.js @@ -0,0 +1,195 @@ +import _extends from '../../polyfills/extends'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import { getData, getSanitizedData, unifiedToNative } from '../../utils'; +import { uncompress } from '../../utils/data'; +import { EmojiPropTypes } from '../../utils/shared-props'; +import { EmojiDefaultProps } from '../../utils/shared-default-props'; + +const _getData = props => { + var { emoji, skin, set, data } = props; + return getData(emoji, skin, set, data); +}; + +const _getPosition = props => { + var { sheet_x, sheet_y } = _getData(props), + multiplyX = 100 / (props.sheetColumns - 1), + multiplyY = 100 / (props.sheetRows - 1); + + return `${multiplyX * sheet_x}% ${multiplyY * sheet_y}%`; +}; + +const _getSanitizedData = props => { + var { emoji, skin, set, data } = props; + return getSanitizedData(emoji, skin, set, data); +}; + +const _handleClick = (e, props) => { + if (!props.onClick) { + return; + } + var { onClick } = props, + emoji = _getSanitizedData(props); + + onClick(emoji, e); +}; + +const _handleOver = (e, props) => { + if (!props.onOver) { + return; + } + var { onOver } = props, + emoji = _getSanitizedData(props); + + onOver(emoji, e); +}; + +const _handleLeave = (e, props) => { + if (!props.onLeave) { + return; + } + var { onLeave } = props, + emoji = _getSanitizedData(props); + + onLeave(emoji, e); +}; + +const _isNumeric = value => { + return !isNaN(value - parseFloat(value)); +}; + +const _convertStyleToCSS = style => { + let div = document.createElement('div'); + + for (let key in style) { + let value = style[key]; + + if (_isNumeric(value)) { + value += 'px'; + } + + div.style[key] = value; + } + + return div.getAttribute('style'); +}; + +const NimbleEmoji = props => { + if (props.data.compressed) { + uncompress(props.data); + } + + for (let k in NimbleEmoji.defaultProps) { + if (props[k] == undefined && NimbleEmoji.defaultProps[k] != undefined) { + props[k] = NimbleEmoji.defaultProps[k]; + } + } + + let data = _getData(props); + if (!data) { + if (props.fallback) { + return props.fallback(null, props); + } else { + return null; + } + } + + let { unified, custom, short_names, imageUrl } = data, + style = {}, + children = props.children, + className = 'emoji-mart-emoji', + title = null; + + if (!unified && !custom) { + if (props.fallback) { + return props.fallback(data, props); + } else { + return null; + } + } + + if (props.tooltip) { + title = short_names[0]; + } + + if (props.native && unified) { + className += ' emoji-mart-emoji-native'; + style = { fontSize: props.size }; + children = unifiedToNative(unified); + + if (props.forceSize) { + style.display = 'inline-block'; + style.width = props.size; + style.height = props.size; + style.wordBreak = 'keep-all'; + } + } else if (custom) { + className += ' emoji-mart-emoji-custom'; + style = { + width: props.size, + height: props.size, + display: 'inline-block' + }; + if (data.spriteUrl) { + style = _extends({}, style, { + backgroundImage: `url(${data.spriteUrl})`, + backgroundSize: `${100 * props.sheetColumns}% ${100 * props.sheetRows}%`, + backgroundPosition: _getPosition(props) + }); + } else { + style = _extends({}, style, { + backgroundImage: `url(${imageUrl})`, + backgroundSize: 'contain' + }); + } + } else { + let setHasEmoji = data[`has_img_${props.set}`] == undefined || data[`has_img_${props.set}`]; + + if (!setHasEmoji) { + if (props.fallback) { + return props.fallback(data, props); + } else { + return null; + } + } else { + style = { + width: props.size, + height: props.size, + display: 'inline-block', + backgroundImage: `url(${props.backgroundImageFn(props.set, props.sheetSize)})`, + backgroundSize: `${100 * props.sheetColumns}% ${100 * props.sheetRows}%`, + backgroundPosition: _getPosition(props) + }; + } + } + + if (props.html) { + style = _convertStyleToCSS(style); + return ``; + } else { + return React.createElement( + 'button', + { + key: props.emoji.id || props.emoji, + onClick: e => _handleClick(e, props), + onMouseEnter: e => _handleOver(e, props), + onMouseLeave: e => _handleLeave(e, props), + title: title, + className: className + }, + React.createElement( + 'span', + { style: style }, + children + ) + ); + } +}; + +NimbleEmoji.propTypes /* remove-proptypes */ = _extends({}, EmojiPropTypes, { + data: PropTypes.object.isRequired +}); +NimbleEmoji.defaultProps = EmojiDefaultProps; + +export default NimbleEmoji; \ No newline at end of file diff --git a/dist-modern/components/not-found.js b/dist-modern/components/not-found.js new file mode 100644 index 000000000..5cc2e9084 --- /dev/null +++ b/dist-modern/components/not-found.js @@ -0,0 +1,37 @@ +import _extends from '../polyfills/extends'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import NimbleEmoji from './emoji/nimble-emoji'; + +export default class NotFound extends React.PureComponent { + render() { + const { data, emojiProps, i18n, notFound, notFoundEmoji } = this.props; + + const component = notFound && notFound() || React.createElement( + 'div', + { className: 'emoji-mart-no-results' }, + NimbleEmoji(_extends({ + data: data + }, emojiProps, { + size: 38, + emoji: notFoundEmoji, + onOver: null, + onLeave: null, + onClick: null + })), + React.createElement( + 'div', + { className: 'emoji-mart-no-results-label' }, + i18n.notfound + ) + ); + + return component; + } +} + +NotFound.propTypes /* remove-proptypes */ = { + notFound: PropTypes.func.isRequired, + emojiProps: PropTypes.object.isRequired +}; \ No newline at end of file diff --git a/dist-modern/components/picker/nimble-picker.js b/dist-modern/components/picker/nimble-picker.js new file mode 100644 index 000000000..24db1f8e2 --- /dev/null +++ b/dist-modern/components/picker/nimble-picker.js @@ -0,0 +1,578 @@ +import _extends from '../../polyfills/extends'; +import '../../vendor/raf-polyfill'; + +import React from 'react'; +import PropTypes from 'prop-types'; + +import * as icons from '../../svgs'; +import store from '../../utils/store'; +import frequently from '../../utils/frequently'; +import { deepMerge, measureScrollbar, getSanitizedData } from '../../utils'; +import { uncompress } from '../../utils/data'; +import { PickerPropTypes } from '../../utils/shared-props'; + +import Anchors from '../anchors'; +import Category from '../category'; +import Preview from '../preview'; +import Search from '../search'; +import { PickerDefaultProps } from '../../utils/shared-default-props'; + +const I18N = { + search: 'Search', + clear: 'Clear', // Accessible label on "clear" button + emojilist: 'List of emoji', + notfound: 'No Emoji Found', + skintext: 'Choose your default skin tone', + categories: { + search: 'Search Results', + recent: 'Frequently Used', + people: 'Smileys & People', + nature: 'Animals & Nature', + foods: 'Food & Drink', + activity: 'Activity', + places: 'Travel & Places', + objects: 'Objects', + symbols: 'Symbols', + flags: 'Flags', + custom: 'Custom' + }, + categorieslabel: 'Emoji categories', // Accessible title for the list of categories + skintones: { + 1: 'Default Skin Tone', + 2: 'Light Skin Tone', + 3: 'Medium-Light Skin Tone', + 4: 'Medium Skin Tone', + 5: 'Medium-Dark Skin Tone', + 6: 'Dark Skin Tone' + } +}; + +export default class NimblePicker extends React.PureComponent { + constructor(props) { + super(props); + + this.RECENT_CATEGORY = { id: 'recent', name: 'Recent', emojis: null }; + this.CUSTOM_CATEGORY = { id: 'custom', name: 'Custom', emojis: [] }; + this.SEARCH_CATEGORY = { + id: 'search', + name: 'Search', + emojis: null, + anchor: false + }; + + if (props.data.compressed) { + uncompress(props.data); + } + + this.data = props.data; + this.i18n = deepMerge(I18N, props.i18n); + this.icons = deepMerge(icons, props.icons); + this.state = { + skin: props.skin || store.get('skin') || props.defaultSkin, + firstRender: true + }; + + this.categories = []; + let allCategories = [].concat(this.data.categories); + + if (props.custom.length > 0) { + this.CUSTOM_CATEGORY.emojis = props.custom.map(emoji => { + return _extends({}, emoji, { + // `` expects emoji to have an `id`. + id: emoji.short_names[0], + custom: true + }); + }); + + allCategories.push(this.CUSTOM_CATEGORY); + } + + this.hideRecent = true; + + if (props.include != undefined) { + allCategories.sort((a, b) => { + if (props.include.indexOf(a.id) > props.include.indexOf(b.id)) { + return 1; + } + + return -1; + }); + } + + for (let categoryIndex = 0; categoryIndex < allCategories.length; categoryIndex++) { + const category = allCategories[categoryIndex]; + let isIncluded = props.include && props.include.length ? props.include.indexOf(category.id) > -1 : true; + let isExcluded = props.exclude && props.exclude.length ? props.exclude.indexOf(category.id) > -1 : false; + if (!isIncluded || isExcluded) { + continue; + } + + if (props.emojisToShowFilter) { + let newEmojis = []; + + const { emojis } = category; + for (let emojiIndex = 0; emojiIndex < emojis.length; emojiIndex++) { + const emoji = emojis[emojiIndex]; + if (props.emojisToShowFilter(this.data.emojis[emoji] || emoji)) { + newEmojis.push(emoji); + } + } + + if (newEmojis.length) { + let newCategory = { + emojis: newEmojis, + name: category.name, + id: category.id + }; + + this.categories.push(newCategory); + } + } else { + this.categories.push(category); + } + } + + let includeRecent = props.include && props.include.length ? props.include.indexOf(this.RECENT_CATEGORY.id) > -1 : true; + let excludeRecent = props.exclude && props.exclude.length ? props.exclude.indexOf(this.RECENT_CATEGORY.id) > -1 : false; + if (includeRecent && !excludeRecent) { + this.hideRecent = false; + this.categories.unshift(this.RECENT_CATEGORY); + } + + if (this.categories[0]) { + this.categories[0].first = true; + } + + this.categories.unshift(this.SEARCH_CATEGORY); + + this.setAnchorsRef = this.setAnchorsRef.bind(this); + this.handleAnchorClick = this.handleAnchorClick.bind(this); + this.setSearchRef = this.setSearchRef.bind(this); + this.handleSearch = this.handleSearch.bind(this); + this.setScrollRef = this.setScrollRef.bind(this); + this.handleScroll = this.handleScroll.bind(this); + this.handleScrollPaint = this.handleScrollPaint.bind(this); + this.handleEmojiOver = this.handleEmojiOver.bind(this); + this.handleEmojiLeave = this.handleEmojiLeave.bind(this); + this.handleEmojiClick = this.handleEmojiClick.bind(this); + this.handleEmojiSelect = this.handleEmojiSelect.bind(this); + this.setPreviewRef = this.setPreviewRef.bind(this); + this.handleSkinChange = this.handleSkinChange.bind(this); + this.handleKeyDown = this.handleKeyDown.bind(this); + } + + componentWillReceiveProps(props) { + if (props.skin) { + this.setState({ skin: props.skin }); + } else if (props.defaultSkin && !store.get('skin')) { + this.setState({ skin: props.defaultSkin }); + } + } + + componentDidMount() { + if (this.state.firstRender) { + this.testStickyPosition(); + this.firstRenderTimeout = setTimeout(() => { + this.setState({ firstRender: false }); + }, 60); + } + } + + componentDidUpdate() { + this.updateCategoriesSize(); + this.handleScroll(); + } + + componentWillUnmount() { + this.SEARCH_CATEGORY.emojis = null; + + clearTimeout(this.leaveTimeout); + clearTimeout(this.firstRenderTimeout); + } + + testStickyPosition() { + const stickyTestElement = document.createElement('div'); + + const prefixes = ['', '-webkit-', '-ms-', '-moz-', '-o-']; + + prefixes.forEach(prefix => stickyTestElement.style.position = `${prefix}sticky`); + + this.hasStickyPosition = !!stickyTestElement.style.position.length; + } + + handleEmojiOver(emoji) { + var { preview } = this; + if (!preview) { + return; + } + + // Use Array.prototype.find() when it is more widely supported. + const emojiData = this.CUSTOM_CATEGORY.emojis.filter(customEmoji => customEmoji.id === emoji.id)[0]; + for (let key in emojiData) { + if (emojiData.hasOwnProperty(key)) { + emoji[key] = emojiData[key]; + } + } + + preview.setState({ emoji }); + clearTimeout(this.leaveTimeout); + } + + handleEmojiLeave(emoji) { + var { preview } = this; + if (!preview) { + return; + } + + this.leaveTimeout = setTimeout(() => { + preview.setState({ emoji: null }); + }, 16); + } + + handleEmojiClick(emoji, e) { + this.props.onClick(emoji, e); + this.handleEmojiSelect(emoji); + } + + handleEmojiSelect(emoji) { + this.props.onSelect(emoji); + if (!this.hideRecent && !this.props.recent) frequently.add(emoji); + + var component = this.categoryRefs['category-1']; + if (component) { + let maxMargin = component.maxMargin; + component.forceUpdate(); + + window.requestAnimationFrame(() => { + if (!this.scroll) return; + component.memoizeSize(); + if (maxMargin == component.maxMargin) return; + + this.updateCategoriesSize(); + this.handleScrollPaint(); + + if (this.SEARCH_CATEGORY.emojis) { + component.updateDisplay('none'); + } + }); + } + } + + handleScroll() { + if (!this.waitingForPaint) { + this.waitingForPaint = true; + window.requestAnimationFrame(this.handleScrollPaint); + } + } + + handleScrollPaint() { + this.waitingForPaint = false; + + if (!this.scroll) { + return; + } + + let activeCategory = null; + + if (this.SEARCH_CATEGORY.emojis) { + activeCategory = this.SEARCH_CATEGORY; + } else { + var target = this.scroll, + scrollTop = target.scrollTop, + scrollingDown = scrollTop > (this.scrollTop || 0), + minTop = 0; + + for (let i = 0, l = this.categories.length; i < l; i++) { + let ii = scrollingDown ? this.categories.length - 1 - i : i, + category = this.categories[ii], + component = this.categoryRefs[`category-${ii}`]; + + if (component) { + let active = component.handleScroll(scrollTop); + + if (!minTop || component.top < minTop) { + if (component.top > 0) { + minTop = component.top; + } + } + + if (active && !activeCategory) { + activeCategory = category; + } + } + } + + if (scrollTop < minTop) { + activeCategory = this.categories.filter(category => !(category.anchor === false))[0]; + } else if (scrollTop + this.clientHeight >= this.scrollHeight) { + activeCategory = this.categories[this.categories.length - 1]; + } + } + + if (activeCategory) { + let { anchors } = this, + { name: categoryName } = activeCategory; + + if (anchors.state.selected != categoryName) { + anchors.setState({ selected: categoryName }); + } + } + + this.scrollTop = scrollTop; + } + + handleSearch(emojis) { + this.SEARCH_CATEGORY.emojis = emojis; + + for (let i = 0, l = this.categories.length; i < l; i++) { + let component = this.categoryRefs[`category-${i}`]; + + if (component && component.props.name != 'Search') { + let display = emojis ? 'none' : 'inherit'; + component.updateDisplay(display); + } + } + + this.forceUpdate(); + this.scroll.scrollTop = 0; + this.handleScroll(); + } + + handleAnchorClick(category, i) { + var component = this.categoryRefs[`category-${i}`], + { scroll, anchors } = this, + scrollToComponent = null; + + scrollToComponent = () => { + if (component) { + let { top } = component; + + if (category.first) { + top = 0; + } else { + top += 1; + } + + scroll.scrollTop = top; + } + }; + + if (this.SEARCH_CATEGORY.emojis) { + this.handleSearch(null); + this.search.clear(); + + window.requestAnimationFrame(scrollToComponent); + } else { + scrollToComponent(); + } + } + + handleSkinChange(skin) { + var newState = { skin: skin }, + { onSkinChange } = this.props; + + this.setState(newState); + store.update(newState); + + onSkinChange(skin); + } + + handleKeyDown(e) { + let handled = false; + + switch (e.keyCode) { + case 13: + let emoji; + + if (this.SEARCH_CATEGORY.emojis && this.SEARCH_CATEGORY.emojis.length && (emoji = getSanitizedData(this.SEARCH_CATEGORY.emojis[0], this.state.skin, this.props.set, this.props.data))) { + this.handleEmojiSelect(emoji); + } + + handled = true; + break; + } + + if (handled) { + e.preventDefault(); + } + } + + updateCategoriesSize() { + for (let i = 0, l = this.categories.length; i < l; i++) { + let component = this.categoryRefs[`category-${i}`]; + if (component) component.memoizeSize(); + } + + if (this.scroll) { + let target = this.scroll; + this.scrollHeight = target.scrollHeight; + this.clientHeight = target.clientHeight; + } + } + + getCategories() { + return this.state.firstRender ? this.categories.slice(0, 3) : this.categories; + } + + setAnchorsRef(c) { + this.anchors = c; + } + + setSearchRef(c) { + this.search = c; + } + + setPreviewRef(c) { + this.preview = c; + } + + setScrollRef(c) { + this.scroll = c; + } + + setCategoryRef(name, c) { + if (!this.categoryRefs) { + this.categoryRefs = {}; + } + + this.categoryRefs[name] = c; + } + + render() { + var { + perLine, + emojiSize, + set, + sheetSize, + sheetColumns, + sheetRows, + style, + title, + emoji, + color, + native, + backgroundImageFn, + emojisToShowFilter, + showPreview, + showSkinTones, + emojiTooltip, + include, + exclude, + recent, + autoFocus, + skinEmoji, + notFound, + notFoundEmoji + } = this.props, + { skin } = this.state, + width = perLine * (emojiSize + 12) + 12 + 2 + measureScrollbar(); + + return React.createElement( + 'div', + { + style: _extends({ width: width }, style), + className: 'emoji-mart', + onKeyDown: this.handleKeyDown + }, + React.createElement( + 'div', + { className: 'emoji-mart-bar' }, + React.createElement(Anchors, { + ref: this.setAnchorsRef, + data: this.data, + i18n: this.i18n, + color: color, + categories: this.categories, + onAnchorClick: this.handleAnchorClick, + icons: this.icons + }) + ), + React.createElement(Search, { + ref: this.setSearchRef, + onSearch: this.handleSearch, + data: this.data, + i18n: this.i18n, + emojisToShowFilter: emojisToShowFilter, + include: include, + exclude: exclude, + custom: this.CUSTOM_CATEGORY.emojis, + autoFocus: autoFocus + }), + React.createElement( + 'section', + { + ref: this.setScrollRef, + className: 'emoji-mart-scroll', + 'aria-label': this.i18n.emojilist, + onScroll: this.handleScroll + }, + this.getCategories().map((category, i) => { + return React.createElement(Category, { + ref: this.setCategoryRef.bind(this, `category-${i}`), + key: category.name, + id: category.id, + name: category.name, + emojis: category.emojis, + perLine: perLine, + native: native, + hasStickyPosition: this.hasStickyPosition, + data: this.data, + i18n: this.i18n, + recent: category.id == this.RECENT_CATEGORY.id ? recent : undefined, + custom: category.id == this.RECENT_CATEGORY.id ? this.CUSTOM_CATEGORY.emojis : undefined, + emojiProps: { + native: native, + skin: skin, + size: emojiSize, + set: set, + sheetSize: sheetSize, + sheetColumns: sheetColumns, + sheetRows: sheetRows, + forceSize: native, + tooltip: emojiTooltip, + backgroundImageFn: backgroundImageFn, + onOver: this.handleEmojiOver, + onLeave: this.handleEmojiLeave, + onClick: this.handleEmojiClick + }, + notFound: notFound, + notFoundEmoji: notFoundEmoji + }); + }) + ), + (showPreview || showSkinTones) && React.createElement( + 'div', + { className: 'emoji-mart-bar' }, + React.createElement(Preview, { + ref: this.setPreviewRef, + data: this.data, + title: title, + emoji: emoji, + showSkinTones: showSkinTones, + showPreview: showPreview, + emojiProps: { + native: native, + size: 38, + skin: skin, + set: set, + sheetSize: sheetSize, + sheetColumns: sheetColumns, + sheetRows: sheetRows, + backgroundImageFn: backgroundImageFn + }, + skinsProps: { + skin: skin, + onChange: this.handleSkinChange, + skinEmoji: skinEmoji + }, + i18n: this.i18n + }) + ) + ); + } +} + +NimblePicker.propTypes /* remove-proptypes */ = _extends({}, PickerPropTypes, { + data: PropTypes.object.isRequired +}); +NimblePicker.defaultProps = _extends({}, PickerDefaultProps); \ No newline at end of file diff --git a/dist-modern/components/picker/picker.js b/dist-modern/components/picker/picker.js new file mode 100644 index 000000000..a7f089b22 --- /dev/null +++ b/dist-modern/components/picker/picker.js @@ -0,0 +1,17 @@ +import _extends from '../../polyfills/extends'; +import React from 'react'; + +import data from '../../../data/all.json'; +import NimblePicker from './nimble-picker'; + +import { PickerPropTypes } from '../../utils/shared-props'; +import { PickerDefaultProps } from '../../utils/shared-default-props'; + +export default class Picker extends React.PureComponent { + render() { + return React.createElement(NimblePicker, _extends({}, this.props, this.state)); + } +} + +Picker.propTypes /* remove-proptypes */ = PickerPropTypes; +Picker.defaultProps = _extends({}, PickerDefaultProps, { data }); \ No newline at end of file diff --git a/dist-modern/components/preview.js b/dist-modern/components/preview.js new file mode 100644 index 000000000..c6829c312 --- /dev/null +++ b/dist-modern/components/preview.js @@ -0,0 +1,139 @@ +import _extends from '../polyfills/extends'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import { getData } from '../utils'; +import NimbleEmoji from './emoji/nimble-emoji'; +import SkinsEmoji from './skins-emoji'; +import SkinsDot from './skins-dot'; + +export default class Preview extends React.PureComponent { + constructor(props) { + super(props); + + this.data = props.data; + this.state = { emoji: null }; + } + + render() { + var { emoji } = this.state, + { + emojiProps, + skinsProps, + showSkinTones, + title, + emoji: idleEmoji, + i18n, + showPreview + } = this.props; + + if (emoji && showPreview) { + var emojiData = getData(emoji, null, null, this.data), + { emoticons = [] } = emojiData, + knownEmoticons = [], + listedEmoticons = []; + + emoticons.forEach(emoticon => { + if (knownEmoticons.indexOf(emoticon.toLowerCase()) >= 0) { + return; + } + + knownEmoticons.push(emoticon.toLowerCase()); + listedEmoticons.push(emoticon); + }); + + return React.createElement( + 'div', + { className: 'emoji-mart-preview' }, + React.createElement( + 'div', + { className: 'emoji-mart-preview-emoji' }, + NimbleEmoji(_extends({ + key: emoji.id, + emoji: emoji, + data: this.data + }, emojiProps)) + ), + React.createElement( + 'div', + { className: 'emoji-mart-preview-data' }, + React.createElement( + 'div', + { className: 'emoji-mart-preview-name' }, + emoji.name + ), + React.createElement( + 'div', + { className: 'emoji-mart-preview-shortnames' }, + emojiData.short_names.map(short_name => React.createElement( + 'span', + { key: short_name, className: 'emoji-mart-preview-shortname' }, + ':', + short_name, + ':' + )) + ), + React.createElement( + 'div', + { className: 'emoji-mart-preview-emoticons' }, + listedEmoticons.map(emoticon => React.createElement( + 'span', + { key: emoticon, className: 'emoji-mart-preview-emoticon' }, + emoticon + )) + ) + ) + ); + } else { + return React.createElement( + 'div', + { className: 'emoji-mart-preview' }, + React.createElement( + 'div', + { className: 'emoji-mart-preview-emoji' }, + idleEmoji && idleEmoji.length && NimbleEmoji(_extends({ emoji: idleEmoji, data: this.data }, emojiProps)) + ), + React.createElement( + 'div', + { className: 'emoji-mart-preview-data' }, + React.createElement( + 'span', + { className: 'emoji-mart-title-label' }, + title + ) + ), + showSkinTones && React.createElement( + 'div', + { + className: `emoji-mart-preview-skins${skinsProps.skinEmoji ? ' custom' : ''}` + }, + skinsProps.skinEmoji ? React.createElement(SkinsEmoji, { + skin: skinsProps.skin, + emojiProps: emojiProps, + data: this.data, + skinEmoji: skinsProps.skinEmoji, + i18n: i18n, + onChange: skinsProps.onChange + }) : React.createElement(SkinsDot, { + skin: skinsProps.skin, + i18n: i18n, + onChange: skinsProps.onChange + }) + ) + ); + } + } +} + +Preview.propTypes /* remove-proptypes */ = { + showSkinTones: PropTypes.bool, + title: PropTypes.string.isRequired, + emoji: PropTypes.string.isRequired, + emojiProps: PropTypes.object.isRequired, + skinsProps: PropTypes.object.isRequired +}; + +Preview.defaultProps = { + showSkinTones: true, + onChange: () => {} +}; \ No newline at end of file diff --git a/dist-modern/components/search.js b/dist-modern/components/search.js new file mode 100644 index 000000000..830ba5e24 --- /dev/null +++ b/dist-modern/components/search.js @@ -0,0 +1,116 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { search as icons } from '../svgs'; +import NimbleEmojiIndex from '../utils/emoji-index/nimble-emoji-index'; +import { throttleIdleTask } from '../utils/index'; + +let id = 0; + +export default class Search extends React.PureComponent { + constructor(props) { + super(props); + this.state = { + icon: icons.search, + isSearching: false, + id: ++id + }; + + this.data = props.data; + this.emojiIndex = new NimbleEmojiIndex(this.data); + this.setRef = this.setRef.bind(this); + this.clear = this.clear.bind(this); + this.handleKeyUp = this.handleKeyUp.bind(this); + + // throttle keyboard input so that typing isn't delayed + this.handleChange = throttleIdleTask(this.handleChange.bind(this)); + } + + search(value) { + if (value == '') this.setState({ + icon: icons.search, + isSearching: false + });else this.setState({ + icon: icons.delete, + isSearching: true + }); + + this.props.onSearch(this.emojiIndex.search(value, { + emojisToShowFilter: this.props.emojisToShowFilter, + maxResults: this.props.maxResults, + include: this.props.include, + exclude: this.props.exclude, + custom: this.props.custom + })); + } + + clear() { + if (this.input.value == '') return; + this.input.value = ''; + this.input.focus(); + this.search(''); + } + + handleChange() { + this.search(this.input.value); + } + + handleKeyUp(e) { + if (e.keyCode === 13) { + this.clear(); + } + } + + setRef(c) { + this.input = c; + } + + render() { + const { i18n, autoFocus } = this.props; + const { icon, isSearching, id } = this.state; + const inputId = `emoji-mart-search-${id}`; + + return React.createElement( + 'div', + { className: 'emoji-mart-search' }, + React.createElement('input', { + id: inputId, + ref: this.setRef, + type: 'search', + onChange: this.handleChange, + placeholder: i18n.search, + autoFocus: autoFocus + }), + React.createElement( + 'label', + { className: 'emoji-mart-sr-only', htmlFor: inputId }, + i18n.search + ), + React.createElement( + 'button', + { + className: 'emoji-mart-search-icon', + onClick: this.clear, + onKeyUp: this.handleKeyUp, + 'aria-label': i18n.clear, + disabled: !isSearching + }, + icon() + ) + ); + } +} + +Search.propTypes /* remove-proptypes */ = { + onSearch: PropTypes.func, + maxResults: PropTypes.number, + emojisToShowFilter: PropTypes.func, + autoFocus: PropTypes.bool +}; + +Search.defaultProps = { + onSearch: () => {}, + maxResults: 75, + emojisToShowFilter: null, + autoFocus: false +}; \ No newline at end of file diff --git a/dist-modern/components/skins-dot.js b/dist-modern/components/skins-dot.js new file mode 100644 index 000000000..e895d8f87 --- /dev/null +++ b/dist-modern/components/skins-dot.js @@ -0,0 +1,71 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import Skins from './skins'; + +export default class SkinsDot extends Skins { + constructor(props) { + super(props); + + this.handleClick = this.handleClick.bind(this); + this.handleKeyDown = this.handleKeyDown.bind(this); + } + + handleKeyDown(event) { + // if either enter or space is pressed, then execute + if (event.keyCode === 13 || event.keyCode === 32) { + this.handleClick(event); + } + } + + render() { + const { skin, i18n } = this.props; + const { opened } = this.state; + const skinToneNodes = []; + + for (let skinTone = 1; skinTone <= 6; skinTone++) { + const selected = skinTone === skin; + const visible = opened || selected; + skinToneNodes.push(React.createElement( + 'span', + { + key: `skin-tone-${skinTone}`, + className: `emoji-mart-skin-swatch${selected ? ' selected' : ''}` + }, + React.createElement('span', { + onClick: this.handleClick, + onKeyDown: this.handleKeyDown, + role: 'button', + tabindex: visible ? '0' : '', + 'aria-hidden': !visible, + 'aria-pressed': opened ? !!selected : '', + 'aria-haspopup': !!selected, + 'aria-expanded': selected ? opened : '', + 'aria-label': i18n.skintones[skinTone], + title: i18n.skintones[skinTone], + 'data-skin': skinTone, + className: `emoji-mart-skin emoji-mart-skin-tone-${skinTone}` + }) + )); + } + + return React.createElement( + 'section', + { + className: `emoji-mart-skin-swatches${opened ? ' opened' : ''}`, + 'aria-label': i18n.skintext + }, + skinToneNodes + ); + } +} + +SkinsDot.propTypes /* remove-proptypes */ = { + onChange: PropTypes.func, + skin: PropTypes.number.isRequired, + i18n: PropTypes.object +}; + +SkinsDot.defaultProps = { + onChange: () => {} +}; \ No newline at end of file diff --git a/dist-modern/components/skins-emoji.js b/dist-modern/components/skins-emoji.js new file mode 100644 index 000000000..837e3ee2b --- /dev/null +++ b/dist-modern/components/skins-emoji.js @@ -0,0 +1,75 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import NimbleEmoji from './emoji/nimble-emoji'; +import Skins from './skins'; + +export default class SkinsEmoji extends Skins { + constructor(props) { + super(props); + + this.handleClick = this.handleClick.bind(this); + } + + render() { + const { skin, emojiProps, data, skinEmoji, i18n } = this.props; + const { opened } = this.state; + const skinToneNodes = []; + + for (let skinTone = 1; skinTone <= 6; skinTone++) { + const selected = skinTone === skin; + skinToneNodes.push(React.createElement( + 'span', + { + key: `skin-tone-${skinTone}`, + className: `emoji-mart-skin-swatch custom${selected ? ' selected' : ''}` + }, + React.createElement( + 'span', + { + onClick: this.handleClick, + 'data-skin': skinTone, + className: `emoji-mart-skin-tone-${skinTone}` + }, + NimbleEmoji({ + emoji: skinEmoji, + data: data, + skin: skinTone, + backgroundImageFn: emojiProps.backgroundImageFn, + native: emojiProps.native, + set: emojiProps.set, + sheetSize: emojiProps.sheetSize, + size: 23 + }) + ) + )); + } + + return React.createElement( + 'div', + { + className: `emoji-mart-skin-swatches custom${opened ? ' opened' : ''}` + }, + React.createElement( + 'div', + { className: `emoji-mart-skin-text${opened ? ' opened' : ''}` }, + i18n.skintext + ), + skinToneNodes + ); + } +} + +SkinsEmoji.propTypes /* remove-proptypes */ = { + onChange: PropTypes.func, + skin: PropTypes.number.isRequired, + emojiProps: PropTypes.object.isRequired, + skinTone: PropTypes.number, + skinEmoji: PropTypes.string.isRequired, + i18n: PropTypes.object +}; + +SkinsEmoji.defaultProps = { + onChange: () => {}, + skinTone: null +}; \ No newline at end of file diff --git a/dist-modern/components/skins.js b/dist-modern/components/skins.js new file mode 100644 index 000000000..727860b91 --- /dev/null +++ b/dist-modern/components/skins.js @@ -0,0 +1,40 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import NimbleEmoji from './emoji/nimble-emoji'; + +export default class Skins extends React.PureComponent { + constructor(props) { + super(props); + this.state = { + opened: false + }; + } + + handleClick(e) { + var skin = parseInt(e.currentTarget.getAttribute('data-skin')); + var { onChange } = this.props; + + if (!this.state.opened) { + this.setState({ opened: true }); + } else { + this.setState({ opened: false }); + if (skin != this.props.skin) { + onChange(skin); + } + } + } + + render() { + return null; + } +} + +Skins.propTypes /* remove-proptypes */ = { + onChange: PropTypes.func, + skin: PropTypes.number.isRequired +}; + +Skins.defaultProps = { + onChange: () => {} +}; \ No newline at end of file diff --git a/dist-modern/index.js b/dist-modern/index.js new file mode 100644 index 000000000..29c206f59 --- /dev/null +++ b/dist-modern/index.js @@ -0,0 +1,10 @@ +export { default as emojiIndex } from './utils/emoji-index/emoji-index'; +export { default as NimbleEmojiIndex } from './utils/emoji-index/nimble-emoji-index'; +export { default as store } from './utils/store'; +export { default as frequently } from './utils/frequently'; + +export { default as Picker } from './components/picker/picker'; +export { default as NimblePicker } from './components/picker/nimble-picker'; +export { default as Emoji } from './components/emoji/emoji'; +export { default as NimbleEmoji } from './components/emoji/nimble-emoji'; +export { default as Category } from './components/category'; \ No newline at end of file diff --git a/dist-modern/polyfills/classCallCheck.js b/dist-modern/polyfills/classCallCheck.js new file mode 100644 index 000000000..054dcc123 --- /dev/null +++ b/dist-modern/polyfills/classCallCheck.js @@ -0,0 +1,5 @@ +export default function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } +} \ No newline at end of file diff --git a/dist-modern/polyfills/createClass.js b/dist-modern/polyfills/createClass.js new file mode 100644 index 000000000..8a9eab070 --- /dev/null +++ b/dist-modern/polyfills/createClass.js @@ -0,0 +1,19 @@ +const _Object = Object; + +export default (function createClass() { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) descriptor.writable = true; + _Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +})(); \ No newline at end of file diff --git a/dist-modern/polyfills/extends.js b/dist-modern/polyfills/extends.js new file mode 100644 index 000000000..53dd39033 --- /dev/null +++ b/dist-modern/polyfills/extends.js @@ -0,0 +1,15 @@ +const _Object = Object; + +export default _Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; +}; \ No newline at end of file diff --git a/dist-modern/polyfills/inherits.js b/dist-modern/polyfills/inherits.js new file mode 100644 index 000000000..f4f615a47 --- /dev/null +++ b/dist-modern/polyfills/inherits.js @@ -0,0 +1,19 @@ +const _Object = Object; + +export default function inherits(subClass, superClass) { + if (typeof superClass !== 'function' && superClass !== null) { + throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); + } + + subClass.prototype = _Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) { + _Object.setPrototypeOf ? _Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } +} \ No newline at end of file diff --git a/dist-modern/polyfills/keys.js b/dist-modern/polyfills/keys.js new file mode 100644 index 000000000..14c25a7c1 --- /dev/null +++ b/dist-modern/polyfills/keys.js @@ -0,0 +1,30 @@ +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys +var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !{ toString: null }.propertyIsEnumerable('toString'), + dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'], + dontEnumsLength = dontEnums.length; + +export default function (obj) { + if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) { + throw new TypeError('Object.keys called on non-object'); + } + + var result = [], + prop, + i; + + for (prop in obj) { + if (hasOwnProperty.call(obj, prop)) { + result.push(prop); + } + } + + if (hasDontEnumBug) { + for (i = 0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) { + result.push(dontEnums[i]); + } + } + } + return result; +} \ No newline at end of file diff --git a/dist-modern/polyfills/objectGetPrototypeOf.js b/dist-modern/polyfills/objectGetPrototypeOf.js new file mode 100644 index 000000000..2ad078553 --- /dev/null +++ b/dist-modern/polyfills/objectGetPrototypeOf.js @@ -0,0 +1,11 @@ +const _Object = Object; + +export default _Object.getPrototypeOf || function (O) { + O = Object(O); + + if (typeof O.constructor === 'function' && O instanceof O.constructor) { + return O.constructor.prototype; + } + + return O instanceof Object ? Object.prototype : null; +}; \ No newline at end of file diff --git a/dist-modern/polyfills/possibleConstructorReturn.js b/dist-modern/polyfills/possibleConstructorReturn.js new file mode 100644 index 000000000..a87e72212 --- /dev/null +++ b/dist-modern/polyfills/possibleConstructorReturn.js @@ -0,0 +1,7 @@ +export default function possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === 'object' || typeof call === 'function') ? call : self; +} \ No newline at end of file diff --git a/dist-modern/polyfills/stringFromCodePoint.js b/dist-modern/polyfills/stringFromCodePoint.js new file mode 100644 index 000000000..b1f943746 --- /dev/null +++ b/dist-modern/polyfills/stringFromCodePoint.js @@ -0,0 +1,40 @@ +const _String = String; + +export default _String.fromCodePoint || function stringFromCodePoint() { + var MAX_SIZE = 0x4000; + var codeUnits = []; + var highSurrogate; + var lowSurrogate; + var index = -1; + var length = arguments.length; + if (!length) { + return ''; + } + var result = ''; + while (++index < length) { + var codePoint = Number(arguments[index]); + if (!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity` + codePoint < 0 || // not a valid Unicode code point + codePoint > 0x10ffff || // not a valid Unicode code point + Math.floor(codePoint) != codePoint // not an integer + ) { + throw RangeError('Invalid code point: ' + codePoint); + } + if (codePoint <= 0xffff) { + // BMP code point + codeUnits.push(codePoint); + } else { + // Astral code point; split in surrogate halves + // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + codePoint -= 0x10000; + highSurrogate = (codePoint >> 10) + 0xd800; + lowSurrogate = codePoint % 0x400 + 0xdc00; + codeUnits.push(highSurrogate, lowSurrogate); + } + if (index + 1 === length || codeUnits.length > MAX_SIZE) { + result += String.fromCharCode.apply(null, codeUnits); + codeUnits.length = 0; + } + } + return result; +}; \ No newline at end of file diff --git a/dist-modern/svgs/index.js b/dist-modern/svgs/index.js new file mode 100644 index 000000000..982c1609c --- /dev/null +++ b/dist-modern/svgs/index.js @@ -0,0 +1,168 @@ +import React from "react"; + +const categories = { + activity: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M12 0C5.373 0 0 5.372 0 12c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.628-5.372-12-12-12m9.949 11H17.05c.224-2.527 1.232-4.773 1.968-6.113A9.966 9.966 0 0 1 21.949 11M13 11V2.051a9.945 9.945 0 0 1 4.432 1.564c-.858 1.491-2.156 4.22-2.392 7.385H13zm-2 0H8.961c-.238-3.165-1.536-5.894-2.393-7.385A9.95 9.95 0 0 1 11 2.051V11zm0 2v8.949a9.937 9.937 0 0 1-4.432-1.564c.857-1.492 2.155-4.221 2.393-7.385H11zm4.04 0c.236 3.164 1.534 5.893 2.392 7.385A9.92 9.92 0 0 1 13 21.949V13h2.04zM4.982 4.887C5.718 6.227 6.726 8.473 6.951 11h-4.9a9.977 9.977 0 0 1 2.931-6.113M2.051 13h4.9c-.226 2.527-1.233 4.771-1.969 6.113A9.972 9.972 0 0 1 2.051 13m16.967 6.113c-.735-1.342-1.744-3.586-1.968-6.113h4.899a9.961 9.961 0 0 1-2.931 6.113" }) + ), + + custom: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement( + "g", + { transform: "translate(2.000000, 1.000000)" }, + React.createElement("rect", { id: "Rectangle", x: "8", y: "0", width: "3", height: "21", rx: "1.5" }), + React.createElement("rect", { + id: "Rectangle", + transform: "translate(9.843, 10.549) rotate(60) translate(-9.843, -10.549) ", + x: "8.343", + y: "0.049", + width: "3", + height: "21", + rx: "1.5" + }), + React.createElement("rect", { + id: "Rectangle", + transform: "translate(9.843, 10.549) rotate(-60) translate(-9.843, -10.549) ", + x: "8.343", + y: "0.049", + width: "3", + height: "21", + rx: "1.5" + }) + ) + ), + + flags: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M0 0l6.084 24H8L1.916 0zM21 5h-4l-1-4H4l3 12h3l1 4h13L21 5zM6.563 3h7.875l2 8H8.563l-2-8zm8.832 10l-2.856 1.904L12.063 13h3.332zM19 13l-1.5-6h1.938l2 8H16l3-2z" }) + ), + + foods: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M17 4.978c-1.838 0-2.876.396-3.68.934.513-1.172 1.768-2.934 4.68-2.934a1 1 0 0 0 0-2c-2.921 0-4.629 1.365-5.547 2.512-.064.078-.119.162-.18.244C11.73 1.838 10.798.023 9.207.023 8.579.022 7.85.306 7 .978 5.027 2.54 5.329 3.902 6.492 4.999 3.609 5.222 0 7.352 0 12.969c0 4.582 4.961 11.009 9 11.009 1.975 0 2.371-.486 3-1 .629.514 1.025 1 3 1 4.039 0 9-6.418 9-11 0-5.953-4.055-8-7-8M8.242 2.546c.641-.508.943-.523.965-.523.426.169.975 1.405 1.357 3.055-1.527-.629-2.741-1.352-2.98-1.846.059-.112.241-.356.658-.686M15 21.978c-1.08 0-1.21-.109-1.559-.402l-.176-.146c-.367-.302-.816-.452-1.266-.452s-.898.15-1.266.452l-.176.146c-.347.292-.477.402-1.557.402-2.813 0-7-5.389-7-9.009 0-5.823 4.488-5.991 5-5.991 1.939 0 2.484.471 3.387 1.251l.323.276a1.995 1.995 0 0 0 2.58 0l.323-.276c.902-.78 1.447-1.251 3.387-1.251.512 0 5 .168 5 6 0 3.617-4.187 9-7 9" }) + ), + + nature: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M15.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 15.5 8M8.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 8.5 8" }), + React.createElement("path", { d: "M18.933 0h-.027c-.97 0-2.138.787-3.018 1.497-1.274-.374-2.612-.51-3.887-.51-1.285 0-2.616.133-3.874.517C7.245.79 6.069 0 5.093 0h-.027C3.352 0 .07 2.67.002 7.026c-.039 2.479.276 4.238 1.04 5.013.254.258.882.677 1.295.882.191 3.177.922 5.238 2.536 6.38.897.637 2.187.949 3.2 1.102C8.04 20.6 8 20.795 8 21c0 1.773 2.35 3 4 3 1.648 0 4-1.227 4-3 0-.201-.038-.393-.072-.586 2.573-.385 5.435-1.877 5.925-7.587.396-.22.887-.568 1.104-.788.763-.774 1.079-2.534 1.04-5.013C23.929 2.67 20.646 0 18.933 0M3.223 9.135c-.237.281-.837 1.155-.884 1.238-.15-.41-.368-1.349-.337-3.291.051-3.281 2.478-4.972 3.091-5.031.256.015.731.27 1.265.646-1.11 1.171-2.275 2.915-2.352 5.125-.133.546-.398.858-.783 1.313M12 22c-.901 0-1.954-.693-2-1 0-.654.475-1.236 1-1.602V20a1 1 0 1 0 2 0v-.602c.524.365 1 .947 1 1.602-.046.307-1.099 1-2 1m3-3.48v.02a4.752 4.752 0 0 0-1.262-1.02c1.092-.516 2.239-1.334 2.239-2.217 0-1.842-1.781-2.195-3.977-2.195-2.196 0-3.978.354-3.978 2.195 0 .883 1.148 1.701 2.238 2.217A4.8 4.8 0 0 0 9 18.539v-.025c-1-.076-2.182-.281-2.973-.842-1.301-.92-1.838-3.045-1.853-6.478l.023-.041c.496-.826 1.49-1.45 1.804-3.102 0-2.047 1.357-3.631 2.362-4.522C9.37 3.178 10.555 3 11.948 3c1.447 0 2.685.192 3.733.57 1 .9 2.316 2.465 2.316 4.48.313 1.651 1.307 2.275 1.803 3.102.035.058.068.117.102.178-.059 5.967-1.949 7.01-4.902 7.19m6.628-8.202c-.037-.065-.074-.13-.113-.195a7.587 7.587 0 0 0-.739-.987c-.385-.455-.648-.768-.782-1.313-.076-2.209-1.241-3.954-2.353-5.124.531-.376 1.004-.63 1.261-.647.636.071 3.044 1.764 3.096 5.031.027 1.81-.347 3.218-.37 3.235" }) + ), + + objects: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M12 0a9 9 0 0 0-5 16.482V21s2.035 3 5 3 5-3 5-3v-4.518A9 9 0 0 0 12 0zm0 2c3.86 0 7 3.141 7 7s-3.14 7-7 7-7-3.141-7-7 3.14-7 7-7zM9 17.477c.94.332 1.946.523 3 .523s2.06-.19 3-.523v.834c-.91.436-1.925.689-3 .689a6.924 6.924 0 0 1-3-.69v-.833zm.236 3.07A8.854 8.854 0 0 0 12 21c.965 0 1.888-.167 2.758-.451C14.155 21.173 13.153 22 12 22c-1.102 0-2.117-.789-2.764-1.453z" }), + React.createElement("path", { d: "M14.745 12.449h-.004c-.852-.024-1.188-.858-1.577-1.824-.421-1.061-.703-1.561-1.182-1.566h-.009c-.481 0-.783.497-1.235 1.537-.436.982-.801 1.811-1.636 1.791l-.276-.043c-.565-.171-.853-.691-1.284-1.794-.125-.313-.202-.632-.27-.913-.051-.213-.127-.53-.195-.634C7.067 9.004 7.039 9 6.99 9A1 1 0 0 1 7 7h.01c1.662.017 2.015 1.373 2.198 2.134.486-.981 1.304-2.058 2.797-2.075 1.531.018 2.28 1.153 2.731 2.141l.002-.008C14.944 8.424 15.327 7 16.979 7h.032A1 1 0 1 1 17 9h-.011c-.149.076-.256.474-.319.709a6.484 6.484 0 0 1-.311.951c-.429.973-.79 1.789-1.614 1.789" }) + ), + + people: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10" }), + React.createElement("path", { d: "M8 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 8 7M16 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 16 7M15.232 15c-.693 1.195-1.87 2-3.349 2-1.477 0-2.655-.805-3.347-2H15m3-2H6a6 6 0 1 0 12 0" }) + ), + + places: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M6.5 12C5.122 12 4 13.121 4 14.5S5.122 17 6.5 17 9 15.879 9 14.5 7.878 12 6.5 12m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5M17.5 12c-1.378 0-2.5 1.121-2.5 2.5s1.122 2.5 2.5 2.5 2.5-1.121 2.5-2.5-1.122-2.5-2.5-2.5m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5" }), + React.createElement("path", { d: "M22.482 9.494l-1.039-.346L21.4 9h.6c.552 0 1-.439 1-.992 0-.006-.003-.008-.003-.008H23c0-1-.889-2-1.984-2h-.642l-.731-1.717C19.262 3.012 18.091 2 16.764 2H7.236C5.909 2 4.738 3.012 4.357 4.283L3.626 6h-.642C1.889 6 1 7 1 8h.003S1 8.002 1 8.008C1 8.561 1.448 9 2 9h.6l-.043.148-1.039.346a2.001 2.001 0 0 0-1.359 2.097l.751 7.508a1 1 0 0 0 .994.901H3v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h6v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h1.096a.999.999 0 0 0 .994-.901l.751-7.508a2.001 2.001 0 0 0-1.359-2.097M6.273 4.857C6.402 4.43 6.788 4 7.236 4h9.527c.448 0 .834.43.963.857L19.313 9H4.688l1.585-4.143zM7 21H5v-1h2v1zm12 0h-2v-1h2v1zm2.189-3H2.811l-.662-6.607L3 11h18l.852.393L21.189 18z" }) + ), + + recent: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M13 4h-2l-.001 7H9v2h2v2h2v-2h4v-2h-4z" }), + React.createElement("path", { d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10" }) + ), + + symbols: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + React.createElement("path", { d: "M0 0h11v2H0zM4 11h3V6h4V4H0v2h4zM15.5 17c1.381 0 2.5-1.116 2.5-2.493s-1.119-2.493-2.5-2.493S13 13.13 13 14.507 14.119 17 15.5 17m0-2.986c.276 0 .5.222.5.493 0 .272-.224.493-.5.493s-.5-.221-.5-.493.224-.493.5-.493M21.5 19.014c-1.381 0-2.5 1.116-2.5 2.493S20.119 24 21.5 24s2.5-1.116 2.5-2.493-1.119-2.493-2.5-2.493m0 2.986a.497.497 0 0 1-.5-.493c0-.271.224-.493.5-.493s.5.222.5.493a.497.497 0 0 1-.5.493M22 13l-9 9 1.513 1.5 8.99-9.009zM17 11c2.209 0 4-1.119 4-2.5V2s.985-.161 1.498.949C23.01 4.055 23 6 23 6s1-1.119 1-3.135C24-.02 21 0 21 0h-2v6.347A5.853 5.853 0 0 0 17 6c-2.209 0-4 1.119-4 2.5s1.791 2.5 4 2.5M10.297 20.482l-1.475-1.585a47.54 47.54 0 0 1-1.442 1.129c-.307-.288-.989-1.016-2.045-2.183.902-.836 1.479-1.466 1.729-1.892s.376-.871.376-1.336c0-.592-.273-1.178-.818-1.759-.546-.581-1.329-.871-2.349-.871-1.008 0-1.79.293-2.344.879-.556.587-.832 1.181-.832 1.784 0 .813.419 1.748 1.256 2.805-.847.614-1.444 1.208-1.794 1.784a3.465 3.465 0 0 0-.523 1.833c0 .857.308 1.56.924 2.107.616.549 1.423.823 2.42.823 1.173 0 2.444-.379 3.813-1.137L8.235 24h2.819l-2.09-2.383 1.333-1.135zm-6.736-6.389a1.02 1.02 0 0 1 .73-.286c.31 0 .559.085.747.254a.849.849 0 0 1 .283.659c0 .518-.419 1.112-1.257 1.784-.536-.651-.805-1.231-.805-1.742a.901.901 0 0 1 .302-.669M3.74 22c-.427 0-.778-.116-1.057-.349-.279-.232-.418-.487-.418-.766 0-.594.509-1.288 1.527-2.083.968 1.134 1.717 1.946 2.248 2.438-.921.507-1.686.76-2.3.76" }) + ) +}; + +const search = { + search: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "13", + height: "13", + viewBox: "0 0 20 20", + opacity: "0.5" + }, + React.createElement("path", { d: "M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z" }) + ), + + delete: () => React.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "13", + height: "13", + viewBox: "0 0 20 20", + opacity: "0.5" + }, + React.createElement("path", { d: "M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z" }) + ) +}; + +export { categories, search }; \ No newline at end of file diff --git a/dist-modern/utils/data.js b/dist-modern/utils/data.js new file mode 100644 index 000000000..88f4de710 --- /dev/null +++ b/dist-modern/utils/data.js @@ -0,0 +1,106 @@ +const mapping = { + name: 'a', + unified: 'b', + non_qualified: 'c', + has_img_apple: 'd', + has_img_google: 'e', + has_img_twitter: 'f', + has_img_emojione: 'g', + has_img_facebook: 'h', + has_img_messenger: 'i', + keywords: 'j', + sheet: 'k', + emoticons: 'l', + text: 'm', + short_names: 'n', + added_in: 'o' +}; + +const buildSearch = emoji => { + const search = []; + + var addToSearch = (strings, split) => { + if (!strings) { + return; + } + + ;(Array.isArray(strings) ? strings : [strings]).forEach(string => { + ;(split ? string.split(/[-|_|\s]+/) : [string]).forEach(s => { + s = s.toLowerCase(); + + if (search.indexOf(s) == -1) { + search.push(s); + } + }); + }); + }; + + addToSearch(emoji.short_names, true); + addToSearch(emoji.name, true); + addToSearch(emoji.keywords, false); + addToSearch(emoji.emoticons, false); + + return search.join(','); +}; + +const compress = emoji => { + emoji.short_names = emoji.short_names.filter(short_name => { + return short_name !== emoji.short_name; + }); + delete emoji.short_name; + + emoji.sheet = [emoji.sheet_x, emoji.sheet_y]; + delete emoji.sheet_x; + delete emoji.sheet_y; + + emoji.added_in = parseInt(emoji.added_in); + if (emoji.added_in === 6) { + delete emoji.added_in; + } + + for (let key in mapping) { + emoji[mapping[key]] = emoji[key]; + delete emoji[key]; + } + + for (let key in emoji) { + let value = emoji[key]; + + if (Array.isArray(value) && !value.length) { + delete emoji[key]; + } else if (typeof value === 'string' && !value.length) { + delete emoji[key]; + } else if (value === null) { + delete emoji[key]; + } + } +}; + +const uncompress = data => { + data.compressed = false; + + for (let id in data.emojis) { + let emoji = data.emojis[id]; + + for (let key in mapping) { + emoji[key] = emoji[mapping[key]]; + delete emoji[mapping[key]]; + } + + if (!emoji.short_names) emoji.short_names = []; + emoji.short_names.unshift(id); + + emoji.sheet_x = emoji.sheet[0]; + emoji.sheet_y = emoji.sheet[1]; + delete emoji.sheet; + + if (!emoji.text) emoji.text = ''; + + if (!emoji.added_in) emoji.added_in = 6; + emoji.added_in = emoji.added_in.toFixed(1); + + emoji.search = buildSearch(emoji); + } +}; + +export { buildSearch, compress, uncompress }; \ No newline at end of file diff --git a/dist-modern/utils/emoji-index/emoji-index.js b/dist-modern/utils/emoji-index/emoji-index.js new file mode 100644 index 000000000..e07687eb2 --- /dev/null +++ b/dist-modern/utils/emoji-index/emoji-index.js @@ -0,0 +1,11 @@ +import data from '../../../data/all.json'; +import NimbleEmojiIndex from './nimble-emoji-index'; + +const emojiIndex = new NimbleEmojiIndex(data); +const { emojis, emoticons } = emojiIndex; + +function search() { + return emojiIndex.search(...arguments); +} + +export default { search, emojis, emoticons }; \ No newline at end of file diff --git a/dist-modern/utils/emoji-index/nimble-emoji-index.js b/dist-modern/utils/emoji-index/nimble-emoji-index.js new file mode 100644 index 000000000..ef16bd3a0 --- /dev/null +++ b/dist-modern/utils/emoji-index/nimble-emoji-index.js @@ -0,0 +1,180 @@ +import { getData, getSanitizedData, intersect } from '..'; +import { uncompress } from '../data'; + +export default class NimbleEmojiIndex { + constructor(data) { + if (data.compressed) { + uncompress(data); + } + + this.data = data || {}; + this.originalPool = {}; + this.index = {}; + this.emojis = {}; + this.emoticons = {}; + this.customEmojisList = []; + + this.buildIndex(); + } + + buildIndex() { + for (let emoji in this.data.emojis) { + let emojiData = this.data.emojis[emoji], + { short_names, emoticons } = emojiData, + id = short_names[0]; + + if (emoticons) { + emoticons.forEach(emoticon => { + if (this.emoticons[emoticon]) { + return; + } + + this.emoticons[emoticon] = id; + }); + } + + this.emojis[id] = getSanitizedData(id, null, null, this.data); + this.originalPool[id] = emojiData; + } + } + + clearCustomEmojis(pool) { + this.customEmojisList.forEach(emoji => { + let emojiId = emoji.id || emoji.short_names[0]; + + delete pool[emojiId]; + delete this.emojis[emojiId]; + }); + } + + addCustomToPool(custom, pool) { + if (this.customEmojisList.length) this.clearCustomEmojis(pool); + + custom.forEach(emoji => { + let emojiId = emoji.id || emoji.short_names[0]; + + if (emojiId && !pool[emojiId]) { + pool[emojiId] = getData(emoji, null, null, this.data); + this.emojis[emojiId] = getSanitizedData(emoji, null, null, this.data); + } + }); + + this.customEmojisList = custom; + this.index = {}; + } + + search(value, { emojisToShowFilter, maxResults, include, exclude, custom = [] } = {}) { + if (this.customEmojisList != custom) this.addCustomToPool(custom, this.originalPool); + + maxResults || (maxResults = 75); + include || (include = []); + exclude || (exclude = []); + + var results = null, + pool = this.originalPool; + + if (value.length) { + if (value == '-' || value == '-1') { + return [this.emojis['-1']]; + } + + var values = value.toLowerCase().split(/[\s|,|\-|_]+/), + allResults = []; + + if (values.length > 2) { + values = [values[0], values[1]]; + } + + if (include.length || exclude.length) { + pool = {}; + + this.data.categories.forEach(category => { + let isIncluded = include && include.length ? include.indexOf(category.id) > -1 : true; + let isExcluded = exclude && exclude.length ? exclude.indexOf(category.id) > -1 : false; + if (!isIncluded || isExcluded) { + return; + } + + category.emojis.forEach(emojiId => pool[emojiId] = this.data.emojis[emojiId]); + }); + + if (custom.length) { + let customIsIncluded = include && include.length ? include.indexOf('custom') > -1 : true; + let customIsExcluded = exclude && exclude.length ? exclude.indexOf('custom') > -1 : false; + if (customIsIncluded && !customIsExcluded) { + this.addCustomToPool(custom, pool); + } + } + } + + allResults = values.map(value => { + var aPool = pool, + aIndex = this.index, + length = 0; + + for (let charIndex = 0; charIndex < value.length; charIndex++) { + const char = value[charIndex]; + length++; + + aIndex[char] || (aIndex[char] = {}); + aIndex = aIndex[char]; + + if (!aIndex.results) { + let scores = {}; + + aIndex.results = []; + aIndex.pool = {}; + + for (let id in aPool) { + let emoji = aPool[id], + { search } = emoji, + sub = value.substr(0, length), + subIndex = search.indexOf(sub); + + if (subIndex != -1) { + let score = subIndex + 1; + if (sub == id) score = 0; + + aIndex.results.push(this.emojis[id]); + aIndex.pool[id] = emoji; + + scores[id] = score; + } + } + + aIndex.results.sort((a, b) => { + var aScore = scores[a.id], + bScore = scores[b.id]; + + return aScore - bScore; + }); + } + + aPool = aIndex.pool; + } + + return aIndex.results; + }).filter(a => a); + + if (allResults.length > 1) { + results = intersect.apply(null, allResults); + } else if (allResults.length) { + results = allResults[0]; + } else { + results = []; + } + } + + if (results) { + if (emojisToShowFilter) { + results = results.filter(result => emojisToShowFilter(pool[result.id])); + } + + if (results && results.length > maxResults) { + results = results.slice(0, maxResults); + } + } + + return results; + } +} \ No newline at end of file diff --git a/dist-modern/utils/frequently.js b/dist-modern/utils/frequently.js new file mode 100644 index 000000000..51aca9f7c --- /dev/null +++ b/dist-modern/utils/frequently.js @@ -0,0 +1,62 @@ +import store from './store'; + +const DEFAULTS = ['+1', 'grinning', 'kissing_heart', 'heart_eyes', 'laughing', 'stuck_out_tongue_winking_eye', 'sweat_smile', 'joy', 'scream', 'disappointed', 'unamused', 'weary', 'sob', 'sunglasses', 'heart', 'poop']; + +let frequently, initialized; +let defaults = {}; + +function init() { + initialized = true; + frequently = store.get('frequently'); +} + +function add(emoji) { + if (!initialized) init(); + var { id } = emoji; + + frequently || (frequently = defaults); + frequently[id] || (frequently[id] = 0); + frequently[id] += 1; + + store.set('last', id); + store.set('frequently', frequently); +} + +function get(perLine) { + if (!initialized) init(); + if (!frequently) { + defaults = {}; + + const result = []; + + for (let i = 0; i < perLine; i++) { + defaults[DEFAULTS[i]] = perLine - i; + result.push(DEFAULTS[i]); + } + + return result; + } + + const quantity = perLine * 4; + const frequentlyKeys = []; + + for (let key in frequently) { + if (frequently.hasOwnProperty(key)) { + frequentlyKeys.push(key); + } + } + + const sorted = frequentlyKeys.sort((a, b) => frequently[a] - frequently[b]).reverse(); + const sliced = sorted.slice(0, quantity); + + const last = store.get('last'); + + if (last && sliced.indexOf(last) == -1) { + sliced.pop(); + sliced.push(last); + } + + return sliced; +} + +export default { add, get }; \ No newline at end of file diff --git a/dist-modern/utils/index.js b/dist-modern/utils/index.js new file mode 100644 index 000000000..0241c8238 --- /dev/null +++ b/dist-modern/utils/index.js @@ -0,0 +1,206 @@ +import _Object$keys from '../polyfills/keys'; +import { buildSearch } from './data'; +import stringFromCodePoint from '../polyfills/stringFromCodePoint'; + +const _JSON = JSON; + +const COLONS_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/; +const SKINS = ['1F3FA', '1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF']; + +function unifiedToNative(unified) { + var unicodes = unified.split('-'), + codePoints = unicodes.map(u => `0x${u}`); + + return stringFromCodePoint.apply(null, codePoints); +} + +function sanitize(emoji) { + var { + name, + short_names, + skin_tone, + skin_variations, + emoticons, + unified, + custom, + imageUrl + } = emoji, + id = emoji.id || short_names[0], + colons = `:${id}:`; + + if (custom) { + return { + id, + name, + colons, + emoticons, + custom, + imageUrl + }; + } + + if (skin_tone) { + colons += `:skin-tone-${skin_tone}:`; + } + + return { + id, + name, + colons, + emoticons, + unified: unified.toLowerCase(), + skin: skin_tone || (skin_variations ? 1 : null), + native: unifiedToNative(unified) + }; +} + +function getSanitizedData() { + return sanitize(getData(...arguments)); +} + +function getData(emoji, skin, set, data) { + var emojiData = {}; + + if (typeof emoji == 'string') { + let matches = emoji.match(COLONS_REGEX); + + if (matches) { + emoji = matches[1]; + + if (matches[2]) { + skin = parseInt(matches[2], 10); + } + } + + if (data.aliases.hasOwnProperty(emoji)) { + emoji = data.aliases[emoji]; + } + + if (data.emojis.hasOwnProperty(emoji)) { + emojiData = data.emojis[emoji]; + } else { + return null; + } + } else if (emoji.id) { + if (data.aliases.hasOwnProperty(emoji.id)) { + emoji.id = data.aliases[emoji.id]; + } + + if (data.emojis.hasOwnProperty(emoji.id)) { + emojiData = data.emojis[emoji.id]; + skin || (skin = emoji.skin); + } + } + + if (!_Object$keys(emojiData).length) { + emojiData = emoji; + emojiData.custom = true; + + if (!emojiData.search) { + emojiData.search = buildSearch(emoji); + } + } + + emojiData.emoticons || (emojiData.emoticons = []); + emojiData.variations || (emojiData.variations = []); + + if (emojiData.skin_variations && skin > 1 && set) { + emojiData = JSON.parse(_JSON.stringify(emojiData)); + + var skinKey = SKINS[skin - 1], + variationData = emojiData.skin_variations[skinKey]; + + if (!variationData.variations && emojiData.variations) { + delete emojiData.variations; + } + + if (variationData[`has_img_${set}`] == undefined || variationData[`has_img_${set}`]) { + emojiData.skin_tone = skin; + + for (let k in variationData) { + let v = variationData[k]; + emojiData[k] = v; + } + } + } + + if (emojiData.variations && emojiData.variations.length) { + emojiData = JSON.parse(_JSON.stringify(emojiData)); + emojiData.unified = emojiData.variations.shift(); + } + + return emojiData; +} + +function uniq(arr) { + return arr.reduce((acc, item) => { + if (acc.indexOf(item) === -1) { + acc.push(item); + } + return acc; + }, []); +} + +function intersect(a, b) { + const uniqA = uniq(a); + const uniqB = uniq(b); + + return uniqA.filter(item => uniqB.indexOf(item) >= 0); +} + +function deepMerge(a, b) { + var o = {}; + + for (let key in a) { + let originalValue = a[key], + value = originalValue; + + if (b.hasOwnProperty(key)) { + value = b[key]; + } + + if (typeof value === 'object') { + value = deepMerge(originalValue, value); + } + + o[key] = value; + } + + return o; +} + +// https://github.com/sonicdoe/measure-scrollbar +function measureScrollbar() { + if (typeof document == 'undefined') return 0; + const div = document.createElement('div'); + + div.style.width = '100px'; + div.style.height = '100px'; + div.style.overflow = 'scroll'; + div.style.position = 'absolute'; + div.style.top = '-9999px'; + + document.body.appendChild(div); + const scrollbarWidth = div.offsetWidth - div.clientWidth; + document.body.removeChild(div); + + return scrollbarWidth; +} + +// Use requestIdleCallback() if available, else fall back to setTimeout(). +// Throttle so as not to run too frequently. +function throttleIdleTask(func) { + const queue = typeof requestIdleCallback === 'function' ? requestIdleCallback : setTimeout; + const clear = typeof cancelIdleCallback === 'function' ? cancelIdleCallback : clearTimeout; + + let id; + + return function throttled() { + if (id) { + clear(id); + } + id = queue(func); + }; +} + +export { getData, getSanitizedData, uniq, intersect, deepMerge, unifiedToNative, measureScrollbar, throttleIdleTask }; \ No newline at end of file diff --git a/dist-modern/utils/shared-default-props.js b/dist-modern/utils/shared-default-props.js new file mode 100644 index 000000000..88d2e632c --- /dev/null +++ b/dist-modern/utils/shared-default-props.js @@ -0,0 +1,45 @@ +const EmojiDefaultProps = { + skin: 1, + set: 'apple', + sheetSize: 64, + sheetColumns: 52, + sheetRows: 52, + native: false, + forceSize: false, + tooltip: false, + backgroundImageFn: (set, sheetSize) => `https://unpkg.com/emoji-datasource-${set}@${'4.0.4'}/img/${set}/sheets-256/${sheetSize}.png`, + onOver: () => {}, + onLeave: () => {}, + onClick: () => {} +}; + +const PickerDefaultProps = { + onClick: () => {}, + onSelect: () => {}, + onSkinChange: () => {}, + emojiSize: 24, + perLine: 9, + i18n: {}, + style: {}, + title: 'Emoji Mart™', + emoji: 'department_store', + color: '#ae65c5', + set: EmojiDefaultProps.set, + skin: null, + defaultSkin: EmojiDefaultProps.skin, + native: EmojiDefaultProps.native, + sheetSize: EmojiDefaultProps.sheetSize, + backgroundImageFn: EmojiDefaultProps.backgroundImageFn, + emojisToShowFilter: null, + showPreview: true, + showSkinTones: true, + emojiTooltip: EmojiDefaultProps.tooltip, + autoFocus: false, + custom: [], + skinEmoji: '', + notFound: () => {}, + notFoundEmoji: 'sleuth_or_spy', + icons: {} +}; + +export { PickerDefaultProps, EmojiDefaultProps }; \ No newline at end of file diff --git a/dist-modern/utils/shared-props.js b/dist-modern/utils/shared-props.js new file mode 100644 index 000000000..419c2fc18 --- /dev/null +++ b/dist-modern/utils/shared-props.js @@ -0,0 +1,59 @@ +import PropTypes from 'prop-types'; + +const EmojiPropTypes = { + data: PropTypes.object.isRequired, + onOver: PropTypes.func, + onLeave: PropTypes.func, + onClick: PropTypes.func, + fallback: PropTypes.func, + backgroundImageFn: PropTypes.func, + native: PropTypes.bool, + forceSize: PropTypes.bool, + tooltip: PropTypes.bool, + skin: PropTypes.oneOf([1, 2, 3, 4, 5, 6]), + sheetSize: PropTypes.oneOf([16, 20, 32, 64]), + sheetColumns: PropTypes.number, + sheetRows: PropTypes.number, + set: PropTypes.oneOf(['apple', 'google', 'twitter', 'emojione', 'messenger', 'facebook']), + size: PropTypes.number.isRequired, + emoji: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired +}; + +const PickerPropTypes = { + onClick: PropTypes.func, + onSelect: PropTypes.func, + onSkinChange: PropTypes.func, + perLine: PropTypes.number, + emojiSize: PropTypes.number, + i18n: PropTypes.object, + style: PropTypes.object, + title: PropTypes.string, + emoji: PropTypes.string, + color: PropTypes.string, + set: EmojiPropTypes.set, + skin: EmojiPropTypes.skin, + native: PropTypes.bool, + backgroundImageFn: EmojiPropTypes.backgroundImageFn, + sheetSize: EmojiPropTypes.sheetSize, + emojisToShowFilter: PropTypes.func, + showPreview: PropTypes.bool, + showSkinTones: PropTypes.bool, + emojiTooltip: EmojiPropTypes.tooltip, + include: PropTypes.arrayOf(PropTypes.string), + exclude: PropTypes.arrayOf(PropTypes.string), + recent: PropTypes.arrayOf(PropTypes.string), + autoFocus: PropTypes.bool, + custom: PropTypes.arrayOf(PropTypes.shape({ + name: PropTypes.string.isRequired, + short_names: PropTypes.arrayOf(PropTypes.string).isRequired, + emoticons: PropTypes.arrayOf(PropTypes.string), + keywords: PropTypes.arrayOf(PropTypes.string), + imageUrl: PropTypes.string.isRequired + })), + skinEmoji: PropTypes.string, + notFound: PropTypes.func, + notFoundEmoji: PropTypes.string, + icons: PropTypes.object +}; + +export { EmojiPropTypes, PickerPropTypes }; \ No newline at end of file diff --git a/dist-modern/utils/store.js b/dist-modern/utils/store.js new file mode 100644 index 000000000..11a6c6cc0 --- /dev/null +++ b/dist-modern/utils/store.js @@ -0,0 +1,56 @@ +var NAMESPACE = 'emoji-mart'; + +const _JSON = JSON; + +var isLocalStorageSupported = typeof window !== 'undefined' && 'localStorage' in window; + +let getter; +let setter; + +function setHandlers(handlers) { + handlers || (handlers = {}); + + getter = handlers.getter; + setter = handlers.setter; +} + +function setNamespace(namespace) { + NAMESPACE = namespace; +} + +function update(state) { + for (let key in state) { + let value = state[key]; + set(key, value); + } +} + +function set(key, value) { + if (setter) { + setter(key, value); + } else { + if (!isLocalStorageSupported) return; + try { + window.localStorage[`${NAMESPACE}.${key}`] = _JSON.stringify(value); + } catch (e) {} + } +} + +function get(key) { + if (getter) { + return getter(key); + } else { + if (!isLocalStorageSupported) return; + try { + var value = window.localStorage[`${NAMESPACE}.${key}`]; + } catch (e) { + return; + } + + if (value) { + return JSON.parse(value); + } + } +} + +export default { update, set, get, setNamespace, setHandlers }; \ No newline at end of file diff --git a/dist-modern/vendor/raf-polyfill.js b/dist-modern/vendor/raf-polyfill.js new file mode 100644 index 000000000..e160df618 --- /dev/null +++ b/dist-modern/vendor/raf-polyfill.js @@ -0,0 +1,33 @@ +// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + +// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel + +// MIT license + +var isWindowAvailable = typeof window !== 'undefined'; + +isWindowAvailable && function () { + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function () { + callback(currTime + timeToCall); + }, timeToCall); + + lastTime = currTime + timeToCall; + return id; + }; + + if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; +}(); \ No newline at end of file diff --git a/dist/components/anchors.js b/dist/components/anchors.js new file mode 100644 index 000000000..3e49beef4 --- /dev/null +++ b/dist/components/anchors.js @@ -0,0 +1,89 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Anchors extends _react2.default.PureComponent { + constructor(props) { + super(props); + + let defaultCategory = props.categories.filter(category => category.first)[0]; + + this.state = { + selected: defaultCategory.name + }; + + this.handleClick = this.handleClick.bind(this); + } + + handleClick(e) { + var index = e.currentTarget.getAttribute('data-index'); + var { categories, onAnchorClick } = this.props; + + onAnchorClick(categories[index], index); + } + + render() { + var { categories, color, i18n, icons } = this.props, + { selected } = this.state; + + return _react2.default.createElement( + 'nav', + { className: 'emoji-mart-anchors', 'aria-label': i18n.categorieslabel }, + categories.map((category, i) => { + var { id, name, anchor } = category, + isSelected = name == selected; + + if (anchor === false) { + return null; + } + + return _react2.default.createElement( + 'button', + { + key: id, + 'aria-label': i18n.categories[id], + title: i18n.categories[id], + 'data-index': i, + onClick: this.handleClick, + className: `emoji-mart-anchor ${isSelected ? 'emoji-mart-anchor-selected' : ''}`, + style: { color: isSelected ? color : null } + }, + _react2.default.createElement( + 'div', + { className: 'emoji-mart-anchor-icon' }, + icons.categories[id]() + ), + _react2.default.createElement('span', { + className: 'emoji-mart-anchor-bar', + style: { backgroundColor: color } + }) + ); + }) + ); + } +} + +exports.default = Anchors; +Anchors.propTypes /* remove-proptypes */ = { + categories: _propTypes2.default.array, + onAnchorClick: _propTypes2.default.func, + icons: _propTypes2.default.object +}; + +Anchors.defaultProps = { + categories: [], + onAnchorClick: () => {}, + icons: {} +}; \ No newline at end of file diff --git a/dist/components/category.js b/dist/components/category.js new file mode 100644 index 000000000..a911c74ee --- /dev/null +++ b/dist/components/category.js @@ -0,0 +1,248 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends2 = require('../polyfills/extends'); + +var _extends3 = _interopRequireDefault(_extends2); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _frequently = require('../utils/frequently'); + +var _frequently2 = _interopRequireDefault(_frequently); + +var _utils = require('../utils'); + +var _nimbleEmoji = require('./emoji/nimble-emoji'); + +var _nimbleEmoji2 = _interopRequireDefault(_nimbleEmoji); + +var _notFound = require('./not-found'); + +var _notFound2 = _interopRequireDefault(_notFound); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Category extends _react2.default.Component { + constructor(props) { + super(props); + + this.data = props.data; + this.setContainerRef = this.setContainerRef.bind(this); + this.setLabelRef = this.setLabelRef.bind(this); + } + + componentDidMount() { + this.margin = 0; + this.minMargin = 0; + + this.memoizeSize(); + } + + shouldComponentUpdate(nextProps, nextState) { + var { + name, + perLine, + native, + hasStickyPosition, + emojis, + emojiProps + } = this.props, + { skin, size, set } = emojiProps, + { + perLine: nextPerLine, + native: nextNative, + hasStickyPosition: nextHasStickyPosition, + emojis: nextEmojis, + emojiProps: nextEmojiProps + } = nextProps, + { skin: nextSkin, size: nextSize, set: nextSet } = nextEmojiProps, + 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; + } + + memoizeSize() { + var parent = this.container.parentElement; + var { top, height } = this.container.getBoundingClientRect(); + var { top: parentTop } = parent.getBoundingClientRect(); + var { height: labelHeight } = this.label.getBoundingClientRect(); + + this.top = top - parentTop + parent.scrollTop; + + if (height == 0) { + this.maxMargin = 0; + } else { + this.maxMargin = height - labelHeight; + } + } + + 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 = `${margin}px`; + } + + this.margin = margin; + return true; + } + + getEmojis() { + var { name, emojis, recent, perLine } = this.props; + + if (name == 'Recent') { + let { custom } = this.props; + let frequentlyUsed = recent || _frequently2.default.get(perLine); + + if (frequentlyUsed.length) { + emojis = frequentlyUsed.map(id => { + const emoji = custom.filter(e => e.id === id)[0]; + if (emoji) { + return emoji; + } + + return id; + }).filter(id => !!(0, _utils.getData)(id, null, null, this.data)); + } + + if (emojis.length === 0 && frequentlyUsed.length > 0) { + return null; + } + } + + if (emojis) { + emojis = emojis.slice(0); + } + + return emojis; + } + + updateDisplay(display) { + var emojis = this.getEmojis(); + + if (!emojis) { + return; + } + + this.container.style.display = display; + } + + setContainerRef(c) { + this.container = c; + } + + setLabelRef(c) { + this.label = c; + } + + render() { + var { + id, + name, + hasStickyPosition, + emojiProps, + i18n, + notFound, + notFoundEmoji + } = this.props, + emojis = this.getEmojis(), + labelStyles = {}, + labelSpanStyles = {}, + containerStyles = {}; + + if (!emojis) { + containerStyles = { + display: 'none' + }; + } + + if (!hasStickyPosition) { + labelStyles = { + height: 28 + }; + + labelSpanStyles = { + position: 'absolute' + }; + } + + return _react2.default.createElement( + 'section', + { + ref: this.setContainerRef, + className: 'emoji-mart-category', + 'aria-label': i18n.categories[id], + style: containerStyles + }, + _react2.default.createElement( + 'div', + { + style: labelStyles, + 'data-name': name, + className: 'emoji-mart-category-label' + }, + _react2.default.createElement( + 'span', + { + style: labelSpanStyles, + ref: this.setLabelRef, + 'aria-hidden': true /* already labeled by the section aria-label */ + }, + i18n.categories[id] + ) + ), + emojis && emojis.map(emoji => (0, _nimbleEmoji2.default)((0, _extends3.default)({ emoji: emoji, data: this.data }, emojiProps))), + emojis && !emojis.length && _react2.default.createElement(_notFound2.default, { + i18n: i18n, + notFound: notFound, + notFoundEmoji: notFoundEmoji, + data: this.data, + emojiProps: emojiProps + }) + ); + } +} + +exports.default = Category; +Category.propTypes /* remove-proptypes */ = { + emojis: _propTypes2.default.array, + hasStickyPosition: _propTypes2.default.bool, + name: _propTypes2.default.string.isRequired, + native: _propTypes2.default.bool.isRequired, + perLine: _propTypes2.default.number.isRequired, + emojiProps: _propTypes2.default.object.isRequired, + recent: _propTypes2.default.arrayOf(_propTypes2.default.string), + notFound: _propTypes2.default.func, + notFoundEmoji: _propTypes2.default.string.isRequired +}; + +Category.defaultProps = { + emojis: [], + hasStickyPosition: true +}; \ No newline at end of file diff --git a/dist/components/emoji/emoji.js b/dist/components/emoji/emoji.js new file mode 100644 index 000000000..7e10e2b7e --- /dev/null +++ b/dist/components/emoji/emoji.js @@ -0,0 +1,42 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends2 = require('../../polyfills/extends'); + +var _extends3 = _interopRequireDefault(_extends2); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _all = require('../../../data/all.json'); + +var _all2 = _interopRequireDefault(_all); + +var _nimbleEmoji = require('./nimble-emoji'); + +var _nimbleEmoji2 = _interopRequireDefault(_nimbleEmoji); + +var _sharedProps = require('../../utils/shared-props'); + +var _sharedDefaultProps = require('../../utils/shared-default-props'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const Emoji = props => { + for (let k in Emoji.defaultProps) { + if (props[k] == undefined && Emoji.defaultProps[k] != undefined) { + props[k] = Emoji.defaultProps[k]; + } + } + + return (0, _nimbleEmoji2.default)((0, _extends3.default)({}, props)); +}; + +Emoji.propTypes /* remove-proptypes */ = _sharedProps.EmojiPropTypes; +Emoji.defaultProps = (0, _extends3.default)({}, _sharedDefaultProps.EmojiDefaultProps, { data: _all2.default }); + +exports.default = Emoji; \ No newline at end of file diff --git a/dist/components/emoji/nimble-emoji.js b/dist/components/emoji/nimble-emoji.js new file mode 100644 index 000000000..7b1071be7 --- /dev/null +++ b/dist/components/emoji/nimble-emoji.js @@ -0,0 +1,214 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends2 = require('../../polyfills/extends'); + +var _extends3 = _interopRequireDefault(_extends2); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _utils = require('../../utils'); + +var _data = require('../../utils/data'); + +var _sharedProps = require('../../utils/shared-props'); + +var _sharedDefaultProps = require('../../utils/shared-default-props'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const _getData = props => { + var { emoji, skin, set, data } = props; + return (0, _utils.getData)(emoji, skin, set, data); +}; + +const _getPosition = props => { + var { sheet_x, sheet_y } = _getData(props), + multiplyX = 100 / (props.sheetColumns - 1), + multiplyY = 100 / (props.sheetRows - 1); + + return `${multiplyX * sheet_x}% ${multiplyY * sheet_y}%`; +}; + +const _getSanitizedData = props => { + var { emoji, skin, set, data } = props; + return (0, _utils.getSanitizedData)(emoji, skin, set, data); +}; + +const _handleClick = (e, props) => { + if (!props.onClick) { + return; + } + var { onClick } = props, + emoji = _getSanitizedData(props); + + onClick(emoji, e); +}; + +const _handleOver = (e, props) => { + if (!props.onOver) { + return; + } + var { onOver } = props, + emoji = _getSanitizedData(props); + + onOver(emoji, e); +}; + +const _handleLeave = (e, props) => { + if (!props.onLeave) { + return; + } + var { onLeave } = props, + emoji = _getSanitizedData(props); + + onLeave(emoji, e); +}; + +const _isNumeric = value => { + return !isNaN(value - parseFloat(value)); +}; + +const _convertStyleToCSS = style => { + let div = document.createElement('div'); + + for (let key in style) { + let value = style[key]; + + if (_isNumeric(value)) { + value += 'px'; + } + + div.style[key] = value; + } + + return div.getAttribute('style'); +}; + +const NimbleEmoji = props => { + if (props.data.compressed) { + (0, _data.uncompress)(props.data); + } + + for (let k in NimbleEmoji.defaultProps) { + if (props[k] == undefined && NimbleEmoji.defaultProps[k] != undefined) { + props[k] = NimbleEmoji.defaultProps[k]; + } + } + + let data = _getData(props); + if (!data) { + if (props.fallback) { + return props.fallback(null, props); + } else { + return null; + } + } + + let { unified, custom, short_names, imageUrl } = data, + style = {}, + children = props.children, + className = 'emoji-mart-emoji', + title = null; + + if (!unified && !custom) { + if (props.fallback) { + return props.fallback(data, props); + } else { + return null; + } + } + + if (props.tooltip) { + title = short_names[0]; + } + + if (props.native && unified) { + className += ' emoji-mart-emoji-native'; + style = { fontSize: props.size }; + children = (0, _utils.unifiedToNative)(unified); + + if (props.forceSize) { + style.display = 'inline-block'; + style.width = props.size; + style.height = props.size; + style.wordBreak = 'keep-all'; + } + } else if (custom) { + className += ' emoji-mart-emoji-custom'; + style = { + width: props.size, + height: props.size, + display: 'inline-block' + }; + if (data.spriteUrl) { + style = (0, _extends3.default)({}, style, { + backgroundImage: `url(${data.spriteUrl})`, + backgroundSize: `${100 * props.sheetColumns}% ${100 * props.sheetRows}%`, + backgroundPosition: _getPosition(props) + }); + } else { + style = (0, _extends3.default)({}, style, { + backgroundImage: `url(${imageUrl})`, + backgroundSize: 'contain' + }); + } + } else { + let setHasEmoji = data[`has_img_${props.set}`] == undefined || data[`has_img_${props.set}`]; + + if (!setHasEmoji) { + if (props.fallback) { + return props.fallback(data, props); + } else { + return null; + } + } else { + style = { + width: props.size, + height: props.size, + display: 'inline-block', + backgroundImage: `url(${props.backgroundImageFn(props.set, props.sheetSize)})`, + backgroundSize: `${100 * props.sheetColumns}% ${100 * props.sheetRows}%`, + backgroundPosition: _getPosition(props) + }; + } + } + + if (props.html) { + style = _convertStyleToCSS(style); + return ``; + } else { + return _react2.default.createElement( + 'button', + { + key: props.emoji.id || props.emoji, + onClick: e => _handleClick(e, props), + onMouseEnter: e => _handleOver(e, props), + onMouseLeave: e => _handleLeave(e, props), + title: title, + className: className + }, + _react2.default.createElement( + 'span', + { style: style }, + children + ) + ); + } +}; + +NimbleEmoji.propTypes /* remove-proptypes */ = (0, _extends3.default)({}, _sharedProps.EmojiPropTypes, { + data: _propTypes2.default.object.isRequired +}); +NimbleEmoji.defaultProps = _sharedDefaultProps.EmojiDefaultProps; + +exports.default = NimbleEmoji; \ No newline at end of file diff --git a/dist/components/not-found.js b/dist/components/not-found.js new file mode 100644 index 000000000..98dc2b53e --- /dev/null +++ b/dist/components/not-found.js @@ -0,0 +1,56 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends2 = require('../polyfills/extends'); + +var _extends3 = _interopRequireDefault(_extends2); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _nimbleEmoji = require('./emoji/nimble-emoji'); + +var _nimbleEmoji2 = _interopRequireDefault(_nimbleEmoji); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class NotFound extends _react2.default.PureComponent { + render() { + const { data, emojiProps, i18n, notFound, notFoundEmoji } = this.props; + + const component = notFound && notFound() || _react2.default.createElement( + 'div', + { className: 'emoji-mart-no-results' }, + (0, _nimbleEmoji2.default)((0, _extends3.default)({ + data: data + }, emojiProps, { + size: 38, + emoji: notFoundEmoji, + onOver: null, + onLeave: null, + onClick: null + })), + _react2.default.createElement( + 'div', + { className: 'emoji-mart-no-results-label' }, + i18n.notfound + ) + ); + + return component; + } +} + +exports.default = NotFound; +NotFound.propTypes /* remove-proptypes */ = { + notFound: _propTypes2.default.func.isRequired, + emojiProps: _propTypes2.default.object.isRequired +}; \ No newline at end of file diff --git a/dist/components/picker/nimble-picker.js b/dist/components/picker/nimble-picker.js new file mode 100644 index 000000000..2bb6d7095 --- /dev/null +++ b/dist/components/picker/nimble-picker.js @@ -0,0 +1,620 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends2 = require('../../polyfills/extends'); + +var _extends3 = _interopRequireDefault(_extends2); + +require('../../vendor/raf-polyfill'); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _svgs = require('../../svgs'); + +var icons = _interopRequireWildcard(_svgs); + +var _store = require('../../utils/store'); + +var _store2 = _interopRequireDefault(_store); + +var _frequently = require('../../utils/frequently'); + +var _frequently2 = _interopRequireDefault(_frequently); + +var _utils = require('../../utils'); + +var _data = require('../../utils/data'); + +var _sharedProps = require('../../utils/shared-props'); + +var _anchors = require('../anchors'); + +var _anchors2 = _interopRequireDefault(_anchors); + +var _category = require('../category'); + +var _category2 = _interopRequireDefault(_category); + +var _preview = require('../preview'); + +var _preview2 = _interopRequireDefault(_preview); + +var _search = require('../search'); + +var _search2 = _interopRequireDefault(_search); + +var _sharedDefaultProps = require('../../utils/shared-default-props'); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const I18N = { + search: 'Search', + clear: 'Clear', // Accessible label on "clear" button + emojilist: 'List of emoji', + notfound: 'No Emoji Found', + skintext: 'Choose your default skin tone', + categories: { + search: 'Search Results', + recent: 'Frequently Used', + people: 'Smileys & People', + nature: 'Animals & Nature', + foods: 'Food & Drink', + activity: 'Activity', + places: 'Travel & Places', + objects: 'Objects', + symbols: 'Symbols', + flags: 'Flags', + custom: 'Custom' + }, + categorieslabel: 'Emoji categories', // Accessible title for the list of categories + skintones: { + 1: 'Default Skin Tone', + 2: 'Light Skin Tone', + 3: 'Medium-Light Skin Tone', + 4: 'Medium Skin Tone', + 5: 'Medium-Dark Skin Tone', + 6: 'Dark Skin Tone' + } +}; + +class NimblePicker extends _react2.default.PureComponent { + constructor(props) { + super(props); + + this.RECENT_CATEGORY = { id: 'recent', name: 'Recent', emojis: null }; + this.CUSTOM_CATEGORY = { id: 'custom', name: 'Custom', emojis: [] }; + this.SEARCH_CATEGORY = { + id: 'search', + name: 'Search', + emojis: null, + anchor: false + }; + + if (props.data.compressed) { + (0, _data.uncompress)(props.data); + } + + this.data = props.data; + this.i18n = (0, _utils.deepMerge)(I18N, props.i18n); + this.icons = (0, _utils.deepMerge)(icons, props.icons); + this.state = { + skin: props.skin || _store2.default.get('skin') || props.defaultSkin, + firstRender: true + }; + + this.categories = []; + let allCategories = [].concat(this.data.categories); + + if (props.custom.length > 0) { + this.CUSTOM_CATEGORY.emojis = props.custom.map(emoji => { + return (0, _extends3.default)({}, emoji, { + // `` expects emoji to have an `id`. + id: emoji.short_names[0], + custom: true + }); + }); + + allCategories.push(this.CUSTOM_CATEGORY); + } + + this.hideRecent = true; + + if (props.include != undefined) { + allCategories.sort((a, b) => { + if (props.include.indexOf(a.id) > props.include.indexOf(b.id)) { + return 1; + } + + return -1; + }); + } + + for (let categoryIndex = 0; categoryIndex < allCategories.length; categoryIndex++) { + const category = allCategories[categoryIndex]; + let isIncluded = props.include && props.include.length ? props.include.indexOf(category.id) > -1 : true; + let isExcluded = props.exclude && props.exclude.length ? props.exclude.indexOf(category.id) > -1 : false; + if (!isIncluded || isExcluded) { + continue; + } + + if (props.emojisToShowFilter) { + let newEmojis = []; + + const { emojis } = category; + for (let emojiIndex = 0; emojiIndex < emojis.length; emojiIndex++) { + const emoji = emojis[emojiIndex]; + if (props.emojisToShowFilter(this.data.emojis[emoji] || emoji)) { + newEmojis.push(emoji); + } + } + + if (newEmojis.length) { + let newCategory = { + emojis: newEmojis, + name: category.name, + id: category.id + }; + + this.categories.push(newCategory); + } + } else { + this.categories.push(category); + } + } + + let includeRecent = props.include && props.include.length ? props.include.indexOf(this.RECENT_CATEGORY.id) > -1 : true; + let excludeRecent = props.exclude && props.exclude.length ? props.exclude.indexOf(this.RECENT_CATEGORY.id) > -1 : false; + if (includeRecent && !excludeRecent) { + this.hideRecent = false; + this.categories.unshift(this.RECENT_CATEGORY); + } + + if (this.categories[0]) { + this.categories[0].first = true; + } + + this.categories.unshift(this.SEARCH_CATEGORY); + + this.setAnchorsRef = this.setAnchorsRef.bind(this); + this.handleAnchorClick = this.handleAnchorClick.bind(this); + this.setSearchRef = this.setSearchRef.bind(this); + this.handleSearch = this.handleSearch.bind(this); + this.setScrollRef = this.setScrollRef.bind(this); + this.handleScroll = this.handleScroll.bind(this); + this.handleScrollPaint = this.handleScrollPaint.bind(this); + this.handleEmojiOver = this.handleEmojiOver.bind(this); + this.handleEmojiLeave = this.handleEmojiLeave.bind(this); + this.handleEmojiClick = this.handleEmojiClick.bind(this); + this.handleEmojiSelect = this.handleEmojiSelect.bind(this); + this.setPreviewRef = this.setPreviewRef.bind(this); + this.handleSkinChange = this.handleSkinChange.bind(this); + this.handleKeyDown = this.handleKeyDown.bind(this); + } + + componentWillReceiveProps(props) { + if (props.skin) { + this.setState({ skin: props.skin }); + } else if (props.defaultSkin && !_store2.default.get('skin')) { + this.setState({ skin: props.defaultSkin }); + } + } + + componentDidMount() { + if (this.state.firstRender) { + this.testStickyPosition(); + this.firstRenderTimeout = setTimeout(() => { + this.setState({ firstRender: false }); + }, 60); + } + } + + componentDidUpdate() { + this.updateCategoriesSize(); + this.handleScroll(); + } + + componentWillUnmount() { + this.SEARCH_CATEGORY.emojis = null; + + clearTimeout(this.leaveTimeout); + clearTimeout(this.firstRenderTimeout); + } + + testStickyPosition() { + const stickyTestElement = document.createElement('div'); + + const prefixes = ['', '-webkit-', '-ms-', '-moz-', '-o-']; + + prefixes.forEach(prefix => stickyTestElement.style.position = `${prefix}sticky`); + + this.hasStickyPosition = !!stickyTestElement.style.position.length; + } + + handleEmojiOver(emoji) { + var { preview } = this; + if (!preview) { + return; + } + + // Use Array.prototype.find() when it is more widely supported. + const emojiData = this.CUSTOM_CATEGORY.emojis.filter(customEmoji => customEmoji.id === emoji.id)[0]; + for (let key in emojiData) { + if (emojiData.hasOwnProperty(key)) { + emoji[key] = emojiData[key]; + } + } + + preview.setState({ emoji }); + clearTimeout(this.leaveTimeout); + } + + handleEmojiLeave(emoji) { + var { preview } = this; + if (!preview) { + return; + } + + this.leaveTimeout = setTimeout(() => { + preview.setState({ emoji: null }); + }, 16); + } + + handleEmojiClick(emoji, e) { + this.props.onClick(emoji, e); + this.handleEmojiSelect(emoji); + } + + handleEmojiSelect(emoji) { + this.props.onSelect(emoji); + if (!this.hideRecent && !this.props.recent) _frequently2.default.add(emoji); + + var component = this.categoryRefs['category-1']; + if (component) { + let maxMargin = component.maxMargin; + component.forceUpdate(); + + window.requestAnimationFrame(() => { + if (!this.scroll) return; + component.memoizeSize(); + if (maxMargin == component.maxMargin) return; + + this.updateCategoriesSize(); + this.handleScrollPaint(); + + if (this.SEARCH_CATEGORY.emojis) { + component.updateDisplay('none'); + } + }); + } + } + + handleScroll() { + if (!this.waitingForPaint) { + this.waitingForPaint = true; + window.requestAnimationFrame(this.handleScrollPaint); + } + } + + handleScrollPaint() { + this.waitingForPaint = false; + + if (!this.scroll) { + return; + } + + let activeCategory = null; + + if (this.SEARCH_CATEGORY.emojis) { + activeCategory = this.SEARCH_CATEGORY; + } else { + var target = this.scroll, + scrollTop = target.scrollTop, + scrollingDown = scrollTop > (this.scrollTop || 0), + minTop = 0; + + for (let i = 0, l = this.categories.length; i < l; i++) { + let ii = scrollingDown ? this.categories.length - 1 - i : i, + category = this.categories[ii], + component = this.categoryRefs[`category-${ii}`]; + + if (component) { + let active = component.handleScroll(scrollTop); + + if (!minTop || component.top < minTop) { + if (component.top > 0) { + minTop = component.top; + } + } + + if (active && !activeCategory) { + activeCategory = category; + } + } + } + + if (scrollTop < minTop) { + activeCategory = this.categories.filter(category => !(category.anchor === false))[0]; + } else if (scrollTop + this.clientHeight >= this.scrollHeight) { + activeCategory = this.categories[this.categories.length - 1]; + } + } + + if (activeCategory) { + let { anchors } = this, + { name: categoryName } = activeCategory; + + if (anchors.state.selected != categoryName) { + anchors.setState({ selected: categoryName }); + } + } + + this.scrollTop = scrollTop; + } + + handleSearch(emojis) { + this.SEARCH_CATEGORY.emojis = emojis; + + for (let i = 0, l = this.categories.length; i < l; i++) { + let component = this.categoryRefs[`category-${i}`]; + + if (component && component.props.name != 'Search') { + let display = emojis ? 'none' : 'inherit'; + component.updateDisplay(display); + } + } + + this.forceUpdate(); + this.scroll.scrollTop = 0; + this.handleScroll(); + } + + handleAnchorClick(category, i) { + var component = this.categoryRefs[`category-${i}`], + { scroll, anchors } = this, + scrollToComponent = null; + + scrollToComponent = () => { + if (component) { + let { top } = component; + + if (category.first) { + top = 0; + } else { + top += 1; + } + + scroll.scrollTop = top; + } + }; + + if (this.SEARCH_CATEGORY.emojis) { + this.handleSearch(null); + this.search.clear(); + + window.requestAnimationFrame(scrollToComponent); + } else { + scrollToComponent(); + } + } + + handleSkinChange(skin) { + var newState = { skin: skin }, + { onSkinChange } = this.props; + + this.setState(newState); + _store2.default.update(newState); + + onSkinChange(skin); + } + + handleKeyDown(e) { + let handled = false; + + switch (e.keyCode) { + case 13: + let emoji; + + if (this.SEARCH_CATEGORY.emojis && this.SEARCH_CATEGORY.emojis.length && (emoji = (0, _utils.getSanitizedData)(this.SEARCH_CATEGORY.emojis[0], this.state.skin, this.props.set, this.props.data))) { + this.handleEmojiSelect(emoji); + } + + handled = true; + break; + } + + if (handled) { + e.preventDefault(); + } + } + + updateCategoriesSize() { + for (let i = 0, l = this.categories.length; i < l; i++) { + let component = this.categoryRefs[`category-${i}`]; + if (component) component.memoizeSize(); + } + + if (this.scroll) { + let target = this.scroll; + this.scrollHeight = target.scrollHeight; + this.clientHeight = target.clientHeight; + } + } + + getCategories() { + return this.state.firstRender ? this.categories.slice(0, 3) : this.categories; + } + + setAnchorsRef(c) { + this.anchors = c; + } + + setSearchRef(c) { + this.search = c; + } + + setPreviewRef(c) { + this.preview = c; + } + + setScrollRef(c) { + this.scroll = c; + } + + setCategoryRef(name, c) { + if (!this.categoryRefs) { + this.categoryRefs = {}; + } + + this.categoryRefs[name] = c; + } + + render() { + var { + perLine, + emojiSize, + set, + sheetSize, + sheetColumns, + sheetRows, + style, + title, + emoji, + color, + native, + backgroundImageFn, + emojisToShowFilter, + showPreview, + showSkinTones, + emojiTooltip, + include, + exclude, + recent, + autoFocus, + skinEmoji, + notFound, + notFoundEmoji + } = this.props, + { skin } = this.state, + width = perLine * (emojiSize + 12) + 12 + 2 + (0, _utils.measureScrollbar)(); + + return _react2.default.createElement( + 'div', + { + style: (0, _extends3.default)({ width: width }, style), + className: 'emoji-mart', + onKeyDown: this.handleKeyDown + }, + _react2.default.createElement( + 'div', + { className: 'emoji-mart-bar' }, + _react2.default.createElement(_anchors2.default, { + ref: this.setAnchorsRef, + data: this.data, + i18n: this.i18n, + color: color, + categories: this.categories, + onAnchorClick: this.handleAnchorClick, + icons: this.icons + }) + ), + _react2.default.createElement(_search2.default, { + ref: this.setSearchRef, + onSearch: this.handleSearch, + data: this.data, + i18n: this.i18n, + emojisToShowFilter: emojisToShowFilter, + include: include, + exclude: exclude, + custom: this.CUSTOM_CATEGORY.emojis, + autoFocus: autoFocus + }), + _react2.default.createElement( + 'section', + { + ref: this.setScrollRef, + className: 'emoji-mart-scroll', + 'aria-label': this.i18n.emojilist, + onScroll: this.handleScroll + }, + this.getCategories().map((category, i) => { + return _react2.default.createElement(_category2.default, { + ref: this.setCategoryRef.bind(this, `category-${i}`), + key: category.name, + id: category.id, + name: category.name, + emojis: category.emojis, + perLine: perLine, + native: native, + hasStickyPosition: this.hasStickyPosition, + data: this.data, + i18n: this.i18n, + recent: category.id == this.RECENT_CATEGORY.id ? recent : undefined, + custom: category.id == this.RECENT_CATEGORY.id ? this.CUSTOM_CATEGORY.emojis : undefined, + emojiProps: { + native: native, + skin: skin, + size: emojiSize, + set: set, + sheetSize: sheetSize, + sheetColumns: sheetColumns, + sheetRows: sheetRows, + forceSize: native, + tooltip: emojiTooltip, + backgroundImageFn: backgroundImageFn, + onOver: this.handleEmojiOver, + onLeave: this.handleEmojiLeave, + onClick: this.handleEmojiClick + }, + notFound: notFound, + notFoundEmoji: notFoundEmoji + }); + }) + ), + (showPreview || showSkinTones) && _react2.default.createElement( + 'div', + { className: 'emoji-mart-bar' }, + _react2.default.createElement(_preview2.default, { + ref: this.setPreviewRef, + data: this.data, + title: title, + emoji: emoji, + showSkinTones: showSkinTones, + showPreview: showPreview, + emojiProps: { + native: native, + size: 38, + skin: skin, + set: set, + sheetSize: sheetSize, + sheetColumns: sheetColumns, + sheetRows: sheetRows, + backgroundImageFn: backgroundImageFn + }, + skinsProps: { + skin: skin, + onChange: this.handleSkinChange, + skinEmoji: skinEmoji + }, + i18n: this.i18n + }) + ) + ); + } +} + +exports.default = NimblePicker; +NimblePicker.propTypes /* remove-proptypes */ = (0, _extends3.default)({}, _sharedProps.PickerPropTypes, { + data: _propTypes2.default.object.isRequired +}); +NimblePicker.defaultProps = (0, _extends3.default)({}, _sharedDefaultProps.PickerDefaultProps); \ No newline at end of file diff --git a/dist/components/picker/picker.js b/dist/components/picker/picker.js new file mode 100644 index 000000000..f401ba346 --- /dev/null +++ b/dist/components/picker/picker.js @@ -0,0 +1,37 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends2 = require('../../polyfills/extends'); + +var _extends3 = _interopRequireDefault(_extends2); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _all = require('../../../data/all.json'); + +var _all2 = _interopRequireDefault(_all); + +var _nimblePicker = require('./nimble-picker'); + +var _nimblePicker2 = _interopRequireDefault(_nimblePicker); + +var _sharedProps = require('../../utils/shared-props'); + +var _sharedDefaultProps = require('../../utils/shared-default-props'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Picker extends _react2.default.PureComponent { + render() { + return _react2.default.createElement(_nimblePicker2.default, (0, _extends3.default)({}, this.props, this.state)); + } +} + +exports.default = Picker; +Picker.propTypes /* remove-proptypes */ = _sharedProps.PickerPropTypes; +Picker.defaultProps = (0, _extends3.default)({}, _sharedDefaultProps.PickerDefaultProps, { data: _all2.default }); \ No newline at end of file diff --git a/dist/components/preview.js b/dist/components/preview.js new file mode 100644 index 000000000..de4934ae6 --- /dev/null +++ b/dist/components/preview.js @@ -0,0 +1,165 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends2 = require('../polyfills/extends'); + +var _extends3 = _interopRequireDefault(_extends2); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _utils = require('../utils'); + +var _nimbleEmoji = require('./emoji/nimble-emoji'); + +var _nimbleEmoji2 = _interopRequireDefault(_nimbleEmoji); + +var _skinsEmoji = require('./skins-emoji'); + +var _skinsEmoji2 = _interopRequireDefault(_skinsEmoji); + +var _skinsDot = require('./skins-dot'); + +var _skinsDot2 = _interopRequireDefault(_skinsDot); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Preview extends _react2.default.PureComponent { + constructor(props) { + super(props); + + this.data = props.data; + this.state = { emoji: null }; + } + + render() { + var { emoji } = this.state, + { + emojiProps, + skinsProps, + showSkinTones, + title, + emoji: idleEmoji, + i18n, + showPreview + } = this.props; + + if (emoji && showPreview) { + var emojiData = (0, _utils.getData)(emoji, null, null, this.data), + { emoticons = [] } = emojiData, + knownEmoticons = [], + listedEmoticons = []; + + emoticons.forEach(emoticon => { + if (knownEmoticons.indexOf(emoticon.toLowerCase()) >= 0) { + return; + } + + knownEmoticons.push(emoticon.toLowerCase()); + listedEmoticons.push(emoticon); + }); + + return _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview' }, + _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview-emoji' }, + (0, _nimbleEmoji2.default)((0, _extends3.default)({ + key: emoji.id, + emoji: emoji, + data: this.data + }, emojiProps)) + ), + _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview-data' }, + _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview-name' }, + emoji.name + ), + _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview-shortnames' }, + emojiData.short_names.map(short_name => _react2.default.createElement( + 'span', + { key: short_name, className: 'emoji-mart-preview-shortname' }, + ':', + short_name, + ':' + )) + ), + _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview-emoticons' }, + listedEmoticons.map(emoticon => _react2.default.createElement( + 'span', + { key: emoticon, className: 'emoji-mart-preview-emoticon' }, + emoticon + )) + ) + ) + ); + } else { + return _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview' }, + _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview-emoji' }, + idleEmoji && idleEmoji.length && (0, _nimbleEmoji2.default)((0, _extends3.default)({ emoji: idleEmoji, data: this.data }, emojiProps)) + ), + _react2.default.createElement( + 'div', + { className: 'emoji-mart-preview-data' }, + _react2.default.createElement( + 'span', + { className: 'emoji-mart-title-label' }, + title + ) + ), + showSkinTones && _react2.default.createElement( + 'div', + { + className: `emoji-mart-preview-skins${skinsProps.skinEmoji ? ' custom' : ''}` + }, + skinsProps.skinEmoji ? _react2.default.createElement(_skinsEmoji2.default, { + skin: skinsProps.skin, + emojiProps: emojiProps, + data: this.data, + skinEmoji: skinsProps.skinEmoji, + i18n: i18n, + onChange: skinsProps.onChange + }) : _react2.default.createElement(_skinsDot2.default, { + skin: skinsProps.skin, + i18n: i18n, + onChange: skinsProps.onChange + }) + ) + ); + } + } +} + +exports.default = Preview; +Preview.propTypes /* remove-proptypes */ = { + showSkinTones: _propTypes2.default.bool, + title: _propTypes2.default.string.isRequired, + emoji: _propTypes2.default.string.isRequired, + emojiProps: _propTypes2.default.object.isRequired, + skinsProps: _propTypes2.default.object.isRequired +}; + +Preview.defaultProps = { + showSkinTones: true, + onChange: () => {} +}; \ No newline at end of file diff --git a/dist/components/search.js b/dist/components/search.js new file mode 100644 index 000000000..1fc90072e --- /dev/null +++ b/dist/components/search.js @@ -0,0 +1,134 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _svgs = require('../svgs'); + +var _nimbleEmojiIndex = require('../utils/emoji-index/nimble-emoji-index'); + +var _nimbleEmojiIndex2 = _interopRequireDefault(_nimbleEmojiIndex); + +var _index = require('../utils/index'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let id = 0; + +class Search extends _react2.default.PureComponent { + constructor(props) { + super(props); + this.state = { + icon: _svgs.search.search, + isSearching: false, + id: ++id + }; + + this.data = props.data; + this.emojiIndex = new _nimbleEmojiIndex2.default(this.data); + this.setRef = this.setRef.bind(this); + this.clear = this.clear.bind(this); + this.handleKeyUp = this.handleKeyUp.bind(this); + + // throttle keyboard input so that typing isn't delayed + this.handleChange = (0, _index.throttleIdleTask)(this.handleChange.bind(this)); + } + + search(value) { + if (value == '') this.setState({ + icon: _svgs.search.search, + isSearching: false + });else this.setState({ + icon: _svgs.search.delete, + isSearching: true + }); + + this.props.onSearch(this.emojiIndex.search(value, { + emojisToShowFilter: this.props.emojisToShowFilter, + maxResults: this.props.maxResults, + include: this.props.include, + exclude: this.props.exclude, + custom: this.props.custom + })); + } + + clear() { + if (this.input.value == '') return; + this.input.value = ''; + this.input.focus(); + this.search(''); + } + + handleChange() { + this.search(this.input.value); + } + + handleKeyUp(e) { + if (e.keyCode === 13) { + this.clear(); + } + } + + setRef(c) { + this.input = c; + } + + render() { + const { i18n, autoFocus } = this.props; + const { icon, isSearching, id } = this.state; + const inputId = `emoji-mart-search-${id}`; + + return _react2.default.createElement( + 'div', + { className: 'emoji-mart-search' }, + _react2.default.createElement('input', { + id: inputId, + ref: this.setRef, + type: 'search', + onChange: this.handleChange, + placeholder: i18n.search, + autoFocus: autoFocus + }), + _react2.default.createElement( + 'label', + { className: 'emoji-mart-sr-only', htmlFor: inputId }, + i18n.search + ), + _react2.default.createElement( + 'button', + { + className: 'emoji-mart-search-icon', + onClick: this.clear, + onKeyUp: this.handleKeyUp, + 'aria-label': i18n.clear, + disabled: !isSearching + }, + icon() + ) + ); + } +} + +exports.default = Search; +Search.propTypes /* remove-proptypes */ = { + onSearch: _propTypes2.default.func, + maxResults: _propTypes2.default.number, + emojisToShowFilter: _propTypes2.default.func, + autoFocus: _propTypes2.default.bool +}; + +Search.defaultProps = { + onSearch: () => {}, + maxResults: 75, + emojisToShowFilter: null, + autoFocus: false +}; \ No newline at end of file diff --git a/dist/components/skins-dot.js b/dist/components/skins-dot.js new file mode 100644 index 000000000..b2699368d --- /dev/null +++ b/dist/components/skins-dot.js @@ -0,0 +1,87 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _skins = require('./skins'); + +var _skins2 = _interopRequireDefault(_skins); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class SkinsDot extends _skins2.default { + constructor(props) { + super(props); + + this.handleClick = this.handleClick.bind(this); + this.handleKeyDown = this.handleKeyDown.bind(this); + } + + handleKeyDown(event) { + // if either enter or space is pressed, then execute + if (event.keyCode === 13 || event.keyCode === 32) { + this.handleClick(event); + } + } + + render() { + const { skin, i18n } = this.props; + const { opened } = this.state; + const skinToneNodes = []; + + for (let skinTone = 1; skinTone <= 6; skinTone++) { + const selected = skinTone === skin; + const visible = opened || selected; + skinToneNodes.push(_react2.default.createElement( + 'span', + { + key: `skin-tone-${skinTone}`, + className: `emoji-mart-skin-swatch${selected ? ' selected' : ''}` + }, + _react2.default.createElement('span', { + onClick: this.handleClick, + onKeyDown: this.handleKeyDown, + role: 'button', + tabindex: visible ? '0' : '', + 'aria-hidden': !visible, + 'aria-pressed': opened ? !!selected : '', + 'aria-haspopup': !!selected, + 'aria-expanded': selected ? opened : '', + 'aria-label': i18n.skintones[skinTone], + title: i18n.skintones[skinTone], + 'data-skin': skinTone, + className: `emoji-mart-skin emoji-mart-skin-tone-${skinTone}` + }) + )); + } + + return _react2.default.createElement( + 'section', + { + className: `emoji-mart-skin-swatches${opened ? ' opened' : ''}`, + 'aria-label': i18n.skintext + }, + skinToneNodes + ); + } +} + +exports.default = SkinsDot; +SkinsDot.propTypes /* remove-proptypes */ = { + onChange: _propTypes2.default.func, + skin: _propTypes2.default.number.isRequired, + i18n: _propTypes2.default.object +}; + +SkinsDot.defaultProps = { + onChange: () => {} +}; \ No newline at end of file diff --git a/dist/components/skins-emoji.js b/dist/components/skins-emoji.js new file mode 100644 index 000000000..1ead44fdd --- /dev/null +++ b/dist/components/skins-emoji.js @@ -0,0 +1,94 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _nimbleEmoji = require('./emoji/nimble-emoji'); + +var _nimbleEmoji2 = _interopRequireDefault(_nimbleEmoji); + +var _skins = require('./skins'); + +var _skins2 = _interopRequireDefault(_skins); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class SkinsEmoji extends _skins2.default { + constructor(props) { + super(props); + + this.handleClick = this.handleClick.bind(this); + } + + render() { + const { skin, emojiProps, data, skinEmoji, i18n } = this.props; + const { opened } = this.state; + const skinToneNodes = []; + + for (let skinTone = 1; skinTone <= 6; skinTone++) { + const selected = skinTone === skin; + skinToneNodes.push(_react2.default.createElement( + 'span', + { + key: `skin-tone-${skinTone}`, + className: `emoji-mart-skin-swatch custom${selected ? ' selected' : ''}` + }, + _react2.default.createElement( + 'span', + { + onClick: this.handleClick, + 'data-skin': skinTone, + className: `emoji-mart-skin-tone-${skinTone}` + }, + (0, _nimbleEmoji2.default)({ + emoji: skinEmoji, + data: data, + skin: skinTone, + backgroundImageFn: emojiProps.backgroundImageFn, + native: emojiProps.native, + set: emojiProps.set, + sheetSize: emojiProps.sheetSize, + size: 23 + }) + ) + )); + } + + return _react2.default.createElement( + 'div', + { + className: `emoji-mart-skin-swatches custom${opened ? ' opened' : ''}` + }, + _react2.default.createElement( + 'div', + { className: `emoji-mart-skin-text${opened ? ' opened' : ''}` }, + i18n.skintext + ), + skinToneNodes + ); + } +} + +exports.default = SkinsEmoji; +SkinsEmoji.propTypes /* remove-proptypes */ = { + onChange: _propTypes2.default.func, + skin: _propTypes2.default.number.isRequired, + emojiProps: _propTypes2.default.object.isRequired, + skinTone: _propTypes2.default.number, + skinEmoji: _propTypes2.default.string.isRequired, + i18n: _propTypes2.default.object +}; + +SkinsEmoji.defaultProps = { + onChange: () => {}, + skinTone: null +}; \ No newline at end of file diff --git a/dist/components/skins.js b/dist/components/skins.js new file mode 100644 index 000000000..16d431be9 --- /dev/null +++ b/dist/components/skins.js @@ -0,0 +1,56 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = require('react'); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _nimbleEmoji = require('./emoji/nimble-emoji'); + +var _nimbleEmoji2 = _interopRequireDefault(_nimbleEmoji); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Skins extends _react2.default.PureComponent { + constructor(props) { + super(props); + this.state = { + opened: false + }; + } + + handleClick(e) { + var skin = parseInt(e.currentTarget.getAttribute('data-skin')); + var { onChange } = this.props; + + if (!this.state.opened) { + this.setState({ opened: true }); + } else { + this.setState({ opened: false }); + if (skin != this.props.skin) { + onChange(skin); + } + } + } + + render() { + return null; + } +} + +exports.default = Skins; +Skins.propTypes /* remove-proptypes */ = { + onChange: _propTypes2.default.func, + skin: _propTypes2.default.number.isRequired +}; + +Skins.defaultProps = { + onChange: () => {} +}; \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 000000000..87ccf54f3 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,88 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _emojiIndex = require('./utils/emoji-index/emoji-index'); + +Object.defineProperty(exports, 'emojiIndex', { + enumerable: true, + get: function () { + return _interopRequireDefault(_emojiIndex).default; + } +}); + +var _nimbleEmojiIndex = require('./utils/emoji-index/nimble-emoji-index'); + +Object.defineProperty(exports, 'NimbleEmojiIndex', { + enumerable: true, + get: function () { + return _interopRequireDefault(_nimbleEmojiIndex).default; + } +}); + +var _store = require('./utils/store'); + +Object.defineProperty(exports, 'store', { + enumerable: true, + get: function () { + return _interopRequireDefault(_store).default; + } +}); + +var _frequently = require('./utils/frequently'); + +Object.defineProperty(exports, 'frequently', { + enumerable: true, + get: function () { + return _interopRequireDefault(_frequently).default; + } +}); + +var _picker = require('./components/picker/picker'); + +Object.defineProperty(exports, 'Picker', { + enumerable: true, + get: function () { + return _interopRequireDefault(_picker).default; + } +}); + +var _nimblePicker = require('./components/picker/nimble-picker'); + +Object.defineProperty(exports, 'NimblePicker', { + enumerable: true, + get: function () { + return _interopRequireDefault(_nimblePicker).default; + } +}); + +var _emoji = require('./components/emoji/emoji'); + +Object.defineProperty(exports, 'Emoji', { + enumerable: true, + get: function () { + return _interopRequireDefault(_emoji).default; + } +}); + +var _nimbleEmoji = require('./components/emoji/nimble-emoji'); + +Object.defineProperty(exports, 'NimbleEmoji', { + enumerable: true, + get: function () { + return _interopRequireDefault(_nimbleEmoji).default; + } +}); + +var _category = require('./components/category'); + +Object.defineProperty(exports, 'Category', { + enumerable: true, + get: function () { + return _interopRequireDefault(_category).default; + } +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/dist/polyfills/classCallCheck.js b/dist/polyfills/classCallCheck.js new file mode 100644 index 000000000..cc7e310f3 --- /dev/null +++ b/dist/polyfills/classCallCheck.js @@ -0,0 +1,11 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } +}; \ No newline at end of file diff --git a/dist/polyfills/createClass.js b/dist/polyfills/createClass.js new file mode 100644 index 000000000..6e2c79130 --- /dev/null +++ b/dist/polyfills/createClass.js @@ -0,0 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +const _Object = Object; + +exports.default = function createClass() { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) descriptor.writable = true; + _Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); \ No newline at end of file diff --git a/dist/polyfills/extends.js b/dist/polyfills/extends.js new file mode 100644 index 000000000..3b304097b --- /dev/null +++ b/dist/polyfills/extends.js @@ -0,0 +1,20 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +const _Object = Object; + +exports.default = _Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; +}; \ No newline at end of file diff --git a/dist/polyfills/inherits.js b/dist/polyfills/inherits.js new file mode 100644 index 000000000..d674d9c26 --- /dev/null +++ b/dist/polyfills/inherits.js @@ -0,0 +1,25 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = inherits; +const _Object = Object; + +function inherits(subClass, superClass) { + if (typeof superClass !== 'function' && superClass !== null) { + throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); + } + + subClass.prototype = _Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) { + _Object.setPrototypeOf ? _Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } +} \ No newline at end of file diff --git a/dist/polyfills/keys.js b/dist/polyfills/keys.js new file mode 100644 index 000000000..e05712989 --- /dev/null +++ b/dist/polyfills/keys.js @@ -0,0 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (obj) { + if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) { + throw new TypeError('Object.keys called on non-object'); + } + + var result = [], + prop, + i; + + for (prop in obj) { + if (hasOwnProperty.call(obj, prop)) { + result.push(prop); + } + } + + if (hasDontEnumBug) { + for (i = 0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) { + result.push(dontEnums[i]); + } + } + } + return result; +}; + +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys +var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !{ toString: null }.propertyIsEnumerable('toString'), + dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'], + dontEnumsLength = dontEnums.length; \ No newline at end of file diff --git a/dist/polyfills/objectGetPrototypeOf.js b/dist/polyfills/objectGetPrototypeOf.js new file mode 100644 index 000000000..8062f3396 --- /dev/null +++ b/dist/polyfills/objectGetPrototypeOf.js @@ -0,0 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +const _Object = Object; + +exports.default = _Object.getPrototypeOf || function (O) { + O = Object(O); + + if (typeof O.constructor === 'function' && O instanceof O.constructor) { + return O.constructor.prototype; + } + + return O instanceof Object ? Object.prototype : null; +}; \ No newline at end of file diff --git a/dist/polyfills/possibleConstructorReturn.js b/dist/polyfills/possibleConstructorReturn.js new file mode 100644 index 000000000..90d1954bb --- /dev/null +++ b/dist/polyfills/possibleConstructorReturn.js @@ -0,0 +1,13 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = possibleConstructorReturn; +function possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === 'object' || typeof call === 'function') ? call : self; +} \ No newline at end of file diff --git a/dist/polyfills/stringFromCodePoint.js b/dist/polyfills/stringFromCodePoint.js new file mode 100644 index 000000000..fb8f0c977 --- /dev/null +++ b/dist/polyfills/stringFromCodePoint.js @@ -0,0 +1,45 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +const _String = String; + +exports.default = _String.fromCodePoint || function stringFromCodePoint() { + var MAX_SIZE = 0x4000; + var codeUnits = []; + var highSurrogate; + var lowSurrogate; + var index = -1; + var length = arguments.length; + if (!length) { + return ''; + } + var result = ''; + while (++index < length) { + var codePoint = Number(arguments[index]); + if (!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity` + codePoint < 0 || // not a valid Unicode code point + codePoint > 0x10ffff || // not a valid Unicode code point + Math.floor(codePoint) != codePoint // not an integer + ) { + throw RangeError('Invalid code point: ' + codePoint); + } + if (codePoint <= 0xffff) { + // BMP code point + codeUnits.push(codePoint); + } else { + // Astral code point; split in surrogate halves + // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + codePoint -= 0x10000; + highSurrogate = (codePoint >> 10) + 0xd800; + lowSurrogate = codePoint % 0x400 + 0xdc00; + codeUnits.push(highSurrogate, lowSurrogate); + } + if (index + 1 === length || codeUnits.length > MAX_SIZE) { + result += String.fromCharCode.apply(null, codeUnits); + codeUnits.length = 0; + } + } + return result; +}; \ No newline at end of file diff --git a/dist/svgs/index.js b/dist/svgs/index.js new file mode 100644 index 000000000..a2236a468 --- /dev/null +++ b/dist/svgs/index.js @@ -0,0 +1,180 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.search = exports.categories = undefined; + +var _react = require("react"); + +var _react2 = _interopRequireDefault(_react); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const categories = { + activity: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M12 0C5.373 0 0 5.372 0 12c0 6.627 5.373 12 12 12 6.628 0 12-5.373 12-12 0-6.628-5.372-12-12-12m9.949 11H17.05c.224-2.527 1.232-4.773 1.968-6.113A9.966 9.966 0 0 1 21.949 11M13 11V2.051a9.945 9.945 0 0 1 4.432 1.564c-.858 1.491-2.156 4.22-2.392 7.385H13zm-2 0H8.961c-.238-3.165-1.536-5.894-2.393-7.385A9.95 9.95 0 0 1 11 2.051V11zm0 2v8.949a9.937 9.937 0 0 1-4.432-1.564c.857-1.492 2.155-4.221 2.393-7.385H11zm4.04 0c.236 3.164 1.534 5.893 2.392 7.385A9.92 9.92 0 0 1 13 21.949V13h2.04zM4.982 4.887C5.718 6.227 6.726 8.473 6.951 11h-4.9a9.977 9.977 0 0 1 2.931-6.113M2.051 13h4.9c-.226 2.527-1.233 4.771-1.969 6.113A9.972 9.972 0 0 1 2.051 13m16.967 6.113c-.735-1.342-1.744-3.586-1.968-6.113h4.899a9.961 9.961 0 0 1-2.931 6.113" }) + ), + + custom: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement( + "g", + { transform: "translate(2.000000, 1.000000)" }, + _react2.default.createElement("rect", { id: "Rectangle", x: "8", y: "0", width: "3", height: "21", rx: "1.5" }), + _react2.default.createElement("rect", { + id: "Rectangle", + transform: "translate(9.843, 10.549) rotate(60) translate(-9.843, -10.549) ", + x: "8.343", + y: "0.049", + width: "3", + height: "21", + rx: "1.5" + }), + _react2.default.createElement("rect", { + id: "Rectangle", + transform: "translate(9.843, 10.549) rotate(-60) translate(-9.843, -10.549) ", + x: "8.343", + y: "0.049", + width: "3", + height: "21", + rx: "1.5" + }) + ) + ), + + flags: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M0 0l6.084 24H8L1.916 0zM21 5h-4l-1-4H4l3 12h3l1 4h13L21 5zM6.563 3h7.875l2 8H8.563l-2-8zm8.832 10l-2.856 1.904L12.063 13h3.332zM19 13l-1.5-6h1.938l2 8H16l3-2z" }) + ), + + foods: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M17 4.978c-1.838 0-2.876.396-3.68.934.513-1.172 1.768-2.934 4.68-2.934a1 1 0 0 0 0-2c-2.921 0-4.629 1.365-5.547 2.512-.064.078-.119.162-.18.244C11.73 1.838 10.798.023 9.207.023 8.579.022 7.85.306 7 .978 5.027 2.54 5.329 3.902 6.492 4.999 3.609 5.222 0 7.352 0 12.969c0 4.582 4.961 11.009 9 11.009 1.975 0 2.371-.486 3-1 .629.514 1.025 1 3 1 4.039 0 9-6.418 9-11 0-5.953-4.055-8-7-8M8.242 2.546c.641-.508.943-.523.965-.523.426.169.975 1.405 1.357 3.055-1.527-.629-2.741-1.352-2.98-1.846.059-.112.241-.356.658-.686M15 21.978c-1.08 0-1.21-.109-1.559-.402l-.176-.146c-.367-.302-.816-.452-1.266-.452s-.898.15-1.266.452l-.176.146c-.347.292-.477.402-1.557.402-2.813 0-7-5.389-7-9.009 0-5.823 4.488-5.991 5-5.991 1.939 0 2.484.471 3.387 1.251l.323.276a1.995 1.995 0 0 0 2.58 0l.323-.276c.902-.78 1.447-1.251 3.387-1.251.512 0 5 .168 5 6 0 3.617-4.187 9-7 9" }) + ), + + nature: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M15.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 15.5 8M8.5 8a1.5 1.5 0 1 0 .001 3.001A1.5 1.5 0 0 0 8.5 8" }), + _react2.default.createElement("path", { d: "M18.933 0h-.027c-.97 0-2.138.787-3.018 1.497-1.274-.374-2.612-.51-3.887-.51-1.285 0-2.616.133-3.874.517C7.245.79 6.069 0 5.093 0h-.027C3.352 0 .07 2.67.002 7.026c-.039 2.479.276 4.238 1.04 5.013.254.258.882.677 1.295.882.191 3.177.922 5.238 2.536 6.38.897.637 2.187.949 3.2 1.102C8.04 20.6 8 20.795 8 21c0 1.773 2.35 3 4 3 1.648 0 4-1.227 4-3 0-.201-.038-.393-.072-.586 2.573-.385 5.435-1.877 5.925-7.587.396-.22.887-.568 1.104-.788.763-.774 1.079-2.534 1.04-5.013C23.929 2.67 20.646 0 18.933 0M3.223 9.135c-.237.281-.837 1.155-.884 1.238-.15-.41-.368-1.349-.337-3.291.051-3.281 2.478-4.972 3.091-5.031.256.015.731.27 1.265.646-1.11 1.171-2.275 2.915-2.352 5.125-.133.546-.398.858-.783 1.313M12 22c-.901 0-1.954-.693-2-1 0-.654.475-1.236 1-1.602V20a1 1 0 1 0 2 0v-.602c.524.365 1 .947 1 1.602-.046.307-1.099 1-2 1m3-3.48v.02a4.752 4.752 0 0 0-1.262-1.02c1.092-.516 2.239-1.334 2.239-2.217 0-1.842-1.781-2.195-3.977-2.195-2.196 0-3.978.354-3.978 2.195 0 .883 1.148 1.701 2.238 2.217A4.8 4.8 0 0 0 9 18.539v-.025c-1-.076-2.182-.281-2.973-.842-1.301-.92-1.838-3.045-1.853-6.478l.023-.041c.496-.826 1.49-1.45 1.804-3.102 0-2.047 1.357-3.631 2.362-4.522C9.37 3.178 10.555 3 11.948 3c1.447 0 2.685.192 3.733.57 1 .9 2.316 2.465 2.316 4.48.313 1.651 1.307 2.275 1.803 3.102.035.058.068.117.102.178-.059 5.967-1.949 7.01-4.902 7.19m6.628-8.202c-.037-.065-.074-.13-.113-.195a7.587 7.587 0 0 0-.739-.987c-.385-.455-.648-.768-.782-1.313-.076-2.209-1.241-3.954-2.353-5.124.531-.376 1.004-.63 1.261-.647.636.071 3.044 1.764 3.096 5.031.027 1.81-.347 3.218-.37 3.235" }) + ), + + objects: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M12 0a9 9 0 0 0-5 16.482V21s2.035 3 5 3 5-3 5-3v-4.518A9 9 0 0 0 12 0zm0 2c3.86 0 7 3.141 7 7s-3.14 7-7 7-7-3.141-7-7 3.14-7 7-7zM9 17.477c.94.332 1.946.523 3 .523s2.06-.19 3-.523v.834c-.91.436-1.925.689-3 .689a6.924 6.924 0 0 1-3-.69v-.833zm.236 3.07A8.854 8.854 0 0 0 12 21c.965 0 1.888-.167 2.758-.451C14.155 21.173 13.153 22 12 22c-1.102 0-2.117-.789-2.764-1.453z" }), + _react2.default.createElement("path", { d: "M14.745 12.449h-.004c-.852-.024-1.188-.858-1.577-1.824-.421-1.061-.703-1.561-1.182-1.566h-.009c-.481 0-.783.497-1.235 1.537-.436.982-.801 1.811-1.636 1.791l-.276-.043c-.565-.171-.853-.691-1.284-1.794-.125-.313-.202-.632-.27-.913-.051-.213-.127-.53-.195-.634C7.067 9.004 7.039 9 6.99 9A1 1 0 0 1 7 7h.01c1.662.017 2.015 1.373 2.198 2.134.486-.981 1.304-2.058 2.797-2.075 1.531.018 2.28 1.153 2.731 2.141l.002-.008C14.944 8.424 15.327 7 16.979 7h.032A1 1 0 1 1 17 9h-.011c-.149.076-.256.474-.319.709a6.484 6.484 0 0 1-.311.951c-.429.973-.79 1.789-1.614 1.789" }) + ), + + people: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10" }), + _react2.default.createElement("path", { d: "M8 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 8 7M16 7a2 2 0 1 0-.001 3.999A2 2 0 0 0 16 7M15.232 15c-.693 1.195-1.87 2-3.349 2-1.477 0-2.655-.805-3.347-2H15m3-2H6a6 6 0 1 0 12 0" }) + ), + + places: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M6.5 12C5.122 12 4 13.121 4 14.5S5.122 17 6.5 17 9 15.879 9 14.5 7.878 12 6.5 12m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5M17.5 12c-1.378 0-2.5 1.121-2.5 2.5s1.122 2.5 2.5 2.5 2.5-1.121 2.5-2.5-1.122-2.5-2.5-2.5m0 3c-.275 0-.5-.225-.5-.5s.225-.5.5-.5.5.225.5.5-.225.5-.5.5" }), + _react2.default.createElement("path", { d: "M22.482 9.494l-1.039-.346L21.4 9h.6c.552 0 1-.439 1-.992 0-.006-.003-.008-.003-.008H23c0-1-.889-2-1.984-2h-.642l-.731-1.717C19.262 3.012 18.091 2 16.764 2H7.236C5.909 2 4.738 3.012 4.357 4.283L3.626 6h-.642C1.889 6 1 7 1 8h.003S1 8.002 1 8.008C1 8.561 1.448 9 2 9h.6l-.043.148-1.039.346a2.001 2.001 0 0 0-1.359 2.097l.751 7.508a1 1 0 0 0 .994.901H3v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h6v1c0 1.103.896 2 2 2h2c1.104 0 2-.897 2-2v-1h1.096a.999.999 0 0 0 .994-.901l.751-7.508a2.001 2.001 0 0 0-1.359-2.097M6.273 4.857C6.402 4.43 6.788 4 7.236 4h9.527c.448 0 .834.43.963.857L19.313 9H4.688l1.585-4.143zM7 21H5v-1h2v1zm12 0h-2v-1h2v1zm2.189-3H2.811l-.662-6.607L3 11h18l.852.393L21.189 18z" }) + ), + + recent: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M13 4h-2l-.001 7H9v2h2v2h2v-2h4v-2h-4z" }), + _react2.default.createElement("path", { d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0m0 22C6.486 22 2 17.514 2 12S6.486 2 12 2s10 4.486 10 10-4.486 10-10 10" }) + ), + + symbols: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24", + width: "24", + height: "24" + }, + _react2.default.createElement("path", { d: "M0 0h11v2H0zM4 11h3V6h4V4H0v2h4zM15.5 17c1.381 0 2.5-1.116 2.5-2.493s-1.119-2.493-2.5-2.493S13 13.13 13 14.507 14.119 17 15.5 17m0-2.986c.276 0 .5.222.5.493 0 .272-.224.493-.5.493s-.5-.221-.5-.493.224-.493.5-.493M21.5 19.014c-1.381 0-2.5 1.116-2.5 2.493S20.119 24 21.5 24s2.5-1.116 2.5-2.493-1.119-2.493-2.5-2.493m0 2.986a.497.497 0 0 1-.5-.493c0-.271.224-.493.5-.493s.5.222.5.493a.497.497 0 0 1-.5.493M22 13l-9 9 1.513 1.5 8.99-9.009zM17 11c2.209 0 4-1.119 4-2.5V2s.985-.161 1.498.949C23.01 4.055 23 6 23 6s1-1.119 1-3.135C24-.02 21 0 21 0h-2v6.347A5.853 5.853 0 0 0 17 6c-2.209 0-4 1.119-4 2.5s1.791 2.5 4 2.5M10.297 20.482l-1.475-1.585a47.54 47.54 0 0 1-1.442 1.129c-.307-.288-.989-1.016-2.045-2.183.902-.836 1.479-1.466 1.729-1.892s.376-.871.376-1.336c0-.592-.273-1.178-.818-1.759-.546-.581-1.329-.871-2.349-.871-1.008 0-1.79.293-2.344.879-.556.587-.832 1.181-.832 1.784 0 .813.419 1.748 1.256 2.805-.847.614-1.444 1.208-1.794 1.784a3.465 3.465 0 0 0-.523 1.833c0 .857.308 1.56.924 2.107.616.549 1.423.823 2.42.823 1.173 0 2.444-.379 3.813-1.137L8.235 24h2.819l-2.09-2.383 1.333-1.135zm-6.736-6.389a1.02 1.02 0 0 1 .73-.286c.31 0 .559.085.747.254a.849.849 0 0 1 .283.659c0 .518-.419 1.112-1.257 1.784-.536-.651-.805-1.231-.805-1.742a.901.901 0 0 1 .302-.669M3.74 22c-.427 0-.778-.116-1.057-.349-.279-.232-.418-.487-.418-.766 0-.594.509-1.288 1.527-2.083.968 1.134 1.717 1.946 2.248 2.438-.921.507-1.686.76-2.3.76" }) + ) +}; + +const search = { + search: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "13", + height: "13", + viewBox: "0 0 20 20", + opacity: "0.5" + }, + _react2.default.createElement("path", { d: "M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z" }) + ), + + delete: () => _react2.default.createElement( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "13", + height: "13", + viewBox: "0 0 20 20", + opacity: "0.5" + }, + _react2.default.createElement("path", { d: "M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z" }) + ) +}; + +exports.categories = categories; +exports.search = search; \ No newline at end of file diff --git a/dist/utils/data.js b/dist/utils/data.js new file mode 100644 index 000000000..05af28931 --- /dev/null +++ b/dist/utils/data.js @@ -0,0 +1,113 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +const mapping = { + name: 'a', + unified: 'b', + non_qualified: 'c', + has_img_apple: 'd', + has_img_google: 'e', + has_img_twitter: 'f', + has_img_emojione: 'g', + has_img_facebook: 'h', + has_img_messenger: 'i', + keywords: 'j', + sheet: 'k', + emoticons: 'l', + text: 'm', + short_names: 'n', + added_in: 'o' +}; + +const buildSearch = emoji => { + const search = []; + + var addToSearch = (strings, split) => { + if (!strings) { + return; + } + + ;(Array.isArray(strings) ? strings : [strings]).forEach(string => { + ;(split ? string.split(/[-|_|\s]+/) : [string]).forEach(s => { + s = s.toLowerCase(); + + if (search.indexOf(s) == -1) { + search.push(s); + } + }); + }); + }; + + addToSearch(emoji.short_names, true); + addToSearch(emoji.name, true); + addToSearch(emoji.keywords, false); + addToSearch(emoji.emoticons, false); + + return search.join(','); +}; + +const compress = emoji => { + emoji.short_names = emoji.short_names.filter(short_name => { + return short_name !== emoji.short_name; + }); + delete emoji.short_name; + + emoji.sheet = [emoji.sheet_x, emoji.sheet_y]; + delete emoji.sheet_x; + delete emoji.sheet_y; + + emoji.added_in = parseInt(emoji.added_in); + if (emoji.added_in === 6) { + delete emoji.added_in; + } + + for (let key in mapping) { + emoji[mapping[key]] = emoji[key]; + delete emoji[key]; + } + + for (let key in emoji) { + let value = emoji[key]; + + if (Array.isArray(value) && !value.length) { + delete emoji[key]; + } else if (typeof value === 'string' && !value.length) { + delete emoji[key]; + } else if (value === null) { + delete emoji[key]; + } + } +}; + +const uncompress = data => { + data.compressed = false; + + for (let id in data.emojis) { + let emoji = data.emojis[id]; + + for (let key in mapping) { + emoji[key] = emoji[mapping[key]]; + delete emoji[mapping[key]]; + } + + if (!emoji.short_names) emoji.short_names = []; + emoji.short_names.unshift(id); + + emoji.sheet_x = emoji.sheet[0]; + emoji.sheet_y = emoji.sheet[1]; + delete emoji.sheet; + + if (!emoji.text) emoji.text = ''; + + if (!emoji.added_in) emoji.added_in = 6; + emoji.added_in = emoji.added_in.toFixed(1); + + emoji.search = buildSearch(emoji); + } +}; + +exports.buildSearch = buildSearch; +exports.compress = compress; +exports.uncompress = uncompress; \ No newline at end of file diff --git a/dist/utils/emoji-index/emoji-index.js b/dist/utils/emoji-index/emoji-index.js new file mode 100644 index 000000000..3627412db --- /dev/null +++ b/dist/utils/emoji-index/emoji-index.js @@ -0,0 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _all = require('../../../data/all.json'); + +var _all2 = _interopRequireDefault(_all); + +var _nimbleEmojiIndex = require('./nimble-emoji-index'); + +var _nimbleEmojiIndex2 = _interopRequireDefault(_nimbleEmojiIndex); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const emojiIndex = new _nimbleEmojiIndex2.default(_all2.default); +const { emojis, emoticons } = emojiIndex; + +function search() { + return emojiIndex.search(...arguments); +} + +exports.default = { search, emojis, emoticons }; \ No newline at end of file diff --git a/dist/utils/emoji-index/nimble-emoji-index.js b/dist/utils/emoji-index/nimble-emoji-index.js new file mode 100644 index 000000000..74ea465c7 --- /dev/null +++ b/dist/utils/emoji-index/nimble-emoji-index.js @@ -0,0 +1,188 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _ = require('..'); + +var _data = require('../data'); + +class NimbleEmojiIndex { + constructor(data) { + if (data.compressed) { + (0, _data.uncompress)(data); + } + + this.data = data || {}; + this.originalPool = {}; + this.index = {}; + this.emojis = {}; + this.emoticons = {}; + this.customEmojisList = []; + + this.buildIndex(); + } + + buildIndex() { + for (let emoji in this.data.emojis) { + let emojiData = this.data.emojis[emoji], + { short_names, emoticons } = emojiData, + id = short_names[0]; + + if (emoticons) { + emoticons.forEach(emoticon => { + if (this.emoticons[emoticon]) { + return; + } + + this.emoticons[emoticon] = id; + }); + } + + this.emojis[id] = (0, _.getSanitizedData)(id, null, null, this.data); + this.originalPool[id] = emojiData; + } + } + + clearCustomEmojis(pool) { + this.customEmojisList.forEach(emoji => { + let emojiId = emoji.id || emoji.short_names[0]; + + delete pool[emojiId]; + delete this.emojis[emojiId]; + }); + } + + addCustomToPool(custom, pool) { + if (this.customEmojisList.length) this.clearCustomEmojis(pool); + + custom.forEach(emoji => { + let emojiId = emoji.id || emoji.short_names[0]; + + if (emojiId && !pool[emojiId]) { + pool[emojiId] = (0, _.getData)(emoji, null, null, this.data); + this.emojis[emojiId] = (0, _.getSanitizedData)(emoji, null, null, this.data); + } + }); + + this.customEmojisList = custom; + this.index = {}; + } + + search(value, { emojisToShowFilter, maxResults, include, exclude, custom = [] } = {}) { + if (this.customEmojisList != custom) this.addCustomToPool(custom, this.originalPool); + + maxResults || (maxResults = 75); + include || (include = []); + exclude || (exclude = []); + + var results = null, + pool = this.originalPool; + + if (value.length) { + if (value == '-' || value == '-1') { + return [this.emojis['-1']]; + } + + var values = value.toLowerCase().split(/[\s|,|\-|_]+/), + allResults = []; + + if (values.length > 2) { + values = [values[0], values[1]]; + } + + if (include.length || exclude.length) { + pool = {}; + + this.data.categories.forEach(category => { + let isIncluded = include && include.length ? include.indexOf(category.id) > -1 : true; + let isExcluded = exclude && exclude.length ? exclude.indexOf(category.id) > -1 : false; + if (!isIncluded || isExcluded) { + return; + } + + category.emojis.forEach(emojiId => pool[emojiId] = this.data.emojis[emojiId]); + }); + + if (custom.length) { + let customIsIncluded = include && include.length ? include.indexOf('custom') > -1 : true; + let customIsExcluded = exclude && exclude.length ? exclude.indexOf('custom') > -1 : false; + if (customIsIncluded && !customIsExcluded) { + this.addCustomToPool(custom, pool); + } + } + } + + allResults = values.map(value => { + var aPool = pool, + aIndex = this.index, + length = 0; + + for (let charIndex = 0; charIndex < value.length; charIndex++) { + const char = value[charIndex]; + length++; + + aIndex[char] || (aIndex[char] = {}); + aIndex = aIndex[char]; + + if (!aIndex.results) { + let scores = {}; + + aIndex.results = []; + aIndex.pool = {}; + + for (let id in aPool) { + let emoji = aPool[id], + { search } = emoji, + sub = value.substr(0, length), + subIndex = search.indexOf(sub); + + if (subIndex != -1) { + let score = subIndex + 1; + if (sub == id) score = 0; + + aIndex.results.push(this.emojis[id]); + aIndex.pool[id] = emoji; + + scores[id] = score; + } + } + + aIndex.results.sort((a, b) => { + var aScore = scores[a.id], + bScore = scores[b.id]; + + return aScore - bScore; + }); + } + + aPool = aIndex.pool; + } + + return aIndex.results; + }).filter(a => a); + + if (allResults.length > 1) { + results = _.intersect.apply(null, allResults); + } else if (allResults.length) { + results = allResults[0]; + } else { + results = []; + } + } + + if (results) { + if (emojisToShowFilter) { + results = results.filter(result => emojisToShowFilter(pool[result.id])); + } + + if (results && results.length > maxResults) { + results = results.slice(0, maxResults); + } + } + + return results; + } +} +exports.default = NimbleEmojiIndex; \ No newline at end of file diff --git a/dist/utils/frequently.js b/dist/utils/frequently.js new file mode 100644 index 000000000..2e37090b5 --- /dev/null +++ b/dist/utils/frequently.js @@ -0,0 +1,72 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _store = require('./store'); + +var _store2 = _interopRequireDefault(_store); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEFAULTS = ['+1', 'grinning', 'kissing_heart', 'heart_eyes', 'laughing', 'stuck_out_tongue_winking_eye', 'sweat_smile', 'joy', 'scream', 'disappointed', 'unamused', 'weary', 'sob', 'sunglasses', 'heart', 'poop']; + +let frequently, initialized; +let defaults = {}; + +function init() { + initialized = true; + frequently = _store2.default.get('frequently'); +} + +function add(emoji) { + if (!initialized) init(); + var { id } = emoji; + + frequently || (frequently = defaults); + frequently[id] || (frequently[id] = 0); + frequently[id] += 1; + + _store2.default.set('last', id); + _store2.default.set('frequently', frequently); +} + +function get(perLine) { + if (!initialized) init(); + if (!frequently) { + defaults = {}; + + const result = []; + + for (let i = 0; i < perLine; i++) { + defaults[DEFAULTS[i]] = perLine - i; + result.push(DEFAULTS[i]); + } + + return result; + } + + const quantity = perLine * 4; + const frequentlyKeys = []; + + for (let key in frequently) { + if (frequently.hasOwnProperty(key)) { + frequentlyKeys.push(key); + } + } + + const sorted = frequentlyKeys.sort((a, b) => frequently[a] - frequently[b]).reverse(); + const sliced = sorted.slice(0, quantity); + + const last = _store2.default.get('last'); + + if (last && sliced.indexOf(last) == -1) { + sliced.pop(); + sliced.push(last); + } + + return sliced; +} + +exports.default = { add, get }; \ No newline at end of file diff --git a/dist/utils/index.js b/dist/utils/index.js new file mode 100644 index 000000000..60fe38c75 --- /dev/null +++ b/dist/utils/index.js @@ -0,0 +1,228 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.throttleIdleTask = exports.measureScrollbar = exports.unifiedToNative = exports.deepMerge = exports.intersect = exports.uniq = exports.getSanitizedData = exports.getData = undefined; + +var _keys = require('../polyfills/keys'); + +var _keys2 = _interopRequireDefault(_keys); + +var _data = require('./data'); + +var _stringFromCodePoint = require('../polyfills/stringFromCodePoint'); + +var _stringFromCodePoint2 = _interopRequireDefault(_stringFromCodePoint); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const _JSON = JSON; + +const COLONS_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/; +const SKINS = ['1F3FA', '1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF']; + +function unifiedToNative(unified) { + var unicodes = unified.split('-'), + codePoints = unicodes.map(u => `0x${u}`); + + return _stringFromCodePoint2.default.apply(null, codePoints); +} + +function sanitize(emoji) { + var { + name, + short_names, + skin_tone, + skin_variations, + emoticons, + unified, + custom, + imageUrl + } = emoji, + id = emoji.id || short_names[0], + colons = `:${id}:`; + + if (custom) { + return { + id, + name, + colons, + emoticons, + custom, + imageUrl + }; + } + + if (skin_tone) { + colons += `:skin-tone-${skin_tone}:`; + } + + return { + id, + name, + colons, + emoticons, + unified: unified.toLowerCase(), + skin: skin_tone || (skin_variations ? 1 : null), + native: unifiedToNative(unified) + }; +} + +function getSanitizedData() { + return sanitize(getData(...arguments)); +} + +function getData(emoji, skin, set, data) { + var emojiData = {}; + + if (typeof emoji == 'string') { + let matches = emoji.match(COLONS_REGEX); + + if (matches) { + emoji = matches[1]; + + if (matches[2]) { + skin = parseInt(matches[2], 10); + } + } + + if (data.aliases.hasOwnProperty(emoji)) { + emoji = data.aliases[emoji]; + } + + if (data.emojis.hasOwnProperty(emoji)) { + emojiData = data.emojis[emoji]; + } else { + return null; + } + } else if (emoji.id) { + if (data.aliases.hasOwnProperty(emoji.id)) { + emoji.id = data.aliases[emoji.id]; + } + + if (data.emojis.hasOwnProperty(emoji.id)) { + emojiData = data.emojis[emoji.id]; + skin || (skin = emoji.skin); + } + } + + if (!(0, _keys2.default)(emojiData).length) { + emojiData = emoji; + emojiData.custom = true; + + if (!emojiData.search) { + emojiData.search = (0, _data.buildSearch)(emoji); + } + } + + emojiData.emoticons || (emojiData.emoticons = []); + emojiData.variations || (emojiData.variations = []); + + if (emojiData.skin_variations && skin > 1 && set) { + emojiData = JSON.parse(_JSON.stringify(emojiData)); + + var skinKey = SKINS[skin - 1], + variationData = emojiData.skin_variations[skinKey]; + + if (!variationData.variations && emojiData.variations) { + delete emojiData.variations; + } + + if (variationData[`has_img_${set}`] == undefined || variationData[`has_img_${set}`]) { + emojiData.skin_tone = skin; + + for (let k in variationData) { + let v = variationData[k]; + emojiData[k] = v; + } + } + } + + if (emojiData.variations && emojiData.variations.length) { + emojiData = JSON.parse(_JSON.stringify(emojiData)); + emojiData.unified = emojiData.variations.shift(); + } + + return emojiData; +} + +function uniq(arr) { + return arr.reduce((acc, item) => { + if (acc.indexOf(item) === -1) { + acc.push(item); + } + return acc; + }, []); +} + +function intersect(a, b) { + const uniqA = uniq(a); + const uniqB = uniq(b); + + return uniqA.filter(item => uniqB.indexOf(item) >= 0); +} + +function deepMerge(a, b) { + var o = {}; + + for (let key in a) { + let originalValue = a[key], + value = originalValue; + + if (b.hasOwnProperty(key)) { + value = b[key]; + } + + if (typeof value === 'object') { + value = deepMerge(originalValue, value); + } + + o[key] = value; + } + + return o; +} + +// https://github.com/sonicdoe/measure-scrollbar +function measureScrollbar() { + if (typeof document == 'undefined') return 0; + const div = document.createElement('div'); + + div.style.width = '100px'; + div.style.height = '100px'; + div.style.overflow = 'scroll'; + div.style.position = 'absolute'; + div.style.top = '-9999px'; + + document.body.appendChild(div); + const scrollbarWidth = div.offsetWidth - div.clientWidth; + document.body.removeChild(div); + + return scrollbarWidth; +} + +// Use requestIdleCallback() if available, else fall back to setTimeout(). +// Throttle so as not to run too frequently. +function throttleIdleTask(func) { + const queue = typeof requestIdleCallback === 'function' ? requestIdleCallback : setTimeout; + const clear = typeof cancelIdleCallback === 'function' ? cancelIdleCallback : clearTimeout; + + let id; + + return function throttled() { + if (id) { + clear(id); + } + id = queue(func); + }; +} + +exports.getData = getData; +exports.getSanitizedData = getSanitizedData; +exports.uniq = uniq; +exports.intersect = intersect; +exports.deepMerge = deepMerge; +exports.unifiedToNative = unifiedToNative; +exports.measureScrollbar = measureScrollbar; +exports.throttleIdleTask = throttleIdleTask; \ No newline at end of file diff --git a/dist/utils/shared-default-props.js b/dist/utils/shared-default-props.js new file mode 100644 index 000000000..2abf15990 --- /dev/null +++ b/dist/utils/shared-default-props.js @@ -0,0 +1,51 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +const EmojiDefaultProps = { + skin: 1, + set: 'apple', + sheetSize: 64, + sheetColumns: 52, + sheetRows: 52, + native: false, + forceSize: false, + tooltip: false, + backgroundImageFn: (set, sheetSize) => `https://unpkg.com/emoji-datasource-${set}@${'4.0.4'}/img/${set}/sheets-256/${sheetSize}.png`, + onOver: () => {}, + onLeave: () => {}, + onClick: () => {} +}; + +const PickerDefaultProps = { + onClick: () => {}, + onSelect: () => {}, + onSkinChange: () => {}, + emojiSize: 24, + perLine: 9, + i18n: {}, + style: {}, + title: 'Emoji Mart™', + emoji: 'department_store', + color: '#ae65c5', + set: EmojiDefaultProps.set, + skin: null, + defaultSkin: EmojiDefaultProps.skin, + native: EmojiDefaultProps.native, + sheetSize: EmojiDefaultProps.sheetSize, + backgroundImageFn: EmojiDefaultProps.backgroundImageFn, + emojisToShowFilter: null, + showPreview: true, + showSkinTones: true, + emojiTooltip: EmojiDefaultProps.tooltip, + autoFocus: false, + custom: [], + skinEmoji: '', + notFound: () => {}, + notFoundEmoji: 'sleuth_or_spy', + icons: {} +}; + +exports.PickerDefaultProps = PickerDefaultProps; +exports.EmojiDefaultProps = EmojiDefaultProps; \ No newline at end of file diff --git a/dist/utils/shared-props.js b/dist/utils/shared-props.js new file mode 100644 index 000000000..127a4d1c2 --- /dev/null +++ b/dist/utils/shared-props.js @@ -0,0 +1,71 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PickerPropTypes = exports.EmojiPropTypes = undefined; + +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const EmojiPropTypes = { + data: _propTypes2.default.object.isRequired, + onOver: _propTypes2.default.func, + onLeave: _propTypes2.default.func, + onClick: _propTypes2.default.func, + fallback: _propTypes2.default.func, + backgroundImageFn: _propTypes2.default.func, + native: _propTypes2.default.bool, + forceSize: _propTypes2.default.bool, + tooltip: _propTypes2.default.bool, + skin: _propTypes2.default.oneOf([1, 2, 3, 4, 5, 6]), + sheetSize: _propTypes2.default.oneOf([16, 20, 32, 64]), + sheetColumns: _propTypes2.default.number, + sheetRows: _propTypes2.default.number, + set: _propTypes2.default.oneOf(['apple', 'google', 'twitter', 'emojione', 'messenger', 'facebook']), + size: _propTypes2.default.number.isRequired, + emoji: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object]).isRequired +}; + +const PickerPropTypes = { + onClick: _propTypes2.default.func, + onSelect: _propTypes2.default.func, + onSkinChange: _propTypes2.default.func, + perLine: _propTypes2.default.number, + emojiSize: _propTypes2.default.number, + i18n: _propTypes2.default.object, + style: _propTypes2.default.object, + title: _propTypes2.default.string, + emoji: _propTypes2.default.string, + color: _propTypes2.default.string, + set: EmojiPropTypes.set, + skin: EmojiPropTypes.skin, + native: _propTypes2.default.bool, + backgroundImageFn: EmojiPropTypes.backgroundImageFn, + sheetSize: EmojiPropTypes.sheetSize, + emojisToShowFilter: _propTypes2.default.func, + showPreview: _propTypes2.default.bool, + showSkinTones: _propTypes2.default.bool, + emojiTooltip: EmojiPropTypes.tooltip, + include: _propTypes2.default.arrayOf(_propTypes2.default.string), + exclude: _propTypes2.default.arrayOf(_propTypes2.default.string), + recent: _propTypes2.default.arrayOf(_propTypes2.default.string), + autoFocus: _propTypes2.default.bool, + custom: _propTypes2.default.arrayOf(_propTypes2.default.shape({ + name: _propTypes2.default.string.isRequired, + short_names: _propTypes2.default.arrayOf(_propTypes2.default.string).isRequired, + emoticons: _propTypes2.default.arrayOf(_propTypes2.default.string), + keywords: _propTypes2.default.arrayOf(_propTypes2.default.string), + imageUrl: _propTypes2.default.string.isRequired + })), + skinEmoji: _propTypes2.default.string, + notFound: _propTypes2.default.func, + notFoundEmoji: _propTypes2.default.string, + icons: _propTypes2.default.object +}; + +exports.EmojiPropTypes = EmojiPropTypes; +exports.PickerPropTypes = PickerPropTypes; \ No newline at end of file diff --git a/dist/utils/store.js b/dist/utils/store.js new file mode 100644 index 000000000..622de4478 --- /dev/null +++ b/dist/utils/store.js @@ -0,0 +1,61 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var NAMESPACE = 'emoji-mart'; + +const _JSON = JSON; + +var isLocalStorageSupported = typeof window !== 'undefined' && 'localStorage' in window; + +let getter; +let setter; + +function setHandlers(handlers) { + handlers || (handlers = {}); + + getter = handlers.getter; + setter = handlers.setter; +} + +function setNamespace(namespace) { + NAMESPACE = namespace; +} + +function update(state) { + for (let key in state) { + let value = state[key]; + set(key, value); + } +} + +function set(key, value) { + if (setter) { + setter(key, value); + } else { + if (!isLocalStorageSupported) return; + try { + window.localStorage[`${NAMESPACE}.${key}`] = _JSON.stringify(value); + } catch (e) {} + } +} + +function get(key) { + if (getter) { + return getter(key); + } else { + if (!isLocalStorageSupported) return; + try { + var value = window.localStorage[`${NAMESPACE}.${key}`]; + } catch (e) { + return; + } + + if (value) { + return JSON.parse(value); + } + } +} + +exports.default = { update, set, get, setNamespace, setHandlers }; \ No newline at end of file diff --git a/dist/vendor/raf-polyfill.js b/dist/vendor/raf-polyfill.js new file mode 100644 index 000000000..dc2509f71 --- /dev/null +++ b/dist/vendor/raf-polyfill.js @@ -0,0 +1,35 @@ +'use strict'; + +// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + +// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel + +// MIT license + +var isWindowAvailable = typeof window !== 'undefined'; + +isWindowAvailable && function () { + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function () { + callback(currTime + timeToCall); + }, timeToCall); + + lastTime = currTime + timeToCall; + return id; + }; + + if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; +}(); \ No newline at end of file