suiss/uim · React Native Component

Button

A pill-shaped button that triggers an action, with variants for every level of emphasis.

Button 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
Button on iOS in light mode

Button is a Pressable with the button role. It supports eight visual variants, five text sizes and five icon-only sizes, and an optional block mode that fills the width of its container.

Use the default variant for the primary action on a screen, secondary, tinted or outline for supporting actions, ghost and plain for low-emphasis actions, and destructive for actions that delete or remove. To join several buttons into one control, use Button Group.

Installation

$ pnpm dlx @esuiss/uim@latest add button

The CLI also adds what it builds on: Icon, Text.

Manual

  1. Install the dependencies:
npx expo install class-variance-authority cn
  1. Add the pieces it builds on: Icon, Text.

  2. Copy the source into components/ui/button.tsx:

uniwind/components/ui/button.tsx
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "cn"
import * as React from "react"
import { Pressable } from "react-native"
import { IconClassContext } from "@/components/ui/icon"
import { TextClassContext } from "@/components/ui/text"

const buttonVariants = cva(
  "shrink-0 flex-row items-center justify-center rounded-full border border-transparent",
  {
    variants: {
      variant: {
        default:
          "bg-accent active:bg-accent-pressed disabled:bg-accent-disabled",
        outline:
          "border-separator bg-surface active:bg-item-pressed dark:bg-transparent",
  1. Update the import paths to match your project.

Usage

import { Button } from "@/components/ui/button"
<View className="items-start">
  <Button>
    <Text>Button</Text>
  </Button>
</View>

Put the label in a Text and icons in an Icon. The button passes its text color and icon size down through context, so children pick them up without extra classes.

Use an icon size, such as icon or icon-sm, for buttons that contain only an icon, and give them an accessibilityLabel.

buttonVariants and buttonTextVariants are also exported if you need the classes on another element.

Examples

Variants

All eight variants, plus an icon-only button.

iOS
Button (variants) on iOS in light mode

Sizes

Compares the text and icon-only sizes.

iOS
Button (sizes) on iOS in light mode

With icon

Leading and trailing icons, and an icon-only button.

iOS
Button (with icon) on iOS in light mode

Disabled

Disabled buttons in every variant.

iOS
Button (disabled) on iOS in light mode

Block

Full-width buttons at each size, whose corner radius scales with size.

iOS
Button (block) on iOS in light mode

API Reference

Button

ExtendsButtonProps

Accessibility

  • Renders a Pressable with role="button", so VoiceOver and TalkBack announce it as a button.
  • disabled is announced and blocks presses.
  • Icon-only buttons need an accessibilityLabel.

Notes

  • Colors come from semantic tokens such as bg-accent, bg-control, bg-accent-surface and bg-danger-surface, each with pressed and disabled states.
  • Light and dark colors follow the system appearance.