useKeyboardInset React hook in TypeScript
v1.0.0Added in 1.0.0
A React hook for the mobile on-screen keyboard: how much of the screen it covers, so bars pinned to the bottom ride above it.
Open the demo on a phone and tap the message field: as the keyboard slides up, the composer rides on top of it instead of hiding behind it, and the readout shows the covered height with the open flag lit. Close the keyboard and it settles back to the bottom. On a desktop there is no on-screen keyboard, so the inset stays 0px.
useKeyboardInset is a Pro React hook in the React hooks and utilities category, written in TypeScript for React 19. It installs as source with npx wingo-ui@latest add use-keyboard-inset, together with the npm package motion.
Add to a project
Requirements: React 19, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup
npx wingo-ui@latest add use-keyboard-insetuseKeyboardInset is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans
Usage
Import useKeyboardInset from @/hooks/use-keyboard-inset.
"use client"
import { motion, useTransform } from "motion/react"
import { useKeyboardInset } from "@/hooks/use-keyboard-inset"
export function Composer() {
const { inset } = useKeyboardInset()
const y = useTransform(inset, (v) => -v)
return (
<motion.form style={{ y }} className="fixed inset-x-0 bottom-0 z-sticky flex gap-2 bg-background p-3 pb-[max(env(safe-area-inset-bottom),12px)]">
<input aria-label="Message" placeholder="Write a message" enterKeyHint="send" className="h-11 flex-1 rounded-full bg-foreground/5 px-4 text-base" />
</motion.form>
)
}API
thresholddefault80numberuseKeyboardInset(options?): px of covered viewport below which it does not count as a keyboard (browser bars resizing, the iOS form accessory alone).
cssVardefault""stringAlso writes the inset in px to this CSS variable on <html> (e.g. "--keyboard-inset"), for CSS-only consumers: bottom: var(--keyboard-inset, 0px). Removed on unmount; use one writer per variable.
disableddefaultfalsebooleanStops measuring and reports 0.
returns{ inset: MotionValue<number>; open: boolean }inset: the covered height in px, updated as the keyboard animates without re-rendering; lift a bar with style={{ y: useTransform(inset, (v) => -v) }}. open: true while the keyboard is up, re-rendering only when it flips (hide a floating button, drop a tab bar). Both are 0 / false on the server, during hydration, on desktops, while pinch-zoomed and when no text field has focus.
Parts
UseKeyboardInsetOptions
typeThe hook's options: { disabled?: boolean; threshold?: number; cssVar?: string }.
KeyboardInset
typeThe return value: { inset: MotionValue<number>; open: boolean }.
Examples
Hide the tab bar while typing
Uses the open flag to slide a bottom tab bar away when the keyboard comes up.
CSS variable
cssVar writes the inset to <html>, so a sticky Pay button lifts with plain CSS.
Dependencies
Files
- hooks/use-keyboard-inset.ts
FAQ
Is the useKeyboardInset hook free?
The preview, props and docs are free; copying the source needs a Pro plan. See plans.
How do I install useKeyboardInset?
Run npx wingo-ui@latest add use-keyboard-inset. It also adds the npm package motion. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/use-keyboard-inset.
See also
Used in
More React hooks and utilities
Articles using this component
- iOS Safari Keyboard Position Fixed: Keep a Composer Visible
Mobile UI in React9 min read
- 100vh Mobile Fix: When to Use dvh, svh or lvh in Tailwind
Mobile UI in React11 min read