about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js55
-rw-r--r--app/javascript/styles/mastodon/_mixins.scss31
-rw-r--r--app/javascript/styles/mastodon/components.scss95
3 files changed, 128 insertions, 53 deletions
diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
index 9c9f62d82..cdc138c8b 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
@@ -1,10 +1,15 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
-import { injectIntl, FormattedMessage } from 'react-intl';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import Toggle from 'react-toggle';
 import AsyncSelect from 'react-select/lib/Async';
 
+const messages = defineMessages({
+  placeholder: { id: 'hashtag.column_settings.select.placeholder', defaultMessage: 'Enter hashtags…' },
+  noOptions: { id: 'hashtag.column_settings.select.no_options_message', defaultMessage: 'No suggestions found' },
+});
+
 export default @injectIntl
 class ColumnSettings extends React.PureComponent {
 
@@ -25,6 +30,7 @@ class ColumnSettings extends React.PureComponent {
 
   tags (mode) {
     let tags = this.props.settings.getIn(['tags', mode]) || [];
+
     if (tags.toJSON) {
       return tags.toJSON();
     } else {
@@ -32,33 +38,36 @@ class ColumnSettings extends React.PureComponent {
     }
   };
 
-  onSelect = (mode) => {
-    return (value) => {
-      this.props.onChange(['tags', mode], value);
-    };
-  };
+  onSelect = mode => value => this.props.onChange(['tags', mode], value);
 
   onToggle = () => {
     if (this.state.open && this.hasTags()) {
       this.props.onChange('tags', {});
     }
+
     this.setState({ open: !this.state.open });
   };
 
+  noOptionsMessage = () => this.props.intl.formatMessage(messages.noOptions);
+
   modeSelect (mode) {
     return (
-      <div className='column-settings__section'>
-        {this.modeLabel(mode)}
+      <div className='column-settings__row'>
+        <span className='column-settings__section'>
+          {this.modeLabel(mode)}
+        </span>
+
         <AsyncSelect
           isMulti
           autoFocus
           value={this.tags(mode)}
-          settings={this.props.settings}
-          settingPath={['tags', mode]}
           onChange={this.onSelect(mode)}
           loadOptions={this.props.onLoad}
-          classNamePrefix='column-settings__hashtag-select'
+          className='column-select__container'
+          classNamePrefix='column-select'
           name='tags'
+          placeholder={this.props.intl.formatMessage(messages.placeholder)}
+          noOptionsMessage={this.noOptionsMessage}
         />
       </div>
     );
@@ -66,11 +75,15 @@ class ColumnSettings extends React.PureComponent {
 
   modeLabel (mode) {
     switch(mode) {
-    case 'any':  return <FormattedMessage id='hashtag.column_settings.tag_mode.any' defaultMessage='Any of these' />;
-    case 'all':  return <FormattedMessage id='hashtag.column_settings.tag_mode.all' defaultMessage='All of these' />;
-    case 'none': return <FormattedMessage id='hashtag.column_settings.tag_mode.none' defaultMessage='None of these' />;
+    case 'any':
+      return <FormattedMessage id='hashtag.column_settings.tag_mode.any' defaultMessage='Any of these' />;
+    case 'all':
+      return <FormattedMessage id='hashtag.column_settings.tag_mode.all' defaultMessage='All of these' />;
+    case 'none':
+      return <FormattedMessage id='hashtag.column_settings.tag_mode.none' defaultMessage='None of these' />;
+    default:
+      return '';
     }
-    return '';
   };
 
   render () {
@@ -78,23 +91,21 @@ class ColumnSettings extends React.PureComponent {
       <div>
         <div className='column-settings__row'>
           <div className='setting-toggle'>
-            <Toggle
-              id='hashtag.column_settings.tag_toggle'
-              onChange={this.onToggle}
-              checked={this.state.open}
-            />
+            <Toggle id='hashtag.column_settings.tag_toggle' onChange={this.onToggle} checked={this.state.open} />
+
             <span className='setting-toggle__label'>
               <FormattedMessage id='hashtag.column_settings.tag_toggle' defaultMessage='Include additional tags in this column' />
             </span>
           </div>
         </div>
-        {this.state.open &&
+
+        {this.state.open && (
           <div className='column-settings__hashtags'>
             {this.modeSelect('any')}
             {this.modeSelect('all')}
             {this.modeSelect('none')}
           </div>
-        }
+        )}
       </div>
     );
   }
diff --git a/app/javascript/styles/mastodon/_mixins.scss b/app/javascript/styles/mastodon/_mixins.scss
index d5bafe6b6..08806599e 100644
--- a/app/javascript/styles/mastodon/_mixins.scss
+++ b/app/javascript/styles/mastodon/_mixins.scss
@@ -41,3 +41,34 @@
     font-size: 16px;
   }
 }
+
+@mixin search-popout() {
+  background: $simple-background-color;
+  border-radius: 4px;
+  padding: 10px 14px;
+  padding-bottom: 14px;
+  margin-top: 10px;
+  color: $light-text-color;
+  box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
+
+  h4 {
+    text-transform: uppercase;
+    color: $light-text-color;
+    font-size: 13px;
+    font-weight: 500;
+    margin-bottom: 10px;
+  }
+
+  li {
+    padding: 4px 0;
+  }
+
+  ul {
+    margin-bottom: 10px;
+  }
+
+  em {
+    font-weight: 500;
+    color: $inverted-text-color;
+  }
+}
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 32fd77385..02bbd345a 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -3056,14 +3056,41 @@ a.status-card.compact:hover {
   display: block;
   font-weight: 500;
   margin-bottom: 10px;
+}
+
+.column-settings__hashtags {
+  .column-settings__row {
+    margin-bottom: 15px;
+  }
 
-  .column-settings__hashtag-select {
+  .column-select {
     &__control {
       @include search-input();
     }
 
+    &__placeholder {
+      color: $dark-text-color;
+      padding-left: 2px;
+      font-size: 12px;
+    }
+
+    &__value-container {
+      padding-left: 6px;
+    }
+
     &__multi-value {
       background: lighten($ui-base-color, 8%);
+
+      &__remove {
+        cursor: pointer;
+
+        &:hover,
+        &:active,
+        &:focus {
+          background: lighten($ui-base-color, 12%);
+          color: lighten($darker-text-color, 4%);
+        }
+      }
     }
 
     &__multi-value__label,
@@ -3071,9 +3098,42 @@ a.status-card.compact:hover {
       color: $darker-text-color;
     }
 
-    &__indicator-separator,
+    &__clear-indicator,
     &__dropdown-indicator {
-      display: none;
+      cursor: pointer;
+      transition: none;
+      color: $dark-text-color;
+
+      &:hover,
+      &:active,
+      &:focus {
+        color: lighten($dark-text-color, 4%);
+      }
+    }
+
+    &__indicator-separator {
+      background-color: lighten($ui-base-color, 8%);
+    }
+
+    &__menu {
+      @include search-popout();
+      padding: 0;
+      background: $ui-secondary-color;
+    }
+
+    &__menu-list {
+      padding: 6px;
+    }
+
+    &__option {
+      color: $inverted-text-color;
+      border-radius: 4px;
+      font-size: 14px;
+
+      &--is-focused,
+      &--is-selected {
+        background: darken($ui-secondary-color, 10%);
+      }
     }
   }
 }
@@ -4867,34 +4927,7 @@ a.status-card.compact:hover {
 }
 
 .search-popout {
-  background: $simple-background-color;
-  border-radius: 4px;
-  padding: 10px 14px;
-  padding-bottom: 14px;
-  margin-top: 10px;
-  color: $light-text-color;
-  box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
-
-  h4 {
-    text-transform: uppercase;
-    color: $light-text-color;
-    font-size: 13px;
-    font-weight: 500;
-    margin-bottom: 10px;
-  }
-
-  li {
-    padding: 4px 0;
-  }
-
-  ul {
-    margin-bottom: 10px;
-  }
-
-  em {
-    font-weight: 500;
-    color: $inverted-text-color;
-  }
+  @include search-popout();
 }
 
 noscript {