diff --git a/docs/components.json b/docs/components.json index 90066ed1..574c4a47 100644 --- a/docs/components.json +++ b/docs/components.json @@ -1449,6 +1449,24 @@ "computed": false } }, + "open": { + "type": { + "name": "bool" + }, + "required": false, + "description": "Toggle the EmojiMenu's visibility", + "defaultValue": { + "value": "false", + "computed": false + } + }, + "hideMenu": { + "type": { + "name": "func" + }, + "required": true, + "description": "Function to hide the menu" + }, "color": { "type": { "name": "string" diff --git a/docs/src/components/emoji-menu.jsx b/docs/src/components/emoji-menu.jsx index 3a85ce32..8e580813 100644 --- a/docs/src/components/emoji-menu.jsx +++ b/docs/src/components/emoji-menu.jsx @@ -1,49 +1,80 @@ -import React from 'react'; +import React, { Component } from 'react'; import ReactMarkdown from 'react-markdown'; import _ from 'underscore'; +import emojione from 'emojione'; import EmojiMenu from '../../../dist/emoji-menu'; +import Button from '../../../dist/button'; import Props from './props'; import components from '../../components.json'; import Paper from '../../../dist/paper'; const usage = '```js\n import EmojiMenu from \'anchor-ui/emoji-menu\';'; -const EmojiMenuDoc = () => { - const componentData = _.find(components, component => component.displayName === 'EmojiMenu'); - const style = { - paper: { - display: 'flex', - flexWrap: 'wrap', - alignItems: 'center', - margin: 0, - padding: '20px' - }, - emojiMenu: { margin: '10px' } - }; - - return ( -
-

EmojiMenu

-
-

Description

-

{componentData.description}

-
-
-

Usage

- -
-
-

Examples

- - {}} - style={style.emojiMenu} - /> - -
- -
- ); -}; +class EmojiMenuDoc extends Component { + static createMarkup = text => ({ + __html: emojione.toImage(text) + }) + + constructor() { + super(); + + this.state = { + open: false, + emoji: '' + }; + } + + toggleMenu = () => this.setState({ open: !this.state.open }) + + sendEmoji = ({ shortname }) => this.setState({ emoji: shortname }) + + render() { + const componentData = _.find(components, component => component.displayName === 'EmojiMenu'); + const style = { + paper: { + display: 'flex', + flexWrap: 'wrap', + alignItems: 'center', + margin: 0, + padding: '20px' + }, + emojiMenu: { margin: '10px' } + }; + + return ( +
+

EmojiMenu

+
+

Description

+

{componentData.description}

+
+
+

Usage

+ +
+
+

Examples

+ + { + this.state.emoji + ? + : null + } + + + +
+ +
+ ); + } +} export default EmojiMenuDoc; diff --git a/docs/src/index.css b/docs/src/index.css index c0fe59ee..98df334f 100644 --- a/docs/src/index.css +++ b/docs/src/index.css @@ -154,3 +154,8 @@ code { tbody tr td:nth-of-type(2) { text-transform: capitalize; } + +.emojione { + width: 32px; + height: 32px; +} diff --git a/src/emoji-menu/index.jsx b/src/emoji-menu/index.jsx index 1860520e..60c25ca9 100644 --- a/src/emoji-menu/index.jsx +++ b/src/emoji-menu/index.jsx @@ -2,9 +2,10 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import emojione from 'emojione'; import _ from 'lodash'; -import pure from 'recompose/pure'; import Radium from 'radium'; import compose from 'recompose/compose'; +import onClickOutside from 'react-onclickoutside'; +import EventListener from 'react-event-listener'; import emojis from './emoji'; import EmojiCategory from './emoji-category'; import EmojiModifiers from './emoji-modifiers'; @@ -38,6 +39,10 @@ class EmojiMenu extends Component { footerStyle: PropTypes.instanceOf(Object), /** Override the styles of the footer icons */ iconStyle: PropTypes.instanceOf(Object), + /** Toggle the EmojiMenu's visibility */ + open: PropTypes.bool, + /** Function to hide the menu */ + hideMenu: PropTypes.func.isRequired, color: PropTypes.string.isRequired } @@ -49,7 +54,8 @@ class EmojiMenu extends Component { categoryStyle: {}, emojiStyle: {}, footerStyle: {}, - iconStyle: {} + iconStyle: {}, + open: false } constructor(props) { @@ -74,6 +80,20 @@ class EmojiMenu extends Component { this.sendEmoji = this.sendEmoji.bind(this); } + handleClickOutside = (event) => { + const { hideMenu } = this.props; + + hideMenu(event); + } + + handleKeyUp = (event) => { + const { hideMenu } = this.props; + + if (event.which === 27) { + hideMenu(event); + } + } + changeTone(tone) { this.setState({ tone @@ -112,9 +132,21 @@ class EmojiMenu extends Component { sendEmoji, // eslint-disable-line no-unused-vars svgSprites, // eslint-disable-line no-unused-vars color, + open, + eventTypes, // eslint-disable-line no-unused-vars, react/prop-types + outsideClickIgnoreClass, // eslint-disable-line no-unused-vars, react/prop-types + preventDefault, // eslint-disable-line no-unused-vars, react/prop-types + stopPropagation, // eslint-disable-line no-unused-vars, react/prop-types + disableOnClickOutside, // eslint-disable-line no-unused-vars, react/prop-types + enableOnClickOutside, // eslint-disable-line no-unused-vars, react/prop-types + hideMenu, // eslint-disable-line no-unused-vars ...custom } = this.props; + if (!open) { + return null; + } + const modifiers = _.filter(emojis, { category: 'modifier' }); const filteredEmoji = _.chain(emojis).filter({ category }).filter((emoji) => { @@ -164,6 +196,7 @@ class EmojiMenu extends Component { style={footerStyle} iconStyle={iconStyle} /> + ); } @@ -171,8 +204,8 @@ class EmojiMenu extends Component { const enhance = compose( themeable(), - Radium, - pure + onClickOutside, + Radium ); export default enhance(EmojiMenu); diff --git a/src/emoji-menu/styles.js b/src/emoji-menu/styles.js index 4b768193..d96e26d3 100644 --- a/src/emoji-menu/styles.js +++ b/src/emoji-menu/styles.js @@ -35,7 +35,8 @@ export default { marginTop: '0', fontWeight: 'bolder', textTransform: 'capitalize', - marginBottom: '10px' + marginBottom: '10px', + fontSize: '16px' }, emojiContainer: { display: 'flex',