Keyboard ToolbariOS
Input accessory bar riding the keyboard's top edge — previous/next field arrows, a custom middle slot, and a Done button that dismisses
$ npx lumioui add keyboard-toolbar
import { KeyboardToolbar } from "@/components/ui/keyboard-toolbar/keyboard-toolbar";
Files installed into your repo
components/ui/keyboard-toolbar/keyboard-toolbar.tsx
Registry dependencies (installed automatically)
Native packages required
@lumioui/core@latestreact-native-reanimated@*react-native-safe-area-context@*
Props9
| onPrevious? | () => void | Show the previous/next chevrons and wire Previous. |
| onNext? | () => void | Wire Next. Shown whenever `onPrevious`/`onNext` is provided. |
| previousDisabled? | boolean | Disable the Previous arrow (e.g. first field). |
| nextDisabled? | boolean | Disable the Next arrow (e.g. last field). |
| onDone? | () => void | Done handler. Default: Keyboard.dismiss(). |
| doneLabel? | string | Done button label. Default "Done". |
| offset? | number | Extra lift above the keyboard in px. Default 0 — flush with it. |
| children? | React.ReactNode | Optional custom content between the arrows and Done. |
| className? | string | |
Keyboard Toolbarwith-field.tsx
Live preview offline the relay is unreachable — check back shortly
keyboard-toolbar/variants/with-field.tsx open Input accessory bar riding the keyboard's top edge — previous/next field arrows, a custom middle slot, and a Done button that dismisses
import { KeyboardToolbarWithField } from "@/components/ui/keyboard-toolbar/variants/with-field";
export function Example() {
return (
<KeyboardToolbarWithField />
);
}
import * as React from "react";
import { Keyboard, View, type TextInput } from "react-native";
import { KeyboardToolbar } from "../keyboard-toolbar";
import { Input } from "../../input/input";
import { Text } from "../../text/text";
import { Glass } from "../../glass/glass";
/** KeyboardToolbarWithField — a two-field form wired to prev/next + Done. */
export function KeyboardToolbarWithField() {
const [name, setName] = React.useState("");
const [note, setNote] = React.useState("");
const noteRef = React.useRef<TextInput>(null);
return (
<View className="w-full gap-3">
<Glass interactive curvature="edge" className="w-full gap-3 rounded-2xl p-4">
<Text variant="small" className="font-semibold">Delivery details · Order #8421</Text>
<Input
glass
label="Recipient"
placeholder="Amara Chen"
// The toolbar only mounts while a field is focused — autofocus keeps
// the docs/static preview from rendering an invisible component.
autoFocus
value={name}
onChangeText={setName}
returnKeyType="next"
onSubmitEditing={() => noteRef.current?.focus()}
/>
<Input
glass
ref={noteRef}
label="Door note"
placeholder="Leave at the blue door"
value={note}
onChangeText={setNote}
/>
<KeyboardToolbar
onPrevious={() => {}}
onNext={() => noteRef.current?.focus()}
previousDisabled={!name && !note}
onDone={() => Keyboard.dismiss()}
>
<Text variant="muted" className="text-xs">
{note.length}/140
</Text>
</KeyboardToolbar>
{/* Spacer matching the parked bar's height so it never overlaps
the field — on device the keyboard pushes this area itself. */}
<View className="h-[68px]" />
</Glass>
</View>
);
}