= {
};
interface IAutosuggestLocation {
- id: string,
+ id: string
}
const AutosuggestLocation: React.FC = ({ id }) => {
@@ -32,7 +32,7 @@ const AutosuggestLocation: React.FC = ({ id }) => {
{location.description}
- {[location.street, location.locality, location.country].filter(val => val.trim()).join(' · ')}
+ {[location.street, location.locality, location.country].filter(val => val?.trim()).join(' · ')}
);
diff --git a/app/soapbox/components/autosuggest-textarea.tsx b/app/soapbox/components/autosuggest-textarea.tsx
index e43f49464..e5ff7473f 100644
--- a/app/soapbox/components/autosuggest-textarea.tsx
+++ b/app/soapbox/components/autosuggest-textarea.tsx
@@ -1,9 +1,9 @@
-import { Portal } from '@reach/portal';
-import classNames from 'clsx';
+import clsx from 'clsx';
import React from 'react';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Textarea from 'react-textarea-autosize';
+import { Portal } from 'soapbox/components/ui';
import { textAtCursorMatchesToken } from 'soapbox/utils/suggestions';
import AutosuggestAccount from '../features/compose/components/autosuggest-account';
@@ -14,22 +14,23 @@ import AutosuggestEmoji, { Emoji } from './autosuggest-emoji';
import type { List as ImmutableList } from 'immutable';
interface IAutosuggesteTextarea {
- id?: string,
- value: string,
- suggestions: ImmutableList,
- disabled: boolean,
- placeholder: string,
- onSuggestionSelected: (tokenStart: number, token: string | null, value: string | undefined) => void,
- onSuggestionsClearRequested: () => void,
- onSuggestionsFetchRequested: (token: string | number) => void,
- onChange: React.ChangeEventHandler,
- onKeyUp?: React.KeyboardEventHandler,
- onKeyDown?: React.KeyboardEventHandler,
- onPaste: (files: FileList) => void,
- autoFocus: boolean,
- onFocus: () => void,
- onBlur?: () => void,
- condensed?: boolean,
+ id?: string
+ value: string
+ suggestions: ImmutableList
+ disabled: boolean
+ placeholder: string
+ onSuggestionSelected: (tokenStart: number, token: string | null, value: string | undefined) => void
+ onSuggestionsClearRequested: () => void
+ onSuggestionsFetchRequested: (token: string | number) => void
+ onChange: React.ChangeEventHandler
+ onKeyUp?: React.KeyboardEventHandler
+ onKeyDown?: React.KeyboardEventHandler
+ onPaste: (files: FileList) => void
+ autoFocus: boolean
+ onFocus: () => void
+ onBlur?: () => void
+ condensed?: boolean
+ children: React.ReactNode
}
class AutosuggestTextarea extends ImmutablePureComponent {
@@ -64,7 +65,7 @@ class AutosuggestTextarea extends ImmutablePureComponent
}
this.props.onChange(e);
- }
+ };
onKeyDown: React.KeyboardEventHandler = (e) => {
const { suggestions, disabled } = this.props;
@@ -122,7 +123,7 @@ class AutosuggestTextarea extends ImmutablePureComponent
}
this.props.onKeyDown(e);
- }
+ };
onBlur = () => {
this.setState({ suggestionsHidden: true, focused: false });
@@ -130,7 +131,7 @@ class AutosuggestTextarea extends ImmutablePureComponent
if (this.props.onBlur) {
this.props.onBlur();
}
- }
+ };
onFocus = () => {
this.setState({ focused: true });
@@ -138,14 +139,14 @@ class AutosuggestTextarea extends ImmutablePureComponent
if (this.props.onFocus) {
this.props.onFocus();
}
- }
+ };
onSuggestionClick: React.MouseEventHandler = (e) => {
const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index') as any);
e.preventDefault();
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
this.textarea?.focus();
- }
+ };
shouldComponentUpdate(nextProps: IAutosuggesteTextarea, nextState: any) {
// Skip updating when only the lastToken changes so the
@@ -156,7 +157,8 @@ class AutosuggestTextarea extends ImmutablePureComponent
if (lastTokenUpdated && !valueUpdated) {
return false;
} else {
- return super.shouldComponentUpdate!(nextProps, nextState, undefined);
+ // https://stackoverflow.com/a/35962835
+ return super.shouldComponentUpdate!.bind(this)(nextProps, nextState, undefined);
}
}
@@ -169,14 +171,14 @@ class AutosuggestTextarea extends ImmutablePureComponent
setTextarea: React.Ref = (c) => {
this.textarea = c;
- }
+ };
onPaste: React.ClipboardEventHandler = (e) => {
if (e.clipboardData && e.clipboardData.files.length === 1) {
this.props.onPaste(e.clipboardData.files);
e.preventDefault();
}
- }
+ };
renderSuggestion = (suggestion: string | Emoji, i: number) => {
const { selectedSuggestion } = this.state;
@@ -199,7 +201,7 @@ class AutosuggestTextarea extends ImmutablePureComponent
tabIndex={0}
key={key}
data-index={i}
- className={classNames({
+ className={clsx({
'px-4 py-2.5 text-sm text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-primary-800 group': true,
'bg-gray-100 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-800': i === selectedSuggestion,
})}
@@ -208,7 +210,7 @@ class AutosuggestTextarea extends ImmutablePureComponent
{inner}
);
- }
+ };
setPortalPosition() {
if (!this.textarea) {
@@ -242,7 +244,7 @@ class AutosuggestTextarea extends ImmutablePureComponent