index.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import React from 'react';
  2. import classNames from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import ConfigContext from '../configProvider/context';
  5. import { cssClasses, strings, numbers } from '@douyinfe/semi-foundation/popover/constants';
  6. import Tooltip, { ArrowBounding, Position, Trigger } from '../tooltip/index';
  7. import Arrow from './Arrow';
  8. import '@douyinfe/semi-foundation/popover/popover.scss';
  9. import { BaseProps } from '../_base/baseComponent';
  10. import { Motion } from '../_base/base';
  11. export { ArrowProps } from './Arrow';
  12. declare interface ArrowStyle {
  13. borderColor?: string;
  14. backgroundColor?: string;
  15. borderOpacity?: string | number;
  16. }
  17. export interface PopoverProps extends BaseProps {
  18. children?: React.ReactNode;
  19. content?: React.ReactNode;
  20. visible?: boolean;
  21. autoAdjustOverflow?: boolean;
  22. motion?: Motion;
  23. position?: Position;
  24. mouseEnterDelay?: number;
  25. mouseLeaveDelay?: number;
  26. trigger?: Trigger;
  27. contentClassName?: string | any[];
  28. onVisibleChange?: (visible: boolean) => void;
  29. showArrow?: boolean;
  30. spacing?: number;
  31. stopPropagation?: boolean | string;
  32. arrowStyle?: ArrowStyle;
  33. arrowBounding?: ArrowBounding;
  34. arrowPointAtCenter?: boolean;
  35. prefixCls?: string;
  36. rePosKey?: string | number;
  37. getPopupContainer?: () => HTMLElement;
  38. zIndex?: number;
  39. }
  40. export interface PopoverState {
  41. popConfirmVisible: boolean;
  42. }
  43. const positionSet = strings.POSITION_SET;
  44. const triggerSet = strings.TRIGGER_SET;
  45. class Popover extends React.PureComponent<PopoverProps, PopoverState> {
  46. static contextType = ConfigContext;
  47. static propTypes = {
  48. children: PropTypes.node,
  49. content: PropTypes.node,
  50. visible: PropTypes.bool,
  51. autoAdjustOverflow: PropTypes.bool,
  52. motion: PropTypes.oneOfType([PropTypes.bool, PropTypes.object, PropTypes.func]),
  53. position: PropTypes.oneOf(positionSet),
  54. // getPopupContainer: PropTypes.func,
  55. mouseEnterDelay: PropTypes.number,
  56. mouseLeaveDelay: PropTypes.number,
  57. trigger: PropTypes.oneOf(triggerSet).isRequired,
  58. contentClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
  59. onVisibleChange: PropTypes.func,
  60. style: PropTypes.object,
  61. spacing: PropTypes.number,
  62. zIndex: PropTypes.number,
  63. showArrow: PropTypes.bool,
  64. arrowStyle: PropTypes.shape({
  65. borderColor: PropTypes.string,
  66. backgroundColor: PropTypes.string,
  67. borderOpacity: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  68. }),
  69. arrowPointAtCenter: PropTypes.bool,
  70. arrowBounding: PropTypes.object,
  71. prefixCls: PropTypes.string,
  72. };
  73. static defaultProps = {
  74. arrowBounding: numbers.ARROW_BOUNDING,
  75. showArrow: false,
  76. autoAdjustOverflow: true,
  77. zIndex: numbers.DEFAULT_Z_INDEX,
  78. motion: true,
  79. trigger: 'hover',
  80. cancelText: 'No',
  81. okText: 'Yes',
  82. position: 'bottom',
  83. prefixCls: cssClasses.PREFIX,
  84. };
  85. constructor(props: PopoverProps) {
  86. super(props);
  87. this.state = {
  88. popConfirmVisible: false,
  89. };
  90. }
  91. renderPopCard() {
  92. const { content, contentClassName, prefixCls } = this.props;
  93. const { direction } = this.context;
  94. const popCardCls = classNames(
  95. prefixCls,
  96. contentClassName,
  97. {
  98. [`${prefixCls}-rtl`]: direction === 'rtl',
  99. }
  100. );
  101. return (
  102. <div className={popCardCls}>
  103. <div className={`${prefixCls}-content`}>{content}</div>
  104. </div>
  105. );
  106. }
  107. render() {
  108. const {
  109. children,
  110. prefixCls,
  111. showArrow,
  112. arrowStyle = {},
  113. arrowBounding,
  114. position,
  115. style,
  116. ...attr
  117. } = this.props;
  118. let { spacing } = this.props;
  119. const popContent = this.renderPopCard();
  120. const arrowProps = {
  121. position,
  122. className: '',
  123. popStyle: style,
  124. arrowStyle,
  125. };
  126. const arrow = showArrow ? <Arrow {...arrowProps} /> : false;
  127. if (typeof spacing !== 'number') {
  128. spacing = showArrow ? numbers.SPACING_WITH_ARROW : numbers.SPACING;
  129. }
  130. return (
  131. <Tooltip
  132. {...(attr as any)}
  133. position={position}
  134. style={style}
  135. content={popContent}
  136. prefixCls={prefixCls}
  137. spacing={spacing}
  138. showArrow={arrow}
  139. arrowBounding={arrowBounding}
  140. >
  141. {children}
  142. </Tooltip>
  143. );
  144. }
  145. }
  146. export default Popover;