Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 4x 4x 10x 10x 10x 10x 10x 10x 1x 60x 2x 2x 2x 2x 2x 10x 1x 1x 1x 10x 3x 3x 10x 10x 10x 60x | import { useRef, useState, MouseEvent, FocusEvent } from 'react';
import { events } from 'app';
import { useForceUpdate } from 'hooks';
import { debounce, filterArrayByQueryMatch } from 'utils';
import { Entities } from 'types';
import * as S from './styles';
const OPTIONS = Object.values(Entities) as unknown as Entities[];
const Select = () => {
const inputRef = useRef<HTMLInputElement>(null);
const dropdownRef = useRef<HTMLDivElement>(null);
const forceUpdate = useForceUpdate();
const [selectedOption, setSelectedOption] = useState<Entities>(
Entities.CHARACTERS
);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const clearInputValue = () =>
!!inputRef.current && (inputRef.current.value = '');
const handleSelect = (option: Entities) => (e: MouseEvent) => {
e.stopPropagation();
setSelectedOption(option);
setIsDropdownOpen(false);
events.search.make({ entity: option });
setTimeout(() => clearInputValue(), 200);
};
const handleBlur = (event: FocusEvent) => {
Iif (dropdownRef.current?.contains(event.relatedTarget as Node)) return;
setIsDropdownOpen(false);
clearInputValue();
};
const handleOpenDropdown = () => {
setIsDropdownOpen(true);
setTimeout(() => inputRef.current?.focus(), 0);
};
const { value = '' } = inputRef.current || {};
const filteredOptions = filterArrayByQueryMatch<Entities>(value, OPTIONS);
return (
<S.Container onClick={handleOpenDropdown}>
<S.Input
ref={inputRef}
isSelected={!!selectedOption}
placeholder={selectedOption}
onInput={debounce(forceUpdate, 200)}
onFocus={handleOpenDropdown}
onBlur={handleBlur}
aria-label="Open drop down select"
/>
<S.ChevronRightIcon />
<S.Dropdown
ref={dropdownRef}
open={isDropdownOpen}
aria-hidden={!isDropdownOpen}
aria-label="drop down select"
>
{!!filteredOptions.length ? (
filteredOptions.map(option => (
<S.Option key={option} type="button" onClick={handleSelect(option)}>
{option}
</S.Option>
))
) : (
<S.Option>No result for "{value}"</S.Option>
)}
</S.Dropdown>
</S.Container>
);
};
export { Select };
|