From 40efd8367a85e3333e9b7cc45c390259d412088c Mon Sep 17 00:00:00 2001
From: Harrison Healey <harrisonmhealey@gmail.com>
Date: Tue, 13 Jun 2017 14:35:45 -0400
Subject: PLT-6127/PLT-6135/PLT-6137 Added EmojiPickerOverlay component to
 better position emoji picker (#6352)

* Cleaned up emoji picker CSS

* Fixed border of emoji picker when reacting to comments in the RHS

* PLT-6135 Made EmojiPicker automatically position itself above/below the [...] menu

* PLT-6135 Changed post textbox emoji picker to use a RootCloseWrapper

* PLT-6135 Changed comment textbox emoji picker to use a RootCloseWrapper

* PLT-6135 Changed RHS post components to use EmojiPickerOverlay

* Removed react-outside-event package

* Fixed merge conflict

* Fixed emoji picker position on posts in RHS

* Removed unused CSS classes

* Fixed not being able to react to posts with emoji picker
---
 webapp/components/emoji_picker/emoji_picker.jsx | 58 +++++++++++--------------
 1 file changed, 25 insertions(+), 33 deletions(-)

(limited to 'webapp/components/emoji_picker/emoji_picker.jsx')

diff --git a/webapp/components/emoji_picker/emoji_picker.jsx b/webapp/components/emoji_picker/emoji_picker.jsx
index e9cddce34..cbb388a10 100644
--- a/webapp/components/emoji_picker/emoji_picker.jsx
+++ b/webapp/components/emoji_picker/emoji_picker.jsx
@@ -1,15 +1,13 @@
-import PropTypes from 'prop-types';
-
 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
 // See License.txt for license information.
 
 import React from 'react';
+import PropTypes from 'prop-types';
 
 import * as Emoji from 'utils/emoji.jsx';
 import EmojiStore from 'stores/emoji_store.jsx';
 import PureRenderMixin from 'react-addons-pure-render-mixin';
 import * as Utils from 'utils/utils.jsx';
-import ReactOutsideEvent from 'react-outside-event';
 import {FormattedMessage} from 'react-intl';
 
 import EmojiPickerCategory from './components/emoji_picker_category.jsx';
@@ -30,13 +28,12 @@ const CATEGORIES = [
     'custom'
 ];
 
-class EmojiPicker extends React.Component {
+export default class EmojiPicker extends React.Component {
     static propTypes = {
+        style: PropTypes.object,
+        placement: PropTypes.oneOf(['top', 'bottom', 'left']),
         customEmojis: PropTypes.object,
-        onEmojiClick: PropTypes.func.isRequired,
-        pickerLocation: PropTypes.string.isRequired,
-        emojiOffset: PropTypes.number,
-        outsideClick: PropTypes.func
+        onEmojiClick: PropTypes.func.isRequired
     }
 
     constructor(props) {
@@ -53,7 +50,6 @@ class EmojiPicker extends React.Component {
         this.handleScroll = this.handleScroll.bind(this);
         this.handleItemUnmount = this.handleItemUnmount.bind(this);
         this.renderCategory = this.renderCategory.bind(this);
-        this.onOutsideEvent = this.onOutsideEvent.bind(this);
 
         this.state = {
             category: 'recent',
@@ -63,14 +59,11 @@ class EmojiPicker extends React.Component {
     }
 
     componentDidMount() {
-        this.searchInput.focus();
-    }
-
-    onOutsideEvent = (event) => {
-        // Handle the event.
-        if (this.props.outsideClick) {
-            this.props.outsideClick(event);
-        }
+        // Delay taking focus because this briefly renders offscreen when using an Overlay
+        // so focusing it immediately on mount can cause weird scrolling
+        requestAnimationFrame(() => {
+            this.searchInput.focus();
+        });
     }
 
     handleCategoryClick(category) {
@@ -99,7 +92,7 @@ class EmojiPicker extends React.Component {
     }
 
     handleItemUnmount(emoji) {
-        //Prevent emoji preview from showing emoji which is not present anymore (due to filter)
+        // Prevent emoji preview from showing emoji which is not present anymore (due to filter)
         if (this.state.selected === emoji) {
             this.setState({selected: null});
         }
@@ -292,22 +285,25 @@ class EmojiPicker extends React.Component {
                 items.push(this.renderCategory(category, this.state.filter));
             }
         }
-        let cssclass = 'emoji-picker ';
-        if (this.props.pickerLocation === 'top') {
-            cssclass += 'emoji-picker-top';
-        } else if (this.props.pickerLocation === 'bottom') {
-            cssclass += 'emoji-picker-bottom';
-        } else if (this.props.pickerLocation === 'react') {
-            cssclass = 'emoji-picker-react';
-        } else if (this.props.pickerLocation === 'react-rhs-comment') {
-            cssclass = 'emoji-picker-react-rhs-comment';
+
+        let pickerStyle;
+        if (this.props.style && !(this.props.style.left === 0 || this.props.style.top === 0)) {
+            if (this.props.placement === 'top' || this.props.placement === 'bottom') {
+                // Only take the top/bottom position passed by React Bootstrap since we want to be right-aligned
+                pickerStyle = {
+                    top: this.props.style.top,
+                    bottom: this.props.style.bottom,
+                    right: 1
+                };
+            } else {
+                pickerStyle = this.props.style;
+            }
         }
 
-        const pickerStyle = this.props.emojiOffset ? {top: this.props.emojiOffset} : {};
         return (
             <div
+                className='emoji-picker'
                 style={pickerStyle}
-                className={cssclass}
             >
                 <div className='emoji-picker__categories'>
                     <EmojiPickerCategory
@@ -426,7 +422,3 @@ class EmojiPicker extends React.Component {
         );
     }
 }
-
-// disabling eslint check for outslide click handler
-// eslint-disable-next-line new-cap
-export default ReactOutsideEvent(EmojiPicker, ['click']);
-- 
cgit v1.2.3-1-g7c22

