All files ResizableBox.js

85.71% Statements 12/14
80% Branches 8/10
100% Functions 4/4
84.62% Lines 11/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99                                    1x         6x                 7x               7x     6x 1x 1x 1x 1x                                                     7x   7x                                            
// @flow
import * as React from 'react';
import type {Node as ReactNode, Element as ReactElement} from 'react';
import PropTypes from 'prop-types';
 
import Resizable from './Resizable';
import {resizableProps} from "./propTypes";
import type {ResizeCallbackData, ResizableBoxState} from './propTypes';
 
// ElementConfig gives us an object type where all items present in `defaultProps` are made optional.
// <ResizableBox> does not have defaultProps, so we can use this type to tell Flow that we don't
// care about that and will handle it in <Resizable> instead.
// A <ResizableBox> can also have a `style` property.
type ResizableBoxProps = {|...React.ElementConfig<typeof Resizable>, style?: Object, children?: ReactElement<any>|};
 
export default class ResizableBox extends React.Component<ResizableBoxProps, ResizableBoxState> {
 
  // PropTypes are identical to <Resizable>, except that children are not strictly required to be present.
  static propTypes = {
    ...resizableProps,
    children: PropTypes.element,
  };
 
  state: ResizableBoxState = {
    width: this.props.width,
    height: this.props.height,
    propsWidth: this.props.width,
    propsHeight: this.props.height,
  };
 
  static getDerivedStateFromProps(props: ResizableBoxProps, state: ResizableBoxState) {
    // If parent changes height/width, set that in our state.
    Iif (state.propsWidth !== props.width || state.propsHeight !== props.height) {
      return {
        width: props.width,
        height: props.height,
        propsWidth: props.width,
        propsHeight: props.height,
      };
    }
    return null;
  }
 
  onResize = (e: SyntheticEvent<>, data: ResizeCallbackData) => {
    const {size} = data;
    Eif (this.props.onResize) {
      e.persist && e.persist();
      this.setState(size, () => this.props.onResize && this.props.onResize(e, data));
    } else {
      this.setState(size);
    }
  };
 
  render(): ReactNode {
    // Basic wrapper around a Resizable instance.
    // If you use Resizable directly, you are responsible for updating the child component
    // with a new width and height.
    const {
      handle,
      handleSize,
      onResize,
      onResizeStart,
      onResizeStop,
      draggableOpts,
      minConstraints,
      maxConstraints,
      lockAspectRatio,
      axis,
      width,
      height,
      resizeHandles,
      style,
      transformScale,
      ...props
    } = this.props;
 
    return (
      <Resizable
        axis={axis}
        draggableOpts={draggableOpts}
        handle={handle}
        handleSize={handleSize}
        height={this.state.height}
        lockAspectRatio={lockAspectRatio}
        maxConstraints={maxConstraints}
        minConstraints={minConstraints}
        onResizeStart={onResizeStart}
        onResize={this.onResize}
        onResizeStop={onResizeStop}
        resizeHandles={resizeHandles}
        transformScale={transformScale}
        width={this.state.width}
      >
        <div {...props} style={{...style, width: this.state.width + 'px', height: this.state.height + 'px'}} />
      </Resizable>
    );
  }
}