Skip to content

Instantly share code, notes, and snippets.

@heorhii1
Created May 28, 2020 18:21
Show Gist options
  • Save heorhii1/23fcb0dca50f0188b786d26f99716d7b to your computer and use it in GitHub Desktop.
Save heorhii1/23fcb0dca50f0188b786d26f99716d7b to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import styles from './Dropdown.module.scss';
export const Dropdown = ({
onClick = () => {},
label,
data,
title,
multiple,
value,
/* eslint-disable no-unused-vars */
classNames,
}) => {
const [selected, setSelected] = useState(multiple ? [] : undefined);
const [display, setDisplay] = useState(true);
const isSelected = (index) => (multiple ? selected.includes(index) : selected === index);
const handleClick = async (e, i) => {
let selectedValue;
if (multiple) {
if (isSelected(i)) {
selectedValue = selected.filter((v) => v !== i);
} else {
selectedValue = [...selected, i];
}
} else {
selectedValue = i;
}
await setSelected(selectedValue);
const newValue = multiple ? data.filter((_, index) => selectedValue.includes(index)) : e;
await onClick(newValue);
};
const chooseAll = () => {
setSelected(data.map((a, i) => i));
onClick(data.map((a) => a));
};
useEffect(() => {
const searchIndex = data?.indexOf(value);
if (searchIndex >= 0) {
handleClick(value, searchIndex);
}
}, [value]);
const arr = data.map((e, i) => (
<div
role="menuitem"
tabIndex="0"
className={[styles.elem, isSelected(i) ? styles.active : ''].join(' ')}
onClick={() => handleClick(e, i)}
onKeyDown={() => {}}
>
{e?.value || e?.name || (typeof e === 'string' ? e : '')}
</div>
));
if (multiple) {
arr.unshift(
<div
className={styles.elem}
role="menuitem"
tabIndex="0"
onClick={chooseAll}
onKeyDown={() => {}}
>
(Вибрати все)
</div>,
);
}
return (
<div className={[styles.container, classNames.root].join(' ')}>
<div
role="menuitem"
tabIndex="0"
className={[styles.lable, classNames.label].join(' ')}
onClick={() => setDisplay(true)}
onKeyDown={() => {}}
>
<p className={styles.title}>{title}</p>
<span>
{(!selected?.length && !Number.isNaN(Number(selected)))
|| selected?.length > 0
? multiple
? `Вибрано ${selected.length} елементи`
: data[selected]?.value || data[selected]?.name || data[selected]
: label}
</span>
<div className={[styles.arrow, classNames.arrow].join(' ')} />
</div>
{display && (
<div
id="list"
className={styles.list}
onMouseLeave={() => setDisplay(false)}
>
{arr}
</div>
)}
</div>
);
};
Dropdown.defaultProps = {
onClick: () => {},
title: '',
label: <span>&nbsp;&nbsp;</span>,
data: [],
multiple: false,
value: '',
classNames: PropTypes.exact({
root: '',
arrow: '',
label: '',
list: '',
}),
};
Dropdown.propTypes = {
onClick: PropTypes.func,
title: PropTypes.string,
label: PropTypes.any,
data: PropTypes.array,
multiple: PropTypes.bool,
value: PropTypes.string,
classNames: {
root: PropTypes.string,
arrow: PropTypes.string,
label: PropTypes.string,
list: PropTypes.string,
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment