From ab31a59913253843305a987ce27666918cc0dbf2 Mon Sep 17 00:00:00 2001 From: Andre Vasconcelos Date: Tue, 12 Mar 2019 16:52:14 +0900 Subject: [PATCH] MM-14489 Making SuggestionList component render at bottom of input on dialogs (#2235) Given a bug found that `SuggestionList`s [will clip through the top of a modal body](https://pre-release.mattermost.com/core/pl/wafwh5fyytgauykxdyytsqa51a), this PR passes along the `listStyle` prop (as an optional prop) to make it render below the input (instead of above, which is the default behavior) --- .../interactive_dialog/dialog_element.jsx | 1 + .../interactive_dialog/interactive_dialog.jsx | 2 +- components/suggestion/suggestion_box.jsx | 14 ++++++++++++- components/suggestion/suggestion_list.jsx | 12 ++++++++++- .../settings/autocomplete_selector.jsx | 3 +++ sass/components/_select.scss | 5 ++--- sass/components/_suggestion-list.scss | 7 +++---- sass/layout/_webhooks.scss | 2 +- sass/routes/_about-modal.scss | 20 +++++++++++++++++-- 9 files changed, 53 insertions(+), 13 deletions(-) diff --git a/components/interactive_dialog/dialog_element.jsx b/components/interactive_dialog/dialog_element.jsx index b81411e725d6..d7b782d64d25 100644 --- a/components/interactive_dialog/dialog_element.jsx +++ b/components/interactive_dialog/dialog_element.jsx @@ -152,6 +152,7 @@ export default class DialogElement extends React.PureComponent { helpText={helpTextContent} placeholder={placeholder} value={this.state.value} + listStyle={'bottom'} /> ); } diff --git a/components/interactive_dialog/interactive_dialog.jsx b/components/interactive_dialog/interactive_dialog.jsx index 94a1750f0718..993ea99c6127 100644 --- a/components/interactive_dialog/interactive_dialog.jsx +++ b/components/interactive_dialog/interactive_dialog.jsx @@ -151,7 +151,7 @@ export default class InteractiveDialog extends React.Component { return ( { const textbox = this.getTextbox(); @@ -598,6 +601,13 @@ export default class SuggestionBox extends React.Component { this.container = container; }; + getDropdownPosition = () => { + const input = ReactDOM.findDOMNode(this.refs.input); + const dropdownPosition = input.getBoundingClientRect().top; + const inputWidth = input.clientWidth; + this.setState({dropdownPosition, inputWidth}); + } + render() { const { listComponent, @@ -661,6 +671,8 @@ export default class SuggestionBox extends React.Component { terms={this.state.terms} selection={this.state.selection} components={this.state.components} + dropdownPosition={this.state.dropdownPosition} + inputWidth={this.state.inputWidth} /> } {(this.props.openWhenEmpty || this.props.value.length >= this.props.requiredCharacters) && this.state.presentationType === 'date' && diff --git a/components/suggestion/suggestion_list.jsx b/components/suggestion/suggestion_list.jsx index 775e7d1e5ad0..42f2a3043dfd 100644 --- a/components/suggestion/suggestion_list.jsx +++ b/components/suggestion/suggestion_list.jsx @@ -24,6 +24,8 @@ export default class SuggestionList extends React.PureComponent { terms: PropTypes.array.isRequired, selection: PropTypes.string.isRequired, components: PropTypes.array.isRequired, + dropdownPosition: PropTypes.number, + inputWidth: PropTypes.number, }; static defaultProps = { @@ -161,8 +163,16 @@ export default class SuggestionList extends React.PureComponent { const mainClass = 'suggestion-list suggestion-list--' + this.props.location; const contentClass = 'suggestion-list__content suggestion-list__content--' + this.props.location; + let style = {}; + if (this.props.dropdownPosition && this.props.location === 'bottom') { + style = {top: this.props.dropdownPosition + 5, width: this.props.inputWidth}; + } + return ( -
+
{helpTextContent} {footer} diff --git a/sass/components/_select.scss b/sass/components/_select.scss index 7e5b351db721..61920b19854a 100644 --- a/sass/components/_select.scss +++ b/sass/components/_select.scss @@ -1,7 +1,7 @@ @charset 'UTF-8'; .select-suggestion-container { - position: relative; + position: static; margin: 8px 8px 0 0; &:hover { @@ -19,9 +19,8 @@ text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - top: 8px; + bottom: 22px; position: absolute; - right: 1rem; opacity: .4; font-size: 16px; pointer-events: none; diff --git a/sass/components/_suggestion-list.scss b/sass/components/_suggestion-list.scss index fda7ad779b81..58a9450c5a02 100644 --- a/sass/components/_suggestion-list.scss +++ b/sass/components/_suggestion-list.scss @@ -4,6 +4,7 @@ @extend %popover-box-shadow; width: 100%; z-index: 100; + position: absolute; .suggestion-list__item { &:hover { @@ -26,12 +27,10 @@ .suggestion-list--top { bottom: 100%; - position: absolute; } .suggestion-list--bottom { height: 0; - position: relative; } .suggestion-list__content { @@ -63,11 +62,11 @@ } .suggestion-list__content--top { - bottom: 0; + bottom: -8px; position: absolute; } -.suggestion-list--bottom { +.suggestion-list__content--bottom { position: relative; } diff --git a/sass/layout/_webhooks.scss b/sass/layout/_webhooks.scss index 7361feb7aafc..c63347c0465f 100644 --- a/sass/layout/_webhooks.scss +++ b/sass/layout/_webhooks.scss @@ -15,7 +15,7 @@ } } - .form-control { + .form-control, .suggestion-list { width: 22rem; } } diff --git a/sass/routes/_about-modal.scss b/sass/routes/_about-modal.scss index 07163cb7f64c..df81da1a668d 100644 --- a/sass/routes/_about-modal.scss +++ b/sass/routes/_about-modal.scss @@ -75,15 +75,31 @@ .select-suggestion-container { margin: 0; + .suggestion-list--top { + height: 0; + bottom: initial; + } + + .suggestion-list { + width: calc(100% - 50px); + + .suggestion-list__content--top { + position: relative; + bottom: initial; + transform: translateY(calc(-100% - 36px)); + } + } + .form-control { height: 36px; padding: 8px 12px; } &:after { - top: 9px; - right: 12px; + left: calc(100% - 27px); + bottom: 27px; font-size: 20px; + position: relative; } }