overleaf/services/web/frontend/js/features/settings/components/emails/downshift-input.tsx
Timothée Alby e5051bcd1d Merge pull request #7765 from overleaf/ii-add-email-ui-affiliating-with-existing-institution
Add email with existing and non existing institution

GitOrigin-RevId: 331bc06f0ea289a82b403a910491e233f4eda4bb
2022-04-28 08:03:16 +00:00

114 lines
2.9 KiB
TypeScript

import { useState, useEffect } from 'react'
import { useCombobox } from 'downshift'
import classnames from 'classnames'
type DownshiftInputProps = {
items: string[]
inputValue: string
label: string
setValue: React.Dispatch<React.SetStateAction<string>>
} & React.InputHTMLAttributes<HTMLInputElement>
const filterItemsByInputValue = (
items: DownshiftInputProps['items'],
inputValue: DownshiftInputProps['inputValue']
) => items.filter(item => item.toLowerCase().includes(inputValue.toLowerCase()))
function DownshiftInput({
items,
inputValue,
placeholder,
label,
setValue,
disabled,
}: DownshiftInputProps) {
const [inputItems, setInputItems] = useState(items)
useEffect(() => {
setInputItems(items)
}, [items])
const {
isOpen,
getLabelProps,
getMenuProps,
getInputProps,
getComboboxProps,
getItemProps,
openMenu,
selectedItem,
} = useCombobox({
inputValue,
items: inputItems,
initialSelectedItem: inputValue,
onSelectedItemChange: ({ selectedItem }) => {
setValue(selectedItem ?? '')
},
onInputValueChange: ({ inputValue = '' }) => {
setInputItems(filterItemsByInputValue(items, inputValue))
},
onStateChange: ({ type }) => {
if (type === useCombobox.stateChangeTypes.FunctionOpenMenu) {
setInputItems(filterItemsByInputValue(items, inputValue))
}
},
})
return (
<div
className={classnames(
'ui-select-container ui-select-bootstrap dropdown',
{
open: isOpen && inputItems.length,
}
)}
>
<div {...getComboboxProps()} className="form-group mb-2">
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
<label {...getLabelProps()} className="sr-only">
{label}
</label>
<input
{...getInputProps({
onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value)
},
onFocus: () => {
if (!isOpen) {
openMenu()
}
},
})}
className="form-control"
type="text"
placeholder={placeholder}
disabled={disabled}
/>
</div>
<ul
{...getMenuProps()}
className="ui-select-choices ui-select-choices-content ui-select-dropdown dropdown-menu"
>
{inputItems.map((item, index) => (
<li
className="ui-select-choices-group"
key={`${item}${index}`}
{...getItemProps({ item, index })}
>
<div
className={classnames('ui-select-choices-row', {
active: selectedItem === item,
})}
>
<span className="ui-select-choices-row-inner">
<span>{item}</span>
</span>
</div>
</li>
))}
</ul>
</div>
)
}
export default DownshiftInput