HextaUI

Drawer: Forms and the keyboard

Wrap <DrawerContent /> in <DrawerVirtualKeyboardProvider /> when a bottom drawer holds text fields. On phones, the focused field scrolls into view above the software keyboard instead of hiding behind it. Keep the fields in <DrawerBody /> so the header and footer stay put.

import { Button } from "@/components/ui/button"
import {
  Drawer,
  DrawerBody,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
  DrawerVirtualKeyboardProvider,
} from "@/components/ui/drawer"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"

export function DrawerKeyboard() {
  return (
    <Drawer>
      <DrawerTrigger render={<Button variant="outline" />}>
        Delivery details
      </DrawerTrigger>
      <DrawerVirtualKeyboardProvider>
        <DrawerContent>
          <DrawerHeader>
            <DrawerTitle>Delivery details</DrawerTitle>
            <DrawerDescription>
              Tap a field on your phone. It stays above the keyboard.
            </DrawerDescription>
          </DrawerHeader>
          <DrawerBody>
            <FieldGroup>
              <Field>
                <FieldLabel>Name</FieldLabel>
                <Input name="name" autoComplete="name" />
              </Field>
              <Field>
                <FieldLabel>Phone</FieldLabel>
                <Input name="phone" type="tel" autoComplete="tel" />
              </Field>
              <Field>
                <FieldLabel>Street address</FieldLabel>
                <Input name="street" autoComplete="street-address" />
              </Field>
              <Field>
                <FieldLabel>Apartment</FieldLabel>
                <Input name="apartment" />
              </Field>
              <Field>
                <FieldLabel>City</FieldLabel>
                <Input name="city" autoComplete="address-level2" />
              </Field>
              <Field>
                <FieldLabel>Postal code</FieldLabel>
                <Input name="postal" autoComplete="postal-code" />
              </Field>
            </FieldGroup>
          </DrawerBody>
          <DrawerFooter>
            <DrawerClose render={<Button />}>Save address</DrawerClose>
          </DrawerFooter>
        </DrawerContent>
      </DrawerVirtualKeyboardProvider>
    </Drawer>
  )
}

This adds the example as components/examples/drawer/keyboard.tsx, together with the Drawer component and the HextaUI theme tokens it needs.

pnpm dlx shadcn@latest add https://hextaui.com/r/drawer-keyboard.json

To add only the component, follow the Drawer installation.

Props in this example

The Drawer props this example sets, from the API reference.

PropTypeDefault
render
ReactElement | (props, state) => ReactElement<button>
PropTypeDefault
render
ReactElement | (props, state) => ReactElement<button>

Every prop is in the Drawer API reference.

See them all, with keyboard support and accessibility notes, on the Drawer page.