# Resize

## Examples


### Basic

The onRequestResize handler must handle any desired constraints on size.

```typescript
import React, { useState } from 'react';

import Resize, { ResizeRequestResizeHandler } from '@splunk/react-ui/Resize';


function Basic() {
    const [state, setState] = useState({
        height: 200,
        width: 400,
    });

    const onRequestResize: ResizeRequestResizeHandler = (e, { height, width }) => {
        const constrainedHeight = Math.min(Math.max(height, 100), 400);
        const constrainedWidth = Math.min(Math.max(width, 300), 600);
        setState({ height: constrainedHeight, width: constrainedWidth });
    };

    return (
        <Resize
            resizeHandles={['se']}
            onRequestResize={onRequestResize}
            style={{
                height: state.height,
                width: state.width,
                padding: 20,
                border: '1px solid #ccc',
            }}
        >
            I am content.
        </Resize>
    );
}

export default Basic;
```



### Appearance

Resize handles can be placed on any edge or corner. Note that margin cannot be overridden when using the "border" appearance.

```typescript
import React, { useState } from 'react';

import Multiselect, { MultiselectChangeHandler } from '@splunk/react-ui/Multiselect';
import RadioBar, { RadioBarChangeHandler } from '@splunk/react-ui/RadioBar';
import Resize, { ResizeDirection, ResizeRequestResizeHandler } from '@splunk/react-ui/Resize';
import { useSplunkTheme } from '@splunk/themes';

interface State {
    appearance: 'border' | 'overlay' | 'separator';
    height: number;
    resizeHandles: ResizeDirection[];
    showHandles: 'always' | 'on-hover';
    width: number;
}


function Appearance() {
    const [state, setState] = useState<State>({
        height: 200,
        width: 200,
        appearance: 'border',
        showHandles: 'always',
        resizeHandles: ['nw', 'n', 'ne', 'w', 'e', 'sw', 's', 'se'],
    });

    const onRequestResize: ResizeRequestResizeHandler = (e, { height, width }) => {
        setState({ ...state, height, width });
    };

    const onChangeAppearance: RadioBarChangeHandler = (e, { value }) => {
        setState({ ...state, appearance: value });
    };

    const onChangeShowHandles: RadioBarChangeHandler = (e, { value }) => {
        setState({ ...state, showHandles: value });
    };

    const onChangeHandles: MultiselectChangeHandler = (e, { values }) => {
        setState({ ...state, resizeHandles: values as ResizeDirection[] });
    };

    const { spacingSmall, spacingXLarge } = useSplunkTheme();

    return (
        <div>
            <div
                style={{
                    marginBottom: spacingXLarge,
                    display: 'flex',
                    gap: spacingSmall,
                }}
            >
                <RadioBar onChange={onChangeAppearance} value={state.appearance}>
                    <RadioBar.Option value="overlay" label="overlay" />
                    <RadioBar.Option value="border" label="border" />
                    <RadioBar.Option value="separator" label="separator" />
                </RadioBar>
                <RadioBar onChange={onChangeShowHandles} value={state.showHandles}>
                    <RadioBar.Option value="always" label="always" />
                    <RadioBar.Option value="on-hover" label="on-hover" />
                </RadioBar>
                <Multiselect onChange={onChangeHandles} values={state.resizeHandles}>
                    <Multiselect.Option value="n" label="n" />
                    <Multiselect.Option value="ne" label="ne" />
                    <Multiselect.Option value="e" label="e" />
                    <Multiselect.Option value="se" label="se" />
                    <Multiselect.Option value="s" label="s" />
                    <Multiselect.Option value="sw" label="sw" />
                    <Multiselect.Option value="w" label="w" />
                    <Multiselect.Option value="nw" label="nw" />
                </Multiselect>
            </div>
            <div
                style={{
                    border: '1px solid #d6d6d6',
                    display: 'inline-block',
                }}
            >
                <Resize
                    resizeHandles={state.resizeHandles}
                    onRequestResize={onRequestResize}
                    appearance={state.appearance}
                    showHandles={state.showHandles}
                    style={{
                        height: state.height,
                        width: state.width,
                    }}
                >
                    <div
                        style={{
                            left: '50%',
                            top: '50%',
                            transform: 'translate(-50%, -50%)',
                            position: 'absolute',
                            textAlign: 'center',
                        }}
                    >
                        I am content.
                    </div>
                </Resize>
            </div>
        </div>
    );
}

export default Appearance;
```



### Sizing outer

Resize does not dictate how it is sized. In this example, styles are placed on an outer container.

