You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
spa_instat_tv/src/features/Combobox/index.tsx

115 lines
2.7 KiB

import { useRouteMatch } from 'react-router-dom'
import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map'
import { useLexicsStore } from 'features/LexicsStore'
import { PAGES } from 'config'
import { T9n } from 'features/T9n'
import { OutsideClick } from 'features/OutsideClick'
import {
Column,
Error,
InputWrapper,
InputStyled,
Label,
LabelTitle,
} from 'features/Common/Input/styled'
import { Props, Option } from './types'
import { useCombobox } from './hooks'
import {
PopOver,
ListOption,
} from './styled'
import { Arrow } from './components/Arrow'
export const Combobox = <T extends Option>(props: Props<T>) => {
const {
className,
disabled,
error,
label,
labelLexic,
labelWidth,
maxLength,
noSearch,
title,
withError,
wrapperHeight,
} = props
const {
index,
inputFieldRef,
isOpen,
onInputBlur,
onKeyDown,
onOptionSelect,
onOutsideClick,
onQueryChange,
open,
options,
popoverRef,
query,
toggle,
} = useCombobox(props)
const { translate } = useLexicsStore()
const isUserAccountPage = useRouteMatch(PAGES.useraccount)?.path === PAGES.useraccount
return (
<Column isUserAccountPage={isUserAccountPage} className={className}>
<InputWrapper
error={error}
wrapperHeight={wrapperHeight}
>
<Label>
<LabelTitle
labelWidth={labelWidth}
isUserAccountPage={isUserAccountPage}
>
{labelLexic ? <T9n t={labelLexic} /> : label}
</LabelTitle>
<InputStyled
maxLength={maxLength}
onBlur={onInputBlur}
onFocus={open}
ref={inputFieldRef}
autoComplete='off'
title={title}
value={query}
disabled={disabled}
readOnly={noSearch}
onChange={onQueryChange}
onKeyDown={onKeyDown}
placeholder={translate(labelLexic || '')}
isUserAccountPage={isUserAccountPage}
/>
</Label>
<Arrow
isExpanded={isOpen}
toggle={toggle}
/>
{isOpen && !isEmpty(options) && (
<OutsideClick onClick={onOutsideClick}>
<PopOver ref={popoverRef}>
{map(options, (option, i) => (
<ListOption
onClick={(e) => onOptionSelect(option.name, e)}
aria-selected={index === i}
isHighlighted={index === i}
key={option.id}
>
{option.name}
</ListOption>
))}
</PopOver>
</OutsideClick>
)}
</InputWrapper>
{withError && <Error t={error || ''} />}
</Column>
)
}