Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 

199 Zeilen
5.4 KiB

  1. import React from "react";
  2. // nodejs library that concatenates classes
  3. import classNames from "classnames";
  4. // nodejs library to set properties for components
  5. import PropTypes from "prop-types";
  6. // @material-ui/core components
  7. import { makeStyles } from "@material-ui/core/styles";
  8. import MenuItem from "@material-ui/core/MenuItem";
  9. import MenuList from "@material-ui/core/MenuList";
  10. import ClickAwayListener from "@material-ui/core/ClickAwayListener";
  11. import Paper from "@material-ui/core/Paper";
  12. import Grow from "@material-ui/core/Grow";
  13. import Divider from "@material-ui/core/Divider";
  14. import Icon from "@material-ui/core/Icon";
  15. import Popper from "@material-ui/core/Popper";
  16. // core components
  17. import Button from "components/CustomButtons/Button.js";
  18. import styles from "assets/jss/nextjs-material-kit/components/customDropdownStyle.js";
  19. const useStyles = makeStyles(styles);
  20. export default function CustomDropdown(props) {
  21. const [anchorEl, setAnchorEl] = React.useState(null);
  22. const handleClick = event => {
  23. if (anchorEl && anchorEl.contains(event.target)) {
  24. setAnchorEl(null);
  25. } else {
  26. setAnchorEl(event.currentTarget);
  27. }
  28. };
  29. const handleClose = param => {
  30. setAnchorEl(null);
  31. if (props && props.onClick) {
  32. props.onClick(param);
  33. }
  34. };
  35. const handleCloseAway = event => {
  36. if (anchorEl.contains(event.target)) {
  37. return;
  38. }
  39. setAnchorEl(null);
  40. };
  41. const classes = useStyles();
  42. const {
  43. buttonText,
  44. buttonIcon,
  45. dropdownList,
  46. buttonProps,
  47. dropup,
  48. dropdownHeader,
  49. caret,
  50. hoverColor,
  51. left,
  52. rtlActive,
  53. noLiPadding,
  54. navDropdown
  55. } = props;
  56. const caretClasses = classNames({
  57. [classes.caret]: true,
  58. [classes.caretActive]: Boolean(anchorEl),
  59. [classes.caretRTL]: rtlActive
  60. });
  61. const dropdownItem = classNames({
  62. [classes.dropdownItem]: true,
  63. [classes[hoverColor + "Hover"]]: true,
  64. [classes.noLiPadding]: noLiPadding,
  65. [classes.dropdownItemRTL]: rtlActive
  66. });
  67. let icon = null;
  68. switch (typeof buttonIcon) {
  69. case "object":
  70. icon = <props.buttonIcon className={classes.buttonIcon} />;
  71. break;
  72. case "string":
  73. icon = <Icon className={classes.buttonIcon}>{props.buttonIcon}</Icon>;
  74. break;
  75. default:
  76. icon = null;
  77. break;
  78. }
  79. return (
  80. <div>
  81. <div>
  82. <Button
  83. aria-label="Notifications"
  84. aria-owns={anchorEl ? "menu-list" : null}
  85. aria-haspopup="true"
  86. {...buttonProps}
  87. onClick={handleClick}
  88. >
  89. {icon}
  90. {buttonText !== undefined ? buttonText : null}
  91. {caret ? <b className={caretClasses} /> : null}
  92. </Button>
  93. </div>
  94. <Popper
  95. open={Boolean(anchorEl)}
  96. anchorEl={anchorEl}
  97. transition
  98. disablePortal
  99. placement={
  100. dropup
  101. ? left
  102. ? "top-start"
  103. : "top"
  104. : left
  105. ? "bottom-start"
  106. : "bottom"
  107. }
  108. className={classNames({
  109. [classes.popperClose]: !anchorEl,
  110. [classes.popperResponsive]: true,
  111. [classes.pooperNav]: Boolean(anchorEl) && navDropdown
  112. })}
  113. >
  114. {() => (
  115. <Grow
  116. in={Boolean(anchorEl)}
  117. id="menu-list"
  118. style={
  119. dropup
  120. ? { transformOrigin: "0 100% 0" }
  121. : { transformOrigin: "0 0 0" }
  122. }
  123. >
  124. <Paper className={classes.dropdown}>
  125. <ClickAwayListener onClickAway={handleCloseAway}>
  126. <MenuList role="menu" className={classes.menuList}>
  127. {dropdownHeader !== undefined ? (
  128. <MenuItem
  129. onClick={() => handleClose(dropdownHeader)}
  130. className={classes.dropdownHeader}
  131. >
  132. {dropdownHeader}
  133. </MenuItem>
  134. ) : null}
  135. {dropdownList.map((prop, key) => {
  136. if (prop.divider) {
  137. return (
  138. <Divider
  139. key={key}
  140. onClick={() => handleClose("divider")}
  141. className={classes.dropdownDividerItem}
  142. />
  143. );
  144. }
  145. return (
  146. <MenuItem
  147. key={key}
  148. onClick={() => handleClose(prop)}
  149. className={dropdownItem}
  150. >
  151. {prop}
  152. </MenuItem>
  153. );
  154. })}
  155. </MenuList>
  156. </ClickAwayListener>
  157. </Paper>
  158. </Grow>
  159. )}
  160. </Popper>
  161. </div>
  162. );
  163. }
  164. CustomDropdown.defaultProps = {
  165. caret: true,
  166. hoverColor: "primary"
  167. };
  168. CustomDropdown.propTypes = {
  169. hoverColor: PropTypes.oneOf([
  170. "black",
  171. "primary",
  172. "info",
  173. "success",
  174. "warning",
  175. "danger",
  176. "rose"
  177. ]),
  178. buttonText: PropTypes.node,
  179. buttonIcon: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
  180. dropdownList: PropTypes.array,
  181. buttonProps: PropTypes.object,
  182. dropup: PropTypes.bool,
  183. dropdownHeader: PropTypes.node,
  184. rtlActive: PropTypes.bool,
  185. caret: PropTypes.bool,
  186. left: PropTypes.bool,
  187. noLiPadding: PropTypes.bool,
  188. navDropdown: PropTypes.bool,
  189. // function that retuns the selected item
  190. onClick: PropTypes.func
  191. };