import React from 'react';
import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container';
import AutosuggestEmoji from './autosuggest_emoji';
+import AutosuggestHashtag from './autosuggest_hashtag';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
-import { isRtl } from '../rtl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Textarea from 'react-textarea-autosize';
import classNames from 'classnames';
const textAtCursorMatchesToken = (str, caretPosition) => {
let word;
- let left = str.slice(0, caretPosition).search(/[^\s\u200B]+$/);
- let right = str.slice(caretPosition).search(/[\s\u200B]/);
+ let left = str.slice(0, caretPosition).search(/\S+$/);
+ let right = str.slice(caretPosition).search(/\s/);
if (right < 0) {
word = str.slice(left);
word = str.slice(left, right + caretPosition);
}
- if (!word || word.trim().length < 3 || ['@', ':'].indexOf(word[0]) === -1) {
+ if (!word || word.trim().length < 3 || ['@', ':', '#'].indexOf(word[0]) === -1) {
return [null, null];
}
};
state = {
- suggestionsHidden: false,
+ suggestionsHidden: true,
+ focused: false,
selectedSuggestion: 0,
lastToken: null,
tokenStart: 0,
return;
}
+ if (e.which === 229 || e.isComposing) {
+ // Ignore key events during text composition
+ // e.key may be a name of the physical key even in this case (e.x. Safari / Chrome on Mac)
+ return;
+ }
+
switch(e.key) {
case 'Escape':
- if (!suggestionsHidden) {
+ if (suggestions.size === 0 || suggestionsHidden) {
+ document.querySelector('.ui').parentElement.focus();
+ } else {
e.preventDefault();
this.setState({ suggestionsHidden: true });
}
this.props.onKeyDown(e);
}
- onKeyUp = e => {
- if (e.key === 'Escape' && this.state.suggestionsHidden) {
- document.querySelector('.ui').parentElement.focus();
- }
-
- if (this.props.onKeyUp) {
- this.props.onKeyUp(e);
- }
+ onBlur = () => {
+ this.setState({ suggestionsHidden: true, focused: false });
}
- onBlur = () => {
- this.setState({ suggestionsHidden: true });
+ onFocus = (e) => {
+ this.setState({ focused: true });
+ if (this.props.onFocus) {
+ this.props.onFocus(e);
+ }
}
onSuggestionClick = (e) => {
}
componentWillReceiveProps (nextProps) {
- if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden) {
+ if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
this.setState({ suggestionsHidden: false });
}
}
const { selectedSuggestion } = this.state;
let inner, key;
- if (typeof suggestion === 'object') {
+ if (suggestion.type === 'emoji') {
inner = <AutosuggestEmoji emoji={suggestion} />;
key = suggestion.id;
- } else {
- inner = <AutosuggestAccountContainer id={suggestion} />;
- key = suggestion;
+ } else if (suggestion.type === 'hashtag') {
+ inner = <AutosuggestHashtag tag={suggestion} />;
+ key = suggestion.name;
+ } else if (suggestion.type === 'account') {
+ inner = <AutosuggestAccountContainer id={suggestion.id} />;
+ key = suggestion.id;
}
return (
}
render () {
- const { value, suggestions, disabled, placeholder, autoFocus } = this.props;
+ const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children } = this.props;
const { suggestionsHidden } = this.state;
- const style = { direction: 'ltr' };
-
- if (isRtl(value)) {
- style.direction = 'rtl';
- }
- return (
- <div className='autosuggest-textarea'>
- <label>
- <span style={{ display: 'none' }}>{placeholder}</span>
-
- <Textarea
- inputRef={this.setTextarea}
- className='autosuggest-textarea__textarea'
- disabled={disabled}
- placeholder={placeholder}
- autoFocus={autoFocus}
- value={value}
- onChange={this.onChange}
- onKeyDown={this.onKeyDown}
- onKeyUp={this.onKeyUp}
- onBlur={this.onBlur}
- onPaste={this.onPaste}
- style={style}
- />
- </label>
+ return [
+ <div className='compose-form__autosuggest-wrapper' key='autosuggest-wrapper'>
+ <div className='autosuggest-textarea'>
+ <label>
+ <span style={{ display: 'none' }}>{placeholder}</span>
+
+ <Textarea
+ ref={this.setTextarea}
+ className='autosuggest-textarea__textarea'
+ disabled={disabled}
+ placeholder={placeholder}
+ autoFocus={autoFocus}
+ value={value}
+ onChange={this.onChange}
+ onKeyDown={this.onKeyDown}
+ onKeyUp={onKeyUp}
+ onFocus={this.onFocus}
+ onBlur={this.onBlur}
+ onPaste={this.onPaste}
+ dir='auto'
+ aria-autocomplete='list'
+ />
+ </label>
+ </div>
+ {children}
+ </div>,
+ <div className='autosuggest-textarea__suggestions-wrapper' key='suggestions-wrapper'>
<div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
{suggestions.map(this.renderSuggestion)}
</div>
- </div>
- );
+ </div>,
+ ];
}
}