Skip to content
Native Animation
Base Button animation previewBase Button animation preview

This preview uses fictional demo content. See the props below for the customization options available in this component.

npx nativeanimation add base-button
Button

Base Button

React Native Button Component

A button with spring-driven press feedback and configurable content, size, variant, and theme.

Native Animation Base · Free · MIT

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

About this component

A button with spring-driven press feedback and configurable content, size, variant, and theme.

How it works

  1. Six variants (default, secondary, outline, ghost, destructive, link) and five sizes read their colors, radius and shadow from the Base theme.
  2. The press is a Gesture Handler tap: it springs to 0.97 on touch-down and back on release (stiffness 550, damping 30, mass 1), on its own shared value so a fast double tap never gets stuck.
  3. Visual heights are 24/32/36/40; a layout wrapper reserves a 48 dp Android or 44 pt iOS/web touch target while preserving the visual surface.
  4. loading swaps the leading slot for a spinner and blocks presses; disabled dims to 50%.

Install

npx nativeanimation add base-button

The CLI also copies base-theme. Dependencies, if you copy by hand:

npx expo install react-native-gesture-handler react-native-reanimated react-native-worklets

Usage

import { BaseButton } from './base-button';

<BaseButton onPress={save}>Save changes</BaseButton>

With icons, variants and states:

<BaseButton variant="outline" size="sm" leading={<Plus size={16} color={theme.colors.foreground} />}>
  New project
</BaseButton>
<BaseButton variant="destructive" loading={deleting} onPress={remove}>Delete</BaseButton>
<BaseButton size="icon" variant="ghost" accessibilityLabel="Next page"><ChevronRight size={16} /></BaseButton>

Wrap your app in BaseThemeProvider (from base-theme) to choose light/dark and an accent; without it, pieces use the light neutral theme. Every piece also takes a theme prop that wins over the provider.

Props

PropTypeDefaultDescription
childrenReactNode—Label text, or any element.
variant'default' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'link''default'Visual style.
size'xs' | 'sm' | 'default' | 'lg' | 'icon''default'Height and padding.
onPress() => void—Called on tap.
loadingbooleanfalseShows a spinner and blocks presses.
disabledbooleanfalseDims and blocks presses.
leading / trailingReactNode—Icon or element before / after the label.
fullWidthbooleanfalseStretches to the container width.
styleStyleProp<ViewStyle>—Extra styles for the button.
accessibilityLabelstring—Required for icon-only buttons.
themeBaseThemeproviderOverrides the theme from BaseThemeProvider.
testIDstring—Test identifier on the root view.

Compatibility

Expo SDK 58 · React Native 0.88 · Reanimated 4.7 · react-native-worklets 0.13. Runs on iOS, Android and web, in Expo Go and in development builds. Part of Native Animation Base, a free family that shares one theme: install base-theme once (the CLI does it for you) and every Base piece picks it up.

Accessibility

Announced as a button with synchronized disabled and busy states. Supports screen-reader activation and Enter/Space on web. With Reduce Motion on, the press scale is skipped; the press still works.

Source code

Loading public source…