```typescript
import React, { useState } from 'react';

import Resize, { ResizeRequestResizeHandler } from '@splunk/react-ui/Resize';


function SizingOuter() {
    const [state, setState] = useState({
        height: 200,
        width: 200,
    });
    const onRequestResize: ResizeRequestResizeHandler = (e, { height, width }) => {
        setState({ height, width });
    };

    return (
        <div // Width and height on outer container
            style={{
                height: state.height,
                width: state.width,
                border: '1px solid #ccc',
                backgroundColor: 'rgba(128, 128, 128, 0.2)',
                position: 'relative',
            }}
        >
            <Resize
                resizeHandles={['se']}
                onRequestResize={onRequestResize}
                style={{
                    position: 'absolute',
                    top: 0,
                    right: 0,
                    bottom: 0,
                    left: 0,
                    padding: 20,
                }}
            >
                Width and height on outer container
            </Resize>
        </div>
    );
}

export default SizingOuter;
```



### Sizing inner

In this example, styles are placed on the inner content.

```typescript
import React, { useState } from 'react';

import Resize, { ResizeRequestResizeHandler } from '@splunk/react-ui/Resize';


function SizingInner() {
    const [state, setState] = useState({
        height: 200,
        width: 200,
    });

    const onRequestResize: ResizeRequestResizeHandler = (e, { height, width }) => {
        setState({ height: height - 2, width: width - 2 }); // border adjustment
    };

    return (
        <Resize // Width and height on inner container
            resizeHandles={['se']}
            onRequestResize={onRequestResize}
            style={{
                border: '1px solid #ccc',
                display: 'inline-block',
            }}
        >
            <div
                style={{
                    width: state.width,
                    height: state.height,
                    backgroundColor: 'rgba(128, 128, 128, 0.2)',
                    padding: 20,
                    boxSizing: 'border-box',
                }}
            >
                Width and height on inner container
            </div>
        </Resize>
    );
}

export default SizingInner;
```



### Percentage

Sizes don't need to be defined in pixels or with height and width styles. Here, flex-basis is calculated as a percentage.

```typescript
import React, { useRef, useState } from 'react';

import Resize, { ResizeRequestResizeHandler } from '@splunk/react-ui/Resize';


function Percentage() {
    const el = useRef<HTMLDivElement | null>(null);

    const [percentage, setPercentage] = useState(50);

    const onRequestResize: ResizeRequestResizeHandler = (e, { width }) => {
        if (el.current) {
            const calculatedPercentage = Math.max((width / el.current.clientWidth) * 100);
            const percentageValue = Math.min(Math.max(calculatedPercentage, 10), 90);

            setPercentage(percentageValue);
        }
    };

    return (
        <div
            ref={el}
            style={{
                minHeight: 100,
                display: 'flex',
            }}
        >
            <Resize
                resizeHandles={['e']}
                onRequestResize={onRequestResize}
                appearance="separator"
                style={{
                    flexBasis: `${percentage}%`,
                    backgroundColor: 'rgba(128, 128, 128, 0.2)',
                }}
            >
                <div
                    style={{
                        padding: 20,
                    }}
                >
                    Left side
                </div>
            </Resize>
            <div
                style={{
                    flexGrow: 1,
                    backgroundColor: 'rgba(128, 200, 128, 0.2)',
                    padding: 20,
                }}
            >
                Right side
            </div>
        </div>
    );
}

export default Percentage;
```




## API


### Resize API

Resize is a utility container with drag handles for resizing.

#### Props

| Name | Type | Required | Default | Description |
|------|------|------|------|------|
| appearance | 'border' \| 'overlay' \| 'separator' | no | 'overlay' | The appearance of the resize handles. Note: When appearance is 'separator', active full length borders will only appear for 'n', 's', 'e', or 'w' `resizeHandles`. |
| children | React.ReactNode | no |  |  |
| elementRef | React.Ref<HTMLDivElement> | no |  | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
| keyIncrement | number | no | 10 | When focused on a resize handle, the arrow keys will adjust the height or width by this amount with each press. |
| onRequestResize | ResizeRequestResizeHandler | yes |  | A callback which is passed the event and an object with the requested height and width. |
| resizeHandles | ResizeDirection[] | yes |  | An array of resize handles placements. |
| showHandles | 'always' \| 'on-hover' | no | 'always' | The appearance of the resize handles. |

#### Types

| Name | Type | Description |
|------|------|------|
| ResizeDirection | 'nw' \| 'n' \| 'ne' \| 'w' \| 'e' \| 'sw' \| 's' \| 'se' |  |
| ResizeRequestResizeHandler | (     event: MouseEvent \| React.KeyboardEvent<HTMLButtonElement>,     data: { height: number; width: number } ) => void |  |





