dropdownItem.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import React from 'react';
  2. import cls from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import { cssClasses as css, strings } from '@douyinfe/semi-foundation/dropdown/constants';
  5. import DropdownContext from './context';
  6. import BaseComponent, { BaseProps } from '../_base/baseComponent';
  7. import { IconTick } from '@douyinfe/semi-icons';
  8. import { noop } from 'lodash';
  9. export type Type = 'primary' | 'secondary' | 'tertiary' | 'warning' | 'danger';
  10. export interface DropdownItemProps extends BaseProps {
  11. disabled?: boolean;
  12. selected?: boolean;
  13. onClick?: React.MouseEventHandler<HTMLLIElement>;
  14. onMouseEnter?: React.MouseEventHandler<HTMLLIElement>;
  15. onMouseLeave?: React.MouseEventHandler<HTMLLIElement>;
  16. onContextMenu?: React.MouseEventHandler<HTMLLIElement>;
  17. forwardRef?: (ele: HTMLLIElement) => void;
  18. type?: Type;
  19. active?: boolean;
  20. icon?: React.ReactNode;
  21. }
  22. const prefixCls = css.PREFIX;
  23. class DropdownItem extends BaseComponent<DropdownItemProps> {
  24. static propTypes = {
  25. children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
  26. name: PropTypes.string,
  27. disabled: PropTypes.bool,
  28. selected: PropTypes.bool,
  29. onClick: PropTypes.func,
  30. onMouseEnter: PropTypes.func,
  31. onMouseLeave: PropTypes.func,
  32. onContextMenu: PropTypes.func,
  33. className: PropTypes.string,
  34. style: PropTypes.object,
  35. forwardRef: PropTypes.func,
  36. type: PropTypes.oneOf(strings.ITEM_TYPE),
  37. active: PropTypes.bool,
  38. icon: PropTypes.node
  39. };
  40. static contextType = DropdownContext;
  41. static defaultProps = {
  42. disabled: false,
  43. divided: false,
  44. selected: false,
  45. onMouseEnter: noop,
  46. onMouseLeave: noop,
  47. forwardRef: noop,
  48. };
  49. render() {
  50. const { children, disabled, className, forwardRef, style, type, active, icon } = this.props;
  51. const { showTick } = this.context;
  52. const itemclass = cls(className, {
  53. [`${prefixCls}-item`]: true,
  54. [`${prefixCls}-item-disabled`]: disabled,
  55. [`${prefixCls}-item-withTick`]: showTick,
  56. [`${prefixCls}-item-${type}`]: type,
  57. [`${prefixCls}-item-active`]: active,
  58. });
  59. const events = {};
  60. if (!disabled) {
  61. ['onClick', 'onMouseEnter', 'onMouseLeave', 'onContextMenu'].forEach(eventName => {
  62. events[eventName] = this.props[eventName];
  63. });
  64. }
  65. let tick = null;
  66. switch (true) {
  67. case showTick && active:
  68. tick = <IconTick />;
  69. break;
  70. case showTick && !active:
  71. tick = <IconTick style={{ color: 'transparent' }} />;
  72. break;
  73. default:
  74. tick = null;
  75. break;
  76. }
  77. let iconContent = null;
  78. if (icon) {
  79. iconContent = (
  80. <div className={`${prefixCls}-item-icon`}>
  81. {icon}
  82. </div>
  83. );
  84. }
  85. return (
  86. <li role="menuitem" {...events} ref={ref => forwardRef(ref)} className={itemclass} style={style}>
  87. {tick}
  88. {iconContent}
  89. {children}
  90. </li>
  91. );
  92. }
  93. }
  94. export default DropdownItem;