1import React, { useCallback, useRef, useState } from 'react';
2import cn from 'classnames';
4import Flex from './Flex';
5import { ErrorText } from './Typography';
6import useOnClickOutside from 'indigo-react/lib/useOnClickOutside';
7import AccessoryIcon from './AccessoryIcon';
9// NOTE: if we really care about accessibility, we should pull in a dependency
10export default function SelectInput({
42 const [isOpen, setIsOpen] = useState(false);
45 // close select on outside clicks
46 useOnClickOutside(ref, useCallback(() => setIsOpen(false), [setIsOpen]));
48 const toggleOpen = useCallback(() => setIsOpen(isOpen => !isOpen), [
52 const onChange = value => {
53 // TODO: provide setValue here?
54 // construct a pseudo event that sets the value correctly
55 bind.onChange({ target: { value } });
59 // redefine accessory because we still want to ignore it from the ..rest above
60 accessory = <AccessoryIcon>{isOpen ? '⬆' : '⬇'}</AccessoryIcon>;
62 const text = options.find(o => o.value === data).text;
67 className={cn(className, 'mb1 us-none')}
71 pointerEvents: 'none',
72 cursor: 'not-allowed',
75 <Flex.Item as="label" className="f6 lh-tall" htmlFor={name}>
78 <Flex.Item as={Flex} row className="rel clickable" onClick={toggleOpen}>
82 'b b1 p3 outline-none',
85 'bg-white': !disabled,
93 'b-green3': visiblyPassed,
94 'b-black': focused && !visiblyPassed,
95 'b-yellow3': !focused && error,
96 'b-gray3': !focused && !error && !visiblyPassed,
103 {isOpen ? placeholder : text}
119 className="abs bg-white b-black b1 z10"
121 top: 'calc(100% + 4px)',
127 {options.map(option => (
130 className="pv2 ph3 hover-bg-grey3"
133 onChange(option.value);
142 <Flex.Item as={ErrorText} className="mv1">
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list