# Resizable

> Lets one element be resized by dragging one of its edges.

Source: https://ngwr.dev/reference/components/resizable  
Kind: Component  
Added in v16.1

## Installation

Import the class, and `@use` the entry point in your global styles. Nothing warns you when the `@use` is missing.

```typescript
import { Component } from '@angular/core';
import { WrResizable } from 'ngwr/resizable';

@Component({ imports: [WrResizable] })
export class MyComponent {}
```

```scss
@use 'ngwr/resizable';
```

## Basic

Put `wrResizable` on the element. It writes the element's own `width` in pixels and nothing else, so a panel lying over other content stays over it. `[(size)]` changes when the drag is released; `(resizing)` fires on every move.

```angular-html
<div class="map">
  <aside wrResizable [(size)]="width" (resizing)="live.set($event)">Layers</aside>
</div>
```

```scss
.map {
  position: relative;
}

aside {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 16rem;
}
```

## Limits

`minSize` and `maxSize` take pixels or a percentage of the parent's matching dimension. The default range is `0` to `100%`; `null` removes a limit.

```angular-html
<aside wrResizable [minSize]="160" maxSize="60%">Layers</aside>
```

## Edges

`edge` is `end` by default. `start` and `end` resize the width and swap sides under RTL; `top` and `bottom` resize the height.

```angular-html
<footer wrResizable edge="top" [minSize]="48" maxSize="80%">Timeline</footer>
```

## Saved size

`persistKey` saves the size through `WrStorage` when a resize ends and restores it on the next visit. Enter or a double click on the handle goes back to `defaultSize`, or to the size the element started with.

```angular-html
<aside wrResizable persistKey="layers-panel" [defaultSize]="256">Layers</aside>
```

## Collapsed and disabled

`collapsed` shrinks the element to zero, hides the handle and keeps `size`, so the element comes back as it was. `disabled` keeps the size and stops the handle. Keep padding and borders on an inner element: the host's own would stay visible at zero.

```angular-html
<aside wrResizable [collapsed]="!open()">
  <div class="body">Layers</div>
</aside>
```

## Keyboard

The handle is a focusable separator that announces the size and its limits in pixels.

| Key | Does |
| --- | --- |
| Arrows | Move the edge by `step` (10px), the way the arrow points. |
| Shift + arrows | Ten steps. |
| Home / End | The smallest and the largest size. |
| Enter | Back to `defaultSize`. |

## Handle

The directive adds the handle inside the host, over the edge. It needs a positioning context: a host whose computed `position` is `static` gets `position: relative`. Scroll an inner element, not the host, or the handle scrolls away with the content. Name the handle with `resizeLabel`, or translate `resizable.handle`.

```angular-html
<aside wrResizable resizeLabel="Resize the layers panel">Layers</aside>
```

```typescript
provideWrI18nStaticLoader({
  en: { resizable: { handle: 'Resize' } },
});
```

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `edge` | The edge that drags. `start` and `end` resize the width and mirror under RTL; `top` and `bottom` resize the height. | `WrResizableEdge` | `'end'` |
| `size` | The size in pixels. Two-way bindable. `null` means not set yet: the element keeps the size its CSS gives it until the first resize. `sizeChange` fires when a drag is released, on each key and on a reset, never during a drag: bind `resizing` for that. | `number \| null` | `null` |
| `minSize` | Smallest size: pixels, or a percentage of the parent's matching dimension (`'20%'`). `null` for none. | `WrResizableLimit \| null` | `0` |
| `maxSize` | Largest size: pixels, or a percentage of the parent's matching dimension. `null` for none. | `WrResizableLimit \| null` | `'100%'` |
| `defaultSize` | The size Enter and a double click on the handle go back to. `null` goes back to what the element started with: the `size` bound at creation, or its CSS size when there was none. | `number \| null` | `null` |
| `step` | Pixels an arrow key moves the edge. Shift moves it ten times as far. | `number` | `10` |
| `persistKey` | Saves the size under this key through `WrStorage` (which adds the app's prefix) when a resize ends, and restores it on creation. | `string \| null` | `null` |
| `collapsed` | Shrinks the element to zero and hides the handle. `size` is left alone, so the element is back at its size when this turns off. | `boolean` | `false` |
| `disabled` | Keeps the size and stops the handle. | `boolean` | `false` |
| `resizeLabel` | Accessible name of the handle. A focusable `role="separator"` is an interactive widget, so it needs one. Falls back to `resizable.handle`. | `string \| null` | `null` |
| `(resizing)` | The size in pixels on every move of a drag, before `sizeChange` settles it on release. | `number` | — |

## CSS variables

Set these on the element itself, with a rule more specific than its Declared on selector. In a global stylesheet, put a class of yours on an ancestor it really has: `<body>` for an overlay panel, which renders outside your markup. In a component stylesheet the selector alone works, but only for an element in that component's own template. A value on a wrapper or `:root` is shadowed, because `ngwr/resizable` declares each default on its own element.

| Variable | Default | Declared on |
| --- | --- | --- |
| `--wr-resizable-grip-active-color` | `var(--wr-color-primary)` | `.wr-resizable` |
| `--wr-resizable-grip-color` | `var(--wr-border-base)` | `.wr-resizable` |
| `--wr-resizable-grip-length` | `2rem` | `.wr-resizable` |
| `--wr-resizable-grip-radius` | `var(--wr-border-radius-pill)` | `.wr-resizable` |
| `--wr-resizable-grip-thickness` | `var(--wr-space-xs)` | `.wr-resizable` |
| `--wr-resizable-handle-hover-bg` | `var(--wr-color-primary-soft)` | `.wr-resizable` |
| `--wr-resizable-handle-size` | `var(--wr-space-sm)` | `.wr-resizable` |
| `--wr-resizable-line-active-color` | `var(--wr-color-primary)` | `.wr-resizable` |
| `--wr-resizable-line-color` | `var(--wr-border-subtle)` | `.wr-resizable` |
| `--wr-resizable-line-size` | `1px` | `.wr-resizable` |

## Dependencies

| Built on | [WrStorage](https://ngwr.dev/reference/services/storage) |
| --- | --- |

## See also

- [Splitter](https://ngwr.dev/reference/components/splitter) — Two panes with a divider the user drags or moves with the arrow keys.
- [Drawer](https://ngwr.dev/reference/components/drawer) — A side panel that slides in from any edge of the screen.
- [Layout](https://ngwr.dev/reference/components/layout) — An app shell: header, sider, content and footer.
- [WrStorage](https://ngwr.dev/reference/services/storage) — Typed key-value storage over localStorage or any engine, read as a signal or written through one, safe under SSR.
