glass-app-manager
Version:
Informatica's Glass Framework CLI for bootstrapping
107 lines (95 loc) • 4.26 kB
JavaScript
// @flow
import * as React from "react";
import classNames from "classnames";
import Checkbox from "../checkbox/Checkbox";
import DownshiftWrapper from "./DownshiftWrapper";
import DropdownIcon from "./DropdownIcon";
import Pill from "../pill/Pill";
import { highlightQuery } from "./utils";
type OptionDefinition = {
text: string,
value: any,
};
type Options = Array<OptionDefinition>;
type MultiDropdownProps = {
checkbox?: boolean,
className?: string,
multiple: boolean,
placeholder?: string,
search?: boolean,
selectedItems?: any,
visibleOptions: Options,
};
export default function MultiDropdown(props: MultiDropdownProps) {
const { checkbox, placeholder, search, visibleOptions } = props;
const inputRef = React.createRef();
const focusInputBox = React.useCallback(() => {
inputRef.current.focus();
}, [inputRef]);
return (
<DownshiftWrapper {...props}>
{({
getInputProps,
getItemProps,
getToggleButtonProps,
getMenuProps,
handleChange,
highlightedIndex,
inputValue,
isOpen,
selectedItem,
}) => (
<div className={classNames("dropdown", props.className)}>
<div className="dropdown__bar">
<div className="dropdown__pills" onClick={focusInputBox}>
{selectedItem.length > 0
? selectedItem.map((item, index) => (
<Pill
className="dropdown__pill"
key={item.value}
onClick={e => e.stopPropagation()}
onClose={() => handleChange(selectedItem[index])}>
{item.text}
</Pill>
))
: null}
<input
className="dropdown__search"
ref={inputRef}
{...getInputProps({ placeholder: selectedItem.length > 0 ? null : placeholder })}
/>
</div>
<DropdownIcon {...getToggleButtonProps()} />
</div>
{isOpen ? (
<div className="dropdown__menu" {...getMenuProps()}>
{visibleOptions.map((item, index) => (
<div
className={classNames({
dropdown__item: true,
"dropdown__item--selected": selectedItem.includes(item),
"dropdown__item--active": highlightedIndex === index,
})}
{...getItemProps({
key: item.value,
item,
index,
})}>
{checkbox ? (
<Checkbox checked={selectedItem.includes(item)} onChange={() => {}}>
{inputValue && search ? highlightQuery(item.text, inputValue) : item.text}
</Checkbox>
) : inputValue && search ? (
highlightQuery(item.text, inputValue)
) : (
<span>{item.text}</span>
)}
</div>
))}
</div>
) : null}
</div>
)}
</DownshiftWrapper>
);
}