react-resizable

repository·master·Indexed 25 days ago

https://github.com/react-grid-layout/react-resizable

A React widget library for making elements resizable via handles. It provides a low-level stateless <Resizable> component for fine-grained control and a high-level stateful <ResizableBox> component for standard resizable containers. Version 4.0.2 includes bundled TypeScript type declarations.

Tokens
3.5K
Snippets
9
Records
14
Agent score
80%

What's inside react-resizable

  1. How `<Resizable>` and `<ResizableBox>` work together

    master

    The package provides two main components for different use cases:

    1. <Resizable>: A raw, stateless component. It acts as a building block. You are responsible for managing the state (width/height) and passing it back into the component via callbacks like onResize.
    2. <ResizableBox>: A high-level component that wraps a <div>. It manages its own basic state, making it much simpler for standard use cases where you just want a resizable container.

    Use <Resizable> when you need fine-grained control over the resizing logic or when integrating with complex state management. Use <ResizableBox> for quick, self-contained resizable elements.

    // Example of the stateless <Resizable>
    <Resizable
      height={this.state.height}
      width={this.state.width}
      onResize={this.onResize}
    >
      <div style={{width: this.state.width + 'px', height: this.state.height + 'px'}} />
    </Resizable>
    
    // Example of the stateful <ResizableBox>
    <ResizableBox
      width={200}
      height={200}
      minConstraints={[100, 100]}
    >
      <div>Contents</div>
    </ResizableBox>
  2. Include react-resizable styles

    master

    You must include the associated styles in your application, otherwise the resize handles will not be visible and will not work properly.

    You can import the CSS in your JS/TS entry point:

    import 'react-resizable/css/styles.css';

    Or import it directly in your CSS:

    @import 'react-resizable/css/styles.css';

    If your bundler does not support CSS imports, manually include the file located at node_modules/react-resizable/css/styles.css.

  3. Customize the Resize Handle

    master

    You can override the default resize handle by passing a custom element or function to the handle prop. Crucially, your custom handle must forward its ref to the underlying DOM element so react-resizable can attach handlers and measure position.

    Using a Native DOM Element

    No special treatment required:

    <Resizable handle={<div className="foo" />} />

    Using a Custom React Component

    You must use React.forwardRef to pass the ref and props to the DOM element.

    Functional Component Example:

    const MyHandle = React.forwardRef((props, ref) => {
      const {handleAxis, ...restProps} = props;
      return <div ref={ref} className={`foo handle-${handleAxis}`} {...restProps} />;
    });
    
    <Resizable handle={<MyHandle />} />

    Using a Custom Function

    You can pass a function that receives the axis and a ref. This is often cleaner for certain coding styles:

    const MyHandle = (props) => {
      return <div ref={props.innerRef} className="foo" {...props} />;
    };
    
    <Resizable handle={(handleAxis, ref) => <MyHandle innerRef={ref} className={`foo handle-${handleAxis}`} />} />
  4. Configure TypeScript for react-resizable

    master

    As of version 4.0.0, the library is authored in TypeScript and includes bundled type declarations. You do not need to install @types/react-resizable. If you have it installed, remove it to prevent conflicts with the bundled types:

    npm uninstall @types/react-resizable
    # or
    yarn remove @types/react-resizable

    Public types are re-exported from the package root. Common types include:

    • ResizeCallbackData
    • ResizeHandleAxis
    • Axis
    • Props (aliased as ResizableProps)
    import {
      Resizable,
      ResizableBox,
      type ResizeCallbackData,
      type ResizeHandleAxis,
      type Axis,
      type Props as ResizableProps,
    } from 'react-resizable';
  5. Use the `<ResizableBox>` component

    master

    The <ResizableBox> component is a simple <div> that manages its own state. It is ideal for quick implementations where you don't want to manually manage width and height in your parent component.

    import { ResizableBox } from 'react-resizable';
    import 'react-resizable/css/styles.css';
    
    class Example extends React.Component {
      render() {
        return (
          <ResizableBox
            width={200}
            height={200}
            draggableOpts={{grid: [25, 25]}}
            minConstraints={[100, 100]}
            maxConstraints={[300, 300]}
          >
            <span>Contents</span>
          </ResizableBox>
        );
      }
    }
  6. Use the `<Resizable>` component

    master

    The <Resizable> component is a stateless component used to make any child element resizable. You must manage the width and height in your own state and update them via the onResize callback.

    import { Resizable } from 'react-resizable';
    import 'react-resizable/css/styles.css';
    
    class Example extends React.Component {
      state = {
        width: 200,
        height: 200,
      };
    
      onResize = (event, {node, size, handle}) => {
        this.setState({width: size.width, height: size.height});
      };
    
      render() {
        return (
          <Resizable
            height={this.state.height}
            width={this.state.width}
            onResize={this.onResize}
          >
            <div
              className="box"
              style={{width: this.state.width + 'px', height: this.state.height + 'px'}}
            >
              <span>Contents</span>
            </div>
          </Resizable>
        );
      }
    }
  7. Reference: ResizableProps

    master

    These props apply to both <Resizable> and <ResizableBox>. Unknown props not listed here are passed through to the child component.

    PropTypeDefaultDescription
    childrenReact.ReactElement<any>The element to be resized
    widthnumberCurrent width
    heightnumberCurrent height
    handleReact.ReactElement or (resizeHandle: ResizeHandleAxis, ref: React.RefObject<HTMLElement>) => React.ReactElementCustom resize handle element or function returning one
    handleSize[number, number][20, 20]Size of the handle. Update your CSS if changed
    lockAspectRatiobooleanfalseWhether to lock the aspect ratio
    axis'both' | 'x' | 'y' | 'none''both'The axis to resize on
    minConstraints[number, number][20, 20]Minimum width and height
    maxConstraints[number, number][Infinity, Infinity]Maximum width and height
    onResizeStop(e, data) => anyCallback when resizing stops
    onResizeStart(e, data) => anyCallback when resizing starts
    onResize(e, data) => anyCallback during resizing
    draggableOptsPartial<DraggableCoreProps>Options forwarded to react-draggable's DraggableCore
    resizeHandlesResizeHandleAxis[]['se']Which handles to show
    transformScalenumber1Scale factor if parent has transform: scale(n)

    Types for callbacks:

    type ResizeCallbackData = {
      node: HTMLElement;
      size: {width: number; height: number};
      handle: ResizeHandleAxis;
    };
    
    type ResizeHandleAxis = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';
    type ResizeCallbackData = {
      node: HTMLElement;
      size: {width: number; height: number};
      handle: ResizeHandleAxis;
    };
    
    type ResizeHandleAxis = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';
    
    type ResizableProps = {
      children: React.ReactElement<any>;
      width: number;
      handle?:
        | React.ReactElement<any>
        | ((resizeHandle: ResizeHandleAxis, ref: React.RefObject<HTMLElement>) => React.ReactElement<any>);
      handleSize?: [number, number];
      lockAspectRatio?: boolean;
      axis?: 'both' | 'x' | 'y' | 'none';
      minConstraints?: [number, number];
      maxConstraints?: [number, number];
      onResizeStop?:  (e: React.SyntheticEvent, data: ResizeCallbackData) => any;
      onResizeStart?: (e: React.SyntheticEvent, data: ResizeCallbackData) => any;
      onResize?:      (e: React.SyntheticEvent, data: ResizeCallbackData) => any;
      draggableOpts?: Partial<React.ComponentProps<typeof import('react-draggable').DraggableCore>>;
      resizeHandles?: ResizeHandleAxis[];
      transformScale?: number;
    };
  8. Import Resizable components from react-resizable

    master
    To use the library, do not attempt to call the default export of the package directly. Instead, access the Resizable and ResizableBox components via their named exports. Calling the default export will throw an error: Don't instantiate Resizable directly! Use require('react-resizable').Resizable.
  9. Configure the `<Resizable>` component props

    master

    The <Resizable> component accepts several props to control resizing behavior, constraints, and event handling.

    Core Props

    • width: number (Required if axis is 'both' or 'x')
    • height: number (Required if axis is 'both' or 'y')
    • axis: 'both' | 'x' | 'y' | 'none' (Controls which dimension can be resized)
    • resizeHandles: An array of ResizeHandleAxis defining which handles are rendered.
    • handle: A React element or a ResizeHandleFn to customize the resize handle.
    • lockAspectRatio: boolean to maintain proportions during resize.
    • minConstraints: [number, number] (Min width and height)
    • maxConstraints: [number, number] (Max width and height)
    • handleSize: [number, number] (Size of the resize handle)
    • transformScale: number (Used if the parent has a CSS transform: scale(n) applied)

    Event Callbacks

    All resize callbacks receive a ResizeCallbackData object:

    • onResizeStart: Called when resizing begins.
    • onResize: Called continuously during resizing.
    • onResizeStop: Called when resizing ends.

    Draggable Options

    You can pass draggableOpts to configure the underlying react-draggable behavior (e.g., grid, cancel, onStop).