UNPKG

react-emoji-picker

Version:

A React component providing a visual emoji picker, similar to Slack's

195 lines (170 loc) 5.17 kB
"use strict"; var React = require('react'); var ReactEmoji = require('react-emoji'); var emojiMap = require('./lib/emojiMap'); function touchDevice() { return "ontouchstart" in document.documentElement; } var tabWrapStyle = { display: 'block', borderBottom: '1px solid silver', } var tabStyle = { marginRight: '0.4rem', display: 'inline-block', padding: '0.2rem 0.3rem', border: '1px solid silver', borderBottom: 'none', borderRadius: '0.3rem 0.3rem 0 0', cursor: 'pointer', position: 'relative', top: 2, } var activeTabStyle = {}; for (var key in tabStyle) { activeTabStyle[key] = tabStyle[key]; } activeTabStyle.borderBottom = '3px solid white'; var bodyStyle = { display: 'block', margin: '0.3em 0 0', maxHeight: '12.5em', overflowY: 'scroll', } function filterByName(opts) { return opts.emoji.name.match(opts.query) || opts.emoji.alternatives.match(opts.query) } function filterByCategory(opts) { return opts.emoji.category === opts.category } module.exports = React.createClass({ displayName: 'EmojiPicker', mixins: [ReactEmoji], propTypes: { query: React.PropTypes.string, doGrabKeyPress: React.PropTypes.bool, }, getDefaultProps: function() { return { doGrabKeyPress: true, }; }, getInitialState: function() { return { hovered: null, category: 'people', } }, componentDidMount: function() { if (this.props.doGrabKeyPress) { document.addEventListener('keydown', this.grabKeyPress, false) } }, componentWillUnmount: function() { if (this.props.doGrabKeyPress) { document.removeEventListener('keydown', this.grabKeyPress, false) } }, // if user presses Enter or Tab while EmojiPicker showing grabKeyPress: function(e) { if(e.keyCode === 13 || e.keyCode === 9) { e.preventDefault() this.selectFirst() } }, selectFirst: function() { if(this.emojis()[0]) { this.props.onSelect(':' + this.emojis()[0].name + ':') } }, emojis: function() { var query = (this.props.query || ''). replace(/:/g, ''). replace(/([\+\-])/g, "\\$&"). toLowerCase(); var category = this.state.category; return emojiMap.filter(function(emoji) { return query ? filterByName({emoji:emoji, query:query}) : filterByCategory({emoji:emoji, category:category}) }) }, setCategory: function(category) { this.setState({category: category}) }, header: function() { var cat = this.state.category; if(!this.props.query) { return ( React.createElement("span", {style: tabWrapStyle}, React.createElement("a", { className: "emoji-picker-emoji", style: cat === 'people' ? activeTabStyle : tabStyle, onClick: this.setCategory.bind(this, 'people')}, this.emojify(':smiley:', {singleEmoji: true}) ), React.createElement("a", {className: "emoji-picker-emoji", style: cat === 'nature' ? activeTabStyle : tabStyle, onClick: this.setCategory.bind(this, 'nature')}, this.emojify(':seedling:', {singleEmoji: true}) ), React.createElement("a", {className: "emoji-picker-emoji", style: cat === 'objects' ? activeTabStyle : tabStyle, onClick: this.setCategory.bind(this, 'objects')}, this.emojify(':telescope:', {singleEmoji: true}) ), React.createElement("a", {className: "emoji-picker-emoji", style: cat === 'places' ? activeTabStyle : tabStyle, onClick: this.setCategory.bind(this, 'places')}, this.emojify(':bike:', {singleEmoji: true}) ), React.createElement("a", {className: "emoji-picker-emoji", style: cat === 'symbols' ? activeTabStyle : tabStyle, onClick: this.setCategory.bind(this, 'symbols')}, this.emojify(':1234:', {singleEmoji: true}) ) ) ) } }, body: function() { var that = this; var emojiLinks = this.emojis().map(function(emoji) { emoji = ':' + emoji.name + ':'; return ( React.createElement("a", {key: emoji, className: "emoji-picker-emoji", onClick: that.props.onSelect.bind(null, emoji), onMouseEnter: !touchDevice() && that.hovered.bind(that, emoji), onMouseLeave: !touchDevice() && that.blurred, style: {padding: '0.2rem', cursor: 'pointer'}}, that.emojify(emoji, {singleEmoji: true}) ) ) }); if(emojiLinks.length === 0) emojiLinks = "No emojis found"; return React.createElement("span", {style: bodyStyle}, emojiLinks); }, footer: function() { if(this.state.hovered) { return ( React.createElement("span", null, this.state.hovered ) ); } }, hovered: function(emoji) { this.setState({hovered: emoji}) }, blurred: function() { this.setState({hovered: null}) }, render: function() { return ( React.createElement("span", {style: this.props.style}, this.header(), this.body(), this.footer() ) ) } })