CarouselIndicator.tsx 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* eslint-disable jsx-a11y/no-static-element-interactions */
  2. /* eslint-disable jsx-a11y/click-events-have-key-events */
  3. import React, { ReactNode } from "react";
  4. import cls from 'classnames';
  5. import PropTypes from 'prop-types';
  6. import { cssClasses, strings } from '@douyinfe/semi-foundation/carousel/constants';
  7. import { CarouselIndicatorProps } from "./interface";
  8. import getDataAttr from "@douyinfe/semi-foundation/utils/getDataAttr";
  9. class CarouselIndicator extends React.PureComponent<CarouselIndicatorProps> {
  10. static propTypes = {
  11. activeKey: PropTypes.number,
  12. className: PropTypes.string,
  13. position: PropTypes.oneOf(strings.POSITION_MAP),
  14. size: PropTypes.oneOf(strings.SIZE),
  15. style: PropTypes.object,
  16. theme: PropTypes.oneOf(strings.THEME_MAP),
  17. total: PropTypes.number,
  18. onIndicatorChange: PropTypes.func,
  19. type: PropTypes.oneOf(strings.TYPE_MAP),
  20. trigger: PropTypes.oneOf(strings.TRIGGER)
  21. };
  22. onIndicatorChange = (activeIndex: number): void => {
  23. this.props.onIndicatorChange(activeIndex);
  24. };
  25. handleIndicatorClick = (activeIndex: number): void => {
  26. const { trigger } = this.props;
  27. if (trigger === 'click') {
  28. this.onIndicatorChange(activeIndex);
  29. }
  30. }
  31. handleIndicatorHover = (activeIndex: number): void => {
  32. const { trigger } = this.props;
  33. if (trigger === 'hover') {
  34. this.onIndicatorChange(activeIndex);
  35. }
  36. }
  37. renderIndicatorContent(): ReactNode {
  38. const { total, theme, size, activeIndex } = this.props;
  39. const indicatorContent: ReactNode[] = [];
  40. for (let i = 0; i < total; i++) {
  41. indicatorContent.push(
  42. <span
  43. // role='none'
  44. key={i}
  45. data-index={i}
  46. className={cls([`${cssClasses.CAROUSEL_INDICATOR}-item`], {
  47. [`${cssClasses.CAROUSEL_INDICATOR}-item-active`]: i === activeIndex,
  48. [`${cssClasses.CAROUSEL_INDICATOR}-item-${theme}`]: theme,
  49. [`${cssClasses.CAROUSEL_INDICATOR}-item-${size}`]: size,
  50. })}
  51. onClick={()=>this.handleIndicatorClick(i)}
  52. onMouseEnter={()=>this.handleIndicatorHover(i)}
  53. ></span>
  54. );
  55. }
  56. return indicatorContent;
  57. }
  58. render(): ReactNode {
  59. const { type, size, theme, style, className, position, ...restProps } = this.props;
  60. const classNames = cls(className, {
  61. [cssClasses.CAROUSEL_INDICATOR]: true,
  62. [`${cssClasses.CAROUSEL_INDICATOR}-${type}`]: type,
  63. [`${cssClasses.CAROUSEL_INDICATOR}-${position}`]: position,
  64. });
  65. const indicatorContent = this.renderIndicatorContent();
  66. return (
  67. <div className={classNames} style={style} {...getDataAttr(restProps)}>
  68. {indicatorContent}
  69. </div>
  70. );
  71. }
  72. }
  73. export default CarouselIndicator;