// TODO: Probably worth merging this dropdown and the one within features/batch import * as React from 'react'; import { Manager, Reference, Popper } from 'react-popper'; import styled from '@emotion/styled'; import { Box, FlameBoxProps } from '@lightspeed/flame/Core'; import { themeGet } from '@styled-system/theme-get'; import enhanceWithClickOutside from 'react-click-outside'; const Wrapper = styled('div')` position: relative; `; const DropdownWrapper = styled(Box)(props => ({ // @ts-ignore ...props.popperStyles, // overriding popper styles pointerEvents: 'auto', opacity: 1, top: '10px', zIndex: 2, // end overriding popper styles backgroundColor: themeGet('colors.white')(props), borderRadius: themeGet('radii.radius-2')(props), boxShadow: '0 0 0 0.0625rem rgba(12, 13, 13, 0.15), 0 0.1875rem 0.375rem rgba(12, 13, 13, 0.15)', })); const Arrow = styled('span')` display: block; ::after, ::before { border-style: solid; border-color: transparent; content: ' '; height: 0; width: 0; position: absolute; pointer-events: none; bottom: 100%; left: ${themeGet('space.4')}; } ::after { border-bottom-color: ${themeGet('colors.white')}; border-bottom-width: 6px; border-left-width: 7px; border-right-width: 7px; } ::before { border-bottom-color: ${themeGet('colors.textDimmed')}; border-bottom-width: 7px; border-left-width: 7px; border-right-width: 7px; } `; const modifiers = { flip: { enabled: false }, preventOverflow: { enabled: false }, hide: { enabled: false }, }; interface Props extends FlameBoxProps { refComponent: (props: { toggleOpen: () => void }) => React.ReactNode; children: (props: { toggleOpen: () => void }) => React.ReactNode; } interface State { isOpen: boolean; } class BaseDropdown extends React.Component { constructor(props: Props) { super(props); this.state = { isOpen: false, }; this.toggleOpen = this.toggleOpen.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); this.handleKeyEvent = this.handleKeyEvent.bind(this); } componentDidMount() { document.addEventListener('keyup', this.handleKeyEvent); } componentWillUnmount() { document.removeEventListener('keyup', this.handleKeyEvent); } handleKeyEvent(event: KeyboardEvent) { const { isOpen } = this.state; if (event.key === 'Escape' && isOpen) { event.preventDefault(); this.toggleOpen(); } } toggleOpen() { this.setState(({ isOpen }) => ({ isOpen: !isOpen, })); } handleClickOutside() { this.setState({ isOpen: false, }); } render() { const { isOpen } = this.state; const { refComponent, children, ...restProps } = this.props; return ( {({ ref }) => (
{refComponent && refComponent({ toggleOpen: this.toggleOpen })}
)}
{isOpen && ( {({ ref, style }) => ( // @ts-ignore {typeof children === 'function' ? children({ toggleOpen: this.toggleOpen }) : children} )} )}
); } } const Dropdown = enhanceWithClickOutside(BaseDropdown); export default Dropdown;