resizeHandler.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import React, { Children, createRef, ReactNode, useContext } from 'react';
  2. import classNames from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import { ResizeHandlerFoundation, ResizeHandlerAdapter } from '@douyinfe/semi-foundation/resizable/foundation';
  5. import { cssClasses } from '@douyinfe/semi-foundation/resizable/constants';
  6. import { Direction, HandlerCallback } from '@douyinfe/semi-foundation/resizable/types';
  7. import BaseComponent from '../../_base/baseComponent';
  8. import { ResizeContext, ResizeContextProps } from './resizeContext';
  9. import { IconHandle } from '@douyinfe/semi-icons';
  10. const prefixCls = cssClasses.PREFIX;
  11. export interface ResizeHandlerProps {
  12. children?: ReactNode;
  13. direction?: Direction;
  14. onResizeStart?: HandlerCallback;
  15. className?: string;
  16. disabled?: boolean;
  17. style?: React.CSSProperties
  18. }
  19. export interface ResizeHandlerState {
  20. }
  21. class ResizeHandler extends BaseComponent<ResizeHandlerProps, ResizeHandlerState> {
  22. static propTypes = {
  23. children: PropTypes.node,
  24. direction: PropTypes.string,
  25. onResizeStart: PropTypes.func,
  26. className: PropTypes.string,
  27. disabled: PropTypes.bool,
  28. style: PropTypes.object,
  29. };
  30. static defaultProps: Partial<ResizeHandlerProps> = {
  31. };
  32. constructor(props: ResizeHandlerProps) {
  33. super(props);
  34. this.state = {
  35. };
  36. this.handlerRef = createRef();
  37. this.foundation = new ResizeHandlerFoundation(this.adapter);
  38. this.handlerIndex = -1;
  39. }
  40. componentDidMount() {
  41. this.foundation.init();
  42. if (this.handlerIndex === -1) {
  43. this.handlerIndex = this.context.registerHandler(this.handlerRef);
  44. }
  45. }
  46. componentDidUpdate(_prevProps: ResizeHandlerProps) {
  47. }
  48. componentWillUnmount() {
  49. this.foundation.destroy();
  50. }
  51. foundation: ResizeHandlerFoundation;
  52. onMouseDown = (e: MouseEvent) => {
  53. const { notifyResizeStart } = this.context;
  54. notifyResizeStart(this.handlerIndex, e, 'mouse');
  55. }
  56. onTouchStart = (e: TouchEvent) => {
  57. const { notifyResizeStart } = this.context;
  58. notifyResizeStart(this.handlerIndex, e.targetTouches[0], 'touch');
  59. }
  60. get adapter(): ResizeHandlerAdapter<ResizeHandlerProps, ResizeHandlerState> {
  61. return {
  62. ...super.adapter,
  63. registerEvents: () => {
  64. this.handlerRef.current.addEventListener('mousedown', this.onMouseDown);
  65. this.handlerRef.current.addEventListener('touchstart', this.onTouchStart);
  66. },
  67. unregisterEvents: () => {
  68. this.handlerRef.current.removeEventListener('mousedown', this.onMouseDown);
  69. this.handlerRef.current.removeEventListener('touchstart', this.onTouchStart);
  70. },
  71. };
  72. }
  73. getHandler: () => HTMLElement = () => {
  74. return this.handlerRef.current;
  75. }
  76. static contextType = ResizeContext;
  77. context: ResizeContextProps;
  78. handlerRef: React.RefObject<HTMLDivElement>
  79. handlerIndex: number;
  80. render() {
  81. const { style, className, children } = this.props;
  82. const { direction } = this.context;
  83. return (
  84. <div
  85. className={classNames(className, prefixCls + '-handler', prefixCls + '-handler-' + direction)}
  86. style={style}
  87. ref={this.handlerRef}
  88. >
  89. {children ?? <IconHandle size='inherit' style={{
  90. rotate: this.context.direction === 'horizontal' ? '0deg' : '90deg',
  91. }}/>}
  92. </div>
  93. );
  94. }
  95. }
  96. export default ResizeHandler;