DragHandle
MD3 drag handle for resizing panes (Compose VerticalDragHandle). It is a
vertical capsule placed between two side-by-side panes. Drag it sideways, or
focus it and use the arrow keys, to change how the width is split, for
example between the list and the detail pane of a list-detail layout.
- Ali ConnorsBrunch this weekend?
- Sandra AdamsSummer BBQ
- Trevor HansenOui oui
const [width, setWidth] = useState(280)
<div style={{ display: 'flex' }}>
<section id="list-pane" aria-label="Inbox" style={{ flex: `0 0 ${width}px` }}>…</section>
<DragHandle
aria-label="Inbox"
aria-controls="list-pane"
min={200}
max={480}
value={width}
onChange={(event, value) => setWidth(value)}
style={{ alignSelf: 'center' }}
/>
<section style={{ flex: 1 }}>…</section>
</div>
Size and layout
The handle only reports a size. Your layout applies it, usually as the width of the pane next to the handle.
value/defaultValueis the size of the controlled pane in px, kept betweenminandmax.onChange(event, value)fires on every pointer move and on every key press that changes the value.paneSidesays which side of the handle that pane is on. With"start"(the default, like the list in a list-detail layout), dragging toward the inline end makes it bigger. With"end", dragging toward the inline start makes it bigger. Both follow the writing direction, so they flip in RTL.onDragStartandonDragEndfire once per pointer drag. UseonDragEndto save the final size, for example tolocalStorage.- The handle is 24dp wide (the spacing between panes) and has a 48dp touch target.
States
At rest the handle is a 4×48dp capsule in the outline color. While it is pressed or dragged it becomes a 12×52dp on-surface shape with 12dp corners. Like Compose, it switches between the two without animation. Hover, focus and press state layers and the focus ring are drawn on the capsule.
Accessibility
The handle is a WAI-ARIA window splitter:
- It has
role="separator",aria-orientation="vertical", andaria-valuenow,aria-valueminandaria-valuemaxset fromvalue,minandmax.getAriaValueTextadds a readablearia-valuetext, for example "280 pixels". - Give it a name that matches the pane it resizes (
aria-labeloraria-labelledby), and pointaria-controlsat that pane. - Keyboard: ← and → move the handle by
step(default 1), or byshiftStep(default 10) with Shift. Page Up and Page Down also change the size byshiftStep, and Home and End jump tominandmax. ↑ makes the pane bigger and ↓ makes it smaller. disabledsetsaria-disabled, removes the handle from the tab order and ignores both pointer and keyboard input.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | number | min | Uncontrolled initial size. |
disabled | boolean | false | Disables dragging and keyboard resizing and removes the handle from the tab order. |
getAriaValueText | ((value: number) => string) | — | Human-readable size for assistive tech (aria-valuetext), e.g. (v) => \${v} pixels\``. |
max | number | 100 | Largest size (aria-valuemax). |
min | number | 0 | Smallest size (aria-valuemin). |
onChange | ((event: SyntheticEvent<Element, Event>, value: number) => void) | — | Fires while dragging and on each key press, with the triggering event and the new (clamped) size. Not fired when the size would not change. |
onDragEnd | ((event: PointerEvent<HTMLDivElement>, value: number) => void) | — | Fires when a pointer drag ends (release or cancel), with the final size — e.g. to persist it. |
onDragStart | ((event: PointerEvent<HTMLDivElement>, value: number) => void) | — | Fires when a pointer drag starts (after the first movement), with the size at that point. |
paneSide | "start" | "end" | start | Which side of the handle the controlled pane is on (logical, so it
mirrors in RTL). 'start': dragging toward the inline end grows it (the
list of a list-detail layout); 'end': dragging toward the inline start
grows it. |
shiftStep | number | 10 | Size change per Shift + arrow and Page Up / Page Down. |
step | number | 1 | Size change per arrow key. |
value | number | — | Controlled size of the controlled pane, in px (the separator's
aria-valuenow). |