Open-source interactive fiction engine, powered by React, Redux and TypeScript. _ https://discoteque.pub/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

47 lines
1.3 KiB

import React, { FC, useState } from 'react';
import cn from 'classnames';
import * as styles from './Dropdown.styles';
import { useClickOutside } from 'react-click-outside-hook';
type ActivateFn = (toggleDropdown: () => void, label?: string, isOpen?: boolean) => React.ReactNode;
type ChildrenFn = (toggleDropdown: () => void) => React.ReactNode;
type Props = {
label?: string;
activate?: ActivateFn;
children: ChildrenFn;
}
const defaultActivate: ActivateFn = (toggleDropdown, label = 'Dropdown', isOpen = false) => (
<span onClick={toggleDropdown}>{label}&nbsp;{isOpen ? '▲' : '▼'}</span>
);
const Dropdown: FC<Props> = ({ label = 'Dropdown', activate = defaultActivate, children }) => {
const [isOpen, setIsOpen] = useState(false);
const [ref, hasClickedOutside] = useClickOutside()
const toggle = () => setIsOpen(!isOpen);
if (hasClickedOutside && isOpen) {
setIsOpen(false);
}
return (
<div className={styles.dropdownContainer} ref={ref}>
<span className={styles.activateContainer}>
{activate(toggle, label, isOpen)}
</span>
<div className={cn(
styles.dropdownContent,
{
[styles.dropdownContentOpen]: isOpen,
},
)}>
{isOpen && children(toggle)}
</div>
</div>
)
}
export default Dropdown;