Skip to main content

Interaction & Drag Controls

Temper gives you granular control over gesture interactions, modal behavior, input positioning, and dismissibility.


Handle-Only Dragging (handleOnly)

By default, dragging anywhere inside <Drawer.Content> drags the drawer down. If your content contains scrollable lists or interactive elements, restrict dragging to <Drawer.Handle />:

<Drawer.Root handleOnly={true}>
{/* Dragging only works when pressing <Drawer.Handle /> */}
</Drawer.Root>

Non-Modal Drawers (modal={false})

To allow users to interact with elements on the background page while the drawer is visible:

<Drawer.Root modal={false}>
{/* Page interactions remain active behind the drawer */}
</Drawer.Root>

Non-Dismissible Drawers (dismissible={false})

To prevent closing via swiping down, pressing Esc, or clicking outside:

<Drawer.Root dismissible={false} open={isOpen} onOpenChange={setIsOpen}>
{/* Drawer can only be closed programmatically or via explicit controls */}
</Drawer.Root>

Reposition Inputs (repositionInputs)

On mobile browsers, opening the virtual keyboard can obscure input fields. By default (repositionInputs = true), Temper adjusts drawer position to keep input fields in viewport view.

<Drawer.Root repositionInputs={true}>
{/* Input fields inside drawer automatically adjust when keyboard appears */}
</Drawer.Root>

Drag Callback Events

Listen to live gesture progress using onDrag and onRelease:

<Drawer.Root
onDrag={(event, percentageDragged) => {
console.log(`Dragged: ${(percentageDragged * 100).toFixed(1)}%`);
}}
onRelease={(event, open) => {
console.log(`Released. Final open state: ${open}`);
}}
onAnimationEnd={(open) => {
console.log(`Open/close transition finished: ${open}`);
}}
>
{/* Drawer content */}
</Drawer.Root>