1
0

dropdownItem.tsx 3.4 KB

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