feat: Dropdown component
This commit is contained in:
parent
92a2071a04
commit
487bcf043b
@ -31,6 +31,7 @@ export {
|
||||
ButtonGroup,
|
||||
DateRange,
|
||||
Dialog,
|
||||
Dropdown,
|
||||
EmptyStudies,
|
||||
Icon,
|
||||
IconButton,
|
||||
|
||||
107
platform/ui/src/components/Dropdown/Dropdown.jsx
Normal file
107
platform/ui/src/components/Dropdown/Dropdown.jsx
Normal file
@ -0,0 +1,107 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import { Icon, Typography } from '@ohif/ui';
|
||||
|
||||
const Dropdown = ({ titleElement, title, list }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const element = useRef(null);
|
||||
|
||||
const renderTitleElement = () => {
|
||||
if (titleElement) {
|
||||
return titleElement;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex">
|
||||
<Typography>{title}</Typography>
|
||||
<Icon name="chevron-down" className="text-white ml-1" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const toggleList = () => {
|
||||
setOpen(s => !s);
|
||||
};
|
||||
|
||||
const handleClick = e => {
|
||||
if (element.current && !element.current.contains(e.target)) {
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
const renderList = () => {
|
||||
const itemsAmount = list.length;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
'absolute origin-top-right transition duration-300 transform top-100 right-0 mt-2 z-10 bg-primary-dark border border-secondary-main rounded shadow',
|
||||
{
|
||||
'scale-0': !open,
|
||||
'scale-100': open,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{list.map((item, idx) => (
|
||||
<div
|
||||
key={item.title}
|
||||
className={classnames(
|
||||
'flex px-4 py-2 cursor-pointer items-center transition duration-300 hover:bg-secondary-main',
|
||||
{
|
||||
'border-b border-secondary-main': itemsAmount !== idx + 1,
|
||||
}
|
||||
)}
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
|
||||
if (item.onClick) {
|
||||
item.onClick();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{!!item.icon && (
|
||||
<Icon name={item.icon} className="text-white w-4 mr-2" />
|
||||
)}
|
||||
<Typography>{item.title}</Typography>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('click', handleClick);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('click', handleClick);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div data-cy="dropdown" ref={element} className="relative">
|
||||
<div className="cursor-pointer flex items-center" onClick={toggleList}>
|
||||
{renderTitleElement()}
|
||||
</div>
|
||||
|
||||
{renderList()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Dropdown.propTypes = {
|
||||
titleElement: PropTypes.node,
|
||||
title: PropTypes.string.isRequired,
|
||||
/** Items to render in the select's drop down */
|
||||
list: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
title: PropTypes.string.isRequired,
|
||||
icon: PropTypes.object,
|
||||
onClick: PropTypes.func,
|
||||
link: PropTypes.string,
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
export default Dropdown;
|
||||
22
platform/ui/src/components/Dropdown/Dropdown.mdx
Normal file
22
platform/ui/src/components/Dropdown/Dropdown.mdx
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
name: Dropdown
|
||||
menu: General
|
||||
route: components/dropdown
|
||||
---
|
||||
|
||||
import { Playground, Props } from 'docz';
|
||||
import { Dropdown } from '@ohif/ui';
|
||||
|
||||
# Dropdown
|
||||
|
||||
...
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Dropdown } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Button} />
|
||||
1
platform/ui/src/components/Dropdown/index.js
Normal file
1
platform/ui/src/components/Dropdown/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './Dropdown';
|
||||
@ -2,6 +2,7 @@ import Button from './Button';
|
||||
import ButtonGroup from './ButtonGroup';
|
||||
import DateRange from './DateRange';
|
||||
import Dialog from './Dialog';
|
||||
import Dropdown from './Dropdown';
|
||||
import EmptyStudies from './EmptyStudies';
|
||||
import Icon from './Icon';
|
||||
import IconButton from './IconButton';
|
||||
@ -53,6 +54,7 @@ export {
|
||||
ButtonGroup,
|
||||
DateRange,
|
||||
Dialog,
|
||||
Dropdown,
|
||||
EmptyStudies,
|
||||
Icon,
|
||||
IconButton,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user