diff options
Diffstat (limited to 'packages/instant/src/components/ui/dropdown.tsx')
-rw-r--r-- | packages/instant/src/components/ui/dropdown.tsx | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/packages/instant/src/components/ui/dropdown.tsx b/packages/instant/src/components/ui/dropdown.tsx new file mode 100644 index 000000000..2bc552ab4 --- /dev/null +++ b/packages/instant/src/components/ui/dropdown.tsx @@ -0,0 +1,127 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { ColorOption } from '../../style/theme'; +import { zIndex } from '../../style/z_index'; + +import { Container } from './container'; +import { Flex } from './flex'; +import { Icon } from './icon'; +import { Text } from './text'; + +export interface DropdownItemConfig { + text: string; + onClick?: () => void; +} + +export interface DropdownProps { + value: string; + label: string; + items: DropdownItemConfig[]; +} + +export interface DropdownState { + isOpen: boolean; +} + +export class Dropdown extends React.Component<DropdownProps, DropdownState> { + public static defaultProps = { + items: [ + { + text: 'Item 1', + }, + { + text: 'Item 2', + }, + ], + }; + public state: DropdownState = { + isOpen: false, + }; + public render(): React.ReactNode { + const { value, label, items } = this.props; + const { isOpen } = this.state; + const hasItems = !_.isEmpty(items); + const borderRadius = isOpen ? '4px 4px 0px 0px' : '4px'; + return ( + <Container position="relative"> + <Container + cursor={hasItems ? 'pointer' : undefined} + onClick={this._handleDropdownClick} + hasBoxShadow={true} + borderRadius={borderRadius} + border="1px solid" + borderColor={ColorOption.feintGrey} + padding="0.8em" + borderBottom="1px solid" + > + <Flex justify="space-between"> + <Text fontSize="16px" lineHeight="19px" fontColor={ColorOption.darkGrey}> + {value} + </Text> + <Container> + <Text fontSize="16px" lineHeight="17px" fontColor={ColorOption.lightGrey}> + {label} + </Text> + {hasItems && ( + <Container marginLeft="5px" display="inline-block" position="relative" bottom="2px"> + <Icon padding="3px" icon="chevron" width={12} stroke={ColorOption.grey} /> + </Container> + )} + </Container> + </Flex> + </Container> + {isOpen && ( + <Container + width="100%" + position="absolute" + onClick={this._closeDropdown} + backgroundColor={ColorOption.white} + hasBoxShadow={true} + zIndex={zIndex.dropdownItems} + > + {_.map(items, (item, index) => ( + <DropdownItem key={item.text} {...item} isLast={index === items.length - 1} /> + ))} + </Container> + )} + </Container> + ); + } + private readonly _handleDropdownClick = (): void => { + if (_.isEmpty(this.props.items)) { + return; + } + this.setState({ + isOpen: !this.state.isOpen, + }); + }; + private readonly _closeDropdown = (): void => { + this.setState({ + isOpen: false, + }); + }; +} + +export interface DropdownItemProps extends DropdownItemConfig { + text: string; + onClick?: () => void; + isLast: boolean; +} + +export const DropdownItem: React.StatelessComponent<DropdownItemProps> = ({ text, onClick, isLast }) => ( + <Container + onClick={onClick} + cursor="pointer" + darkenOnHover={true} + backgroundColor={ColorOption.white} + padding="0.8em" + borderTop="0" + border="1px solid" + borderRadius={isLast ? '0px 0px 4px 4px' : undefined} + width="100%" + borderColor={ColorOption.feintGrey} + > + <Text>{text}</Text> + </Container> +); |