dropdownItem.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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, { DropdownContextType } 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. context: DropdownContextType;
  42. static defaultProps = {
  43. disabled: false,
  44. divided: false,
  45. selected: false,
  46. onMouseEnter: noop,
  47. onMouseLeave: noop,
  48. forwardRef: noop,
  49. };
  50. render() {
  51. const { children, disabled, className, forwardRef, style, type, active, icon } = this.props;
  52. const { showTick } = this.context;
  53. const itemclass = cls(className, {
  54. [`${prefixCls}-item`]: true,
  55. [`${prefixCls}-item-disabled`]: disabled,
  56. [`${prefixCls}-item-withTick`]: showTick,
  57. [`${prefixCls}-item-${type}`]: type,
  58. [`${prefixCls}-item-active`]: active,
  59. });
  60. const events = {};
  61. if (!disabled) {
  62. ['onClick', 'onMouseEnter', 'onMouseLeave', 'onContextMenu'].forEach(eventName => {
  63. events[eventName] = this.props[eventName];
  64. });
  65. }
  66. let tick = null;
  67. switch (true) {
  68. case showTick && active:
  69. tick = <IconTick />;
  70. break;
  71. case showTick && !active:
  72. tick = <IconTick style={{ color: 'transparent' }} />;
  73. break;
  74. default:
  75. tick = null;
  76. break;
  77. }
  78. let iconContent = null;
  79. if (icon) {
  80. iconContent = (
  81. <div className={`${prefixCls}-item-icon`}>
  82. {icon}
  83. </div>
  84. );
  85. }
  86. return (
  87. <li role="menuitem" tabIndex={-1} aria-disabled={disabled} {...events} ref={ref => forwardRef(ref)} className={itemclass} style={style}>
  88. {tick}
  89. {iconContent}
  90. {children}
  91. </li>
  92. );
  93. }
  94. }
  95. export default DropdownItem;