suiss/uim · React Native Component

Input Accessory Bar

A toolbar above the keyboard with previous, next and done buttons for moving through form fields.

Input Accessory Bar is an open-source mobile component from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Input Accessory Bar on iOS in light mode

InputAccessoryBar connects a set of inputs and shows a bar above the keyboard while one of them is focused. The up and down arrows move focus to the previous or next input, and the done button dismisses the keyboard.

On iOS the bar is a native InputAccessoryView, attached to the keyboard. On Android it is rendered through a portal and positioned just above the keyboard while an input is focused.

Installation

$ pnpm dlx @esuiss/uim@latest add input-accessory-bar

The CLI also adds what it builds on: Button, Icon, Input, Keyboard Scroll View, Text.

Manual

  1. Install the dependencies:
npx expo install cn phosphor-react-native react-native-svg
  1. Add the pieces it builds on: Button, Icon, Input, Keyboard Scroll View, Text, and the primitives components/primitives/hooks.tsx, components/primitives/keyboard.tsx, components/primitives/portal.tsx.

  2. Copy the source into components/ui/input-accessory-bar.tsx:

uniwind/components/ui/input-accessory-bar.tsx
import { cn } from "cn"
import { CaretDownIcon, CaretUpIcon } from "phosphor-react-native"
import * as React from "react"
import {
  InputAccessoryView,
  Keyboard,
  Platform,
  type TextInput,
  type TextInputProps,
  View,
} from "react-native"
import { useComposedRefs } from "@/components/primitives/hooks"
import {
  setKeyboardAccessoryHeight,
  useKeyboard,
} from "@/components/primitives/keyboard"
  1. Update the import paths to match your project.

Usage

import { InputAccessoryBar, InputAccessoryBarInput } from "@/components/ui/input-accessory-bar"
<InputAccessoryBar>
  <Form />
</InputAccessoryBar>

Wrap the form in InputAccessoryBar and use InputAccessoryBarInput in place of Input. Inputs are ordered by the order they mount. The return key reads "next" on every input but the last, which reads "done" and dismisses the keyboard.

For other text inputs, such as a Textarea, call useInputAccessoryBarInput() and spread the returned props onto the input. Inside a Keyboard Scroll View, the focused input is scrolled into view.

Use previousLabel, nextLabel and doneLabel to localize the buttons, and onDone to react when done is pressed.

Examples

Focused

The first input focused, so the bar is visible.

iOS
Input Accessory Bar (focused) on iOS in light mode

Custom labels

Custom labels for the previous, next and done buttons.

iOS
Input Accessory Bar (custom labels) on iOS in light mode

With textarea

A textarea connected through useInputAccessoryBarInput.

iOS
Input Accessory Bar (with textarea) on iOS in light mode

API Reference

InputAccessoryBar

Provider that tracks the inputs and renders the bar.

PropType
About
Label for the previous button. Defaults to "Previous".
Type
string
Default
"Previous"
About
Label for the next button. Defaults to "Next".
Type
string
Default
"Next"
About
Text or node for the done button. Defaults to "Done".
Type
React.ReactNode
Default
"Done"
About
Called after the keyboard is dismissed with done.
Type
() => void
Default
—
About
Name of the portal host on Android.
Type
string
Default
—
Type
string
Default
—
Type
React.ReactNode
Default
—

InputAccessoryBarInput

Input connected to the bar.

ExtendsReact.ComponentProps<typeof Input>

Accessibility

  • The arrow buttons are labelled with previousLabel and nextLabel and are disabled at the first and last input.
  • The done button is a text button that dismisses the keyboard.

Notes

  • iOS uses the native input accessory view; Android uses a portal and reserves the bar height so keyboard-aware layouts stay above it.
  • Uses bg-surface-raised (a secondary surface in dark mode) and border-separator tokens.