import React, { Component, MouseEventHandler } from 'react'; import classes from 'component-classes'; import transform, { toTransformValue } from 'choerodon-ui/pro/lib/_util/transform'; import { transformZoomData } from 'choerodon-ui/shared/util'; import EventManager, { stopEvent } from '../_util/EventManager'; function cloneElement(element: any, props: any) { if (props.style && element.props.style) { props.style = { ...element.props.style, ...props.style }; } if (props.className && element.props.className) { props.className = `${element.props.className} ${props.className}`; } return React.cloneElement(element, props); } type DragCallbackData = { node: HTMLElement, x: number, y: number, deltaX: number, deltaY: number, lastX: number, lastY: number, }; export default class Resizable extends Component<any> { draggable: HTMLSpanElement | null; resizeEvent?: EventManager; componentWillUnmount(): void { const { resizeEvent } = this; if (resizeEvent) { resizeEvent.clear(); delete this.resizeEvent; } } handleMouseDown: MouseEventHandler<HTMLSpanElement> = (event) => { stopEvent(event); const { currentTarget } = event; const clientX = transformZoomData(event.clientX); const { resizeEvent = new EventManager() } = this; const clz = classes(currentTarget); this.resizeEvent = resizeEvent; clz.add('react-draggable-dragging'); resizeEvent .setTarget(currentTarget.ownerDocument) .addEventListener('mousemove', (e) => { transform(toTransformValue({ translateX: `${e.clientX - clientX}px`, }), currentTarget.style); }) .addEventListener('mouseup', (e) => { const { onResize } = this.props; if (onResize) { const x = transformZoomData(e.clientX) - clientX; const dragCallbackData: DragCallbackData = { x, y: 0, lastX: x, lastY: 0, deltaX: 0, deltaY: 0, node: currentTarget, }; onResize(event, dragCallbackData); } currentTarget.style.cssText = ''; resizeEvent.clear(); clz.remove('react-draggable-dragging'); }); }; saveDraggable = (draggable: HTMLSpanElement | null) => { this.draggable = draggable; }; render() { const { children, className } = this.props; const { props: { children: subchildren } } = children as any; return cloneElement(children, { className: className ? `${className} react-resizable` : 'react-resizable', children: [ subchildren, <span ref={this.saveDraggable} key="resizableHandle" className="column-resizable-handle" onMouseDown={this.handleMouseDown} />, ], }); } }