2022-08-31 02:35:06 -07:00
|
|
|
import classNames from 'clsx';
|
2022-05-06 11:31:35 -07:00
|
|
|
import React, { useState } from 'react';
|
|
|
|
import { defineMessages, useIntl } from 'react-intl';
|
|
|
|
|
2022-11-15 06:10:14 -08:00
|
|
|
import AutosuggestAccountInput from 'soapbox/components/autosuggest-account-input';
|
2022-05-06 11:31:35 -07:00
|
|
|
|
2022-08-10 05:38:49 -07:00
|
|
|
import SvgIcon from './ui/icon/svg-icon';
|
|
|
|
|
2022-05-06 11:31:35 -07:00
|
|
|
const messages = defineMessages({
|
|
|
|
placeholder: { id: 'account_search.placeholder', defaultMessage: 'Search for an account' },
|
|
|
|
});
|
|
|
|
|
|
|
|
interface IAccountSearch {
|
|
|
|
/** Callback when a searched account is chosen. */
|
|
|
|
onSelected: (accountId: string) => void,
|
|
|
|
/** Override the default placeholder of the input. */
|
|
|
|
placeholder?: string,
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Input to search for accounts. */
|
2022-12-08 11:41:26 -08:00
|
|
|
const AccountSearch: React.FC<IAccountSearch> = ({ onSelected, ...rest }) => {
|
2022-05-06 11:31:35 -07:00
|
|
|
const intl = useIntl();
|
|
|
|
|
|
|
|
const [value, setValue] = useState('');
|
|
|
|
|
|
|
|
const isEmpty = (): boolean => {
|
|
|
|
return !(value.length > 0);
|
|
|
|
};
|
|
|
|
|
|
|
|
const clearState = () => {
|
|
|
|
setValue('');
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleChange: React.ChangeEventHandler<HTMLInputElement> = ({ target }) => {
|
|
|
|
setValue(target.value);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleSelected = (accountId: string) => {
|
|
|
|
clearState();
|
|
|
|
onSelected(accountId);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleClear: React.MouseEventHandler = e => {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
if (!isEmpty()) {
|
|
|
|
setValue('');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleKeyDown: React.KeyboardEventHandler = e => {
|
|
|
|
if (e.key === 'Escape') {
|
|
|
|
document.querySelector('.ui')?.parentElement?.focus();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2022-08-10 05:38:49 -07:00
|
|
|
<div className='w-full'>
|
|
|
|
<label className='sr-only'>{intl.formatMessage(messages.placeholder)}</label>
|
|
|
|
|
|
|
|
<div className='relative'>
|
2022-05-06 11:31:35 -07:00
|
|
|
<AutosuggestAccountInput
|
2022-12-08 11:41:26 -08:00
|
|
|
className='rounded-full'
|
2022-05-06 11:31:35 -07:00
|
|
|
placeholder={intl.formatMessage(messages.placeholder)}
|
|
|
|
value={value}
|
|
|
|
onChange={handleChange}
|
|
|
|
onSelected={handleSelected}
|
|
|
|
onKeyDown={handleKeyDown}
|
|
|
|
{...rest}
|
|
|
|
/>
|
2022-08-10 05:38:49 -07:00
|
|
|
|
2022-12-08 11:41:26 -08:00
|
|
|
<div
|
|
|
|
role='button'
|
|
|
|
tabIndex={0}
|
|
|
|
className='absolute inset-y-0 right-0 px-3 flex items-center cursor-pointer'
|
|
|
|
onClick={handleClear}
|
|
|
|
>
|
|
|
|
<SvgIcon
|
|
|
|
src={require('@tabler/icons/search.svg')}
|
|
|
|
className={classNames('h-4 w-4 text-gray-400', { hidden: !isEmpty() })}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<SvgIcon
|
|
|
|
src={require('@tabler/icons/x.svg')}
|
|
|
|
className={classNames('h-4 w-4 text-gray-400', { hidden: isEmpty() })}
|
|
|
|
aria-label={intl.formatMessage(messages.placeholder)}
|
|
|
|
/>
|
|
|
|
</div>
|
2022-05-06 11:31:35 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default AccountSearch;
|