правочки
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import styles from './SearchableSelect.module.scss';
|
||||
import { DropdownPortal } from './DropdownPortal';
|
||||
import { Icon } from './Icon';
|
||||
import { texts } from '../../texts';
|
||||
|
||||
@@ -51,6 +52,7 @@ export function AsyncSearchableSelect<T>({
|
||||
const [error, setError] = React.useState<string | undefined>();
|
||||
|
||||
const rootRef = React.useRef<HTMLDivElement>(null);
|
||||
const menuRef = React.useRef<HTMLDivElement>(null);
|
||||
const searchRef = React.useRef<HTMLInputElement>(null);
|
||||
const listRef = React.useRef<HTMLDivElement>(null);
|
||||
const sentinelRef = React.useRef<HTMLDivElement>(null);
|
||||
@@ -103,7 +105,10 @@ export function AsyncSearchableSelect<T>({
|
||||
if (!open) return;
|
||||
|
||||
const onDocumentMouseDown = (e: MouseEvent): void => {
|
||||
if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);
|
||||
const target = e.target as Node;
|
||||
if (rootRef.current?.contains(target)) return;
|
||||
if (menuRef.current?.contains(target)) return;
|
||||
setOpen(false);
|
||||
};
|
||||
const onKeyDown = (e: KeyboardEvent): void => {
|
||||
if (e.key === 'Escape') setOpen(false);
|
||||
@@ -167,51 +172,49 @@ export function AsyncSearchableSelect<T>({
|
||||
<Icon name="chevron-down" size="sm" className={styles.chevron} />
|
||||
</button>
|
||||
|
||||
{open && (
|
||||
<div className={styles.menu}>
|
||||
<input
|
||||
ref={searchRef}
|
||||
className={styles.search}
|
||||
placeholder={searchPlaceholder}
|
||||
value={query}
|
||||
onChange={e => setQuery(e.target.value)}
|
||||
/>
|
||||
<div className={styles.list} ref={listRef}>
|
||||
{loading && <div className={styles.empty}>{texts.select.searching}</div>}
|
||||
{!loading && error && <div className={styles.errorText}>{error}</div>}
|
||||
{!loading && !error && items.length === 0 && (
|
||||
<div className={styles.empty}>{texts.select.nothingFound}</div>
|
||||
)}
|
||||
{!loading && !error && items.map(item => {
|
||||
const itemValue = getValue(item);
|
||||
const sub = getSublabel ? getSublabel(item) : undefined;
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
key={itemValue}
|
||||
className={`${styles.item} ${itemValue === value ? styles.selected : ''}`}
|
||||
onClick={() => pick(item)}
|
||||
>
|
||||
{getLabel(item)}
|
||||
{sub && <span className={styles.itemSub}>{sub}</span>}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
{!loading && !error && hasMore && (
|
||||
<div ref={sentinelRef} className={styles.sentinel}>
|
||||
{loadingMore && 'Загрузка...'}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{allowClear && value && (
|
||||
<div className={styles.clear}>
|
||||
<button type="button" className={styles.item} onClick={() => pick(undefined)}>
|
||||
{clearLabel}
|
||||
<DropdownPortal anchorRef={rootRef} open={open} className={styles.menu} menuRef={menuRef}>
|
||||
<input
|
||||
ref={searchRef}
|
||||
className={styles.search}
|
||||
placeholder={searchPlaceholder}
|
||||
value={query}
|
||||
onChange={e => setQuery(e.target.value)}
|
||||
/>
|
||||
<div className={styles.list} ref={listRef}>
|
||||
{loading && <div className={styles.empty}>{texts.select.searching}</div>}
|
||||
{!loading && error && <div className={styles.errorText}>{error}</div>}
|
||||
{!loading && !error && items.length === 0 && (
|
||||
<div className={styles.empty}>{texts.select.nothingFound}</div>
|
||||
)}
|
||||
{!loading && !error && items.map(item => {
|
||||
const itemValue = getValue(item);
|
||||
const sub = getSublabel ? getSublabel(item) : undefined;
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
key={itemValue}
|
||||
className={`${styles.item} ${itemValue === value ? styles.selected : ''}`}
|
||||
onClick={() => pick(item)}
|
||||
>
|
||||
{getLabel(item)}
|
||||
{sub && <span className={styles.itemSub}>{sub}</span>}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
{!loading && !error && hasMore && (
|
||||
<div ref={sentinelRef} className={styles.sentinel}>
|
||||
{loadingMore && 'Загрузка...'}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{allowClear && value && (
|
||||
<div className={styles.clear}>
|
||||
<button type="button" className={styles.item} onClick={() => pick(undefined)}>
|
||||
{clearLabel}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</DropdownPortal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user