rcaferati/react-native-awesome-button

React Native button component. Awesome Button is a 3D at 60fps, progress enabled, social ready, extendable, production ready component that renders an awesome animated set of UI buttons. 📱

TypeScript

1,279

189 commits

updated Aug 31, 2026

See the code

README

React Native Awesome Button

@rcaferati/react-native-awesome-button brings the Awesome Button interaction, progress, sizing, and theme system to React Native with native Pressable, accessibility, and animation behavior.

The library exports:

  • AwesomeButton as the default export
  • ThemedButton
  • getTheme
  • explicit TypeScript types such as AwesomeButtonProps, ThemedButtonProps, ButtonWidth, ThemeName, ButtonVariant, and ButtonSize
Blue Awesome Button theme demoRick Awesome Button theme demoCartman Awesome Button theme demo

Live Demo

Try the live package demo on expo.dev.

Open the React Native Awesome Button live Expo demo

Figma File

Explore the shared Awesome Button visual system in the Figma design file. The Figma file is a visual design reference; this package's documentation defines its behavior, accessibility, and public API contract.

Awesome Button components in the shared Figma design file

Installation

npm install @rcaferati/react-native-awesome-button

Current peer support:

  • react >= 18.2.0
  • react-native >= 0.76.0

Basic Usage

import AwesomeButton from '@rcaferati/react-native-awesome-button';

export function SaveButton() {
  return <AwesomeButton>Save</AwesomeButton>;
}

AwesomeButton supports both plain string labels and arbitrary React Native content.

Features

Size Changes

animateSize is enabled by default.

  • fixed-size changes animate with the package's 175 ms size transition
  • auto-width string labels grow and shrink when their measured target width changes
  • with textTransition plus auto width:
    • wider labels start growing immediately and begin text at 30% of the text timeline
    • narrower labels begin text immediately and start shrinking at 30%
    • every transient grapheme frame is measured before it is shown, so an unconstrained auto-width label cannot wrap or clip
  • without textTransition, wider labels keep the fitting source visible until the target fits; the target remains clipped to one line until a matching native layout commit confirms physical-pixel fit, while narrower labels swap before width shrinks
  • fixed, stretch, and externally constrained transitions stay on one clipped line; stable labels regain normal wrapping after settlement
  • text scrambling uses Unicode grapheme clusters, metric-aware Latin pools, a 7 ms slot stagger, and a native frame clock
  • animateSize={false} settles target geometry before text begins; Reduced Motion settles both immediately
  • accessibility keeps exposing the stable target label rather than randomized visual frames
  • fixed-to-auto and auto-to-fixed changes remain instant in 3.1.0
import { ThemedButton } from '@rcaferati/react-native-awesome-button';

export function SizeExample({
  isLong,
  size,
}: {
  isLong: boolean;
  size: 'small' | 'medium' | 'large';
}) {
  const label = isLong ? 'Open analytics dashboard' : 'Open';

  return (
    <>
      <ThemedButton name="basic" autoWidth textTransition>
        {label}
      </ThemedButton>
      <ThemedButton name="basic" autoWidth animateSize={false}>
        {label}
      </ThemedButton>
      <ThemedButton name="rick" size={size}>
        {size}
      </ThemedButton>
    </>
  );
}

Progress Buttons

When progress is enabled, onPress receives a next callback. Call it when your work is done to complete the progress animation and release the button.

import AwesomeButton from '@rcaferati/react-native-awesome-button';

export function SubmitButton() {
  return (
    <AwesomeButton
      progress
      onPress={(next) => {
        setTimeout(() => {
          next?.();
        }, 800);
      }}
    >
      Submit
    </AwesomeButton>
  );
}

Themed Buttons

import { ThemedButton } from '@rcaferati/react-native-awesome-button';

export function ThemeExample() {
  return (
    <>
      <ThemedButton name="rick" type="primary">
        Rick Primary
      </ThemedButton>
      <ThemedButton name="rick" type="secondary">
        Rick Secondary
      </ThemedButton>
    </>
  );
}

If you need the full registered theme object, use getTheme.

import { ThemedButton, getTheme } from '@rcaferati/react-native-awesome-button';

export function ThemeConfigExample() {
  const theme = getTheme(0);

  return (
    <ThemedButton config={theme} type="anchor">
      {theme.title}
    </ThemedButton>
  );
}

getTheme() safely falls back to the default basic theme if the provided index or name is invalid.

Before / After / Extra Content

Use before and after for inline content that should animate with the label, and extra for content rendered behind the button body.

import { StyleSheet, Text } from 'react-native';
import { AntDesign } from '@expo/vector-icons';
import { LinearGradient } from 'expo-linear-gradient';
import AwesomeButton from '@rcaferati/react-native-awesome-button';

export function ButtonContentExample() {
  return (
    <AwesomeButton
      before={<AntDesign name="arrowleft" size={18} color="#FFFFFF" />}
      after={<AntDesign name="arrowright" size={18} color="#FFFFFF" />}
      extra={
        <LinearGradient
          colors={['#4C63D2', '#BC3081', '#F47133', '#FED576']}
          style={StyleSheet.absoluteFillObject}
        />
      }
    >
      <Text style={{ color: '#FFFFFF', fontWeight: '700' }}>Continue</Text>
    </AwesomeButton>
  );
}

Transparent Buttons

transparent is supported on ThemedButton. It removes the visible shell layers while preserving the content, hit target, and active/progress feedback.

import { ThemedButton } from '@rcaferati/react-native-awesome-button';

export function TransparentExample() {
  return (
    <ThemedButton name="bruce" type="anchor" transparent>
      Transparent
    </ThemedButton>
  );
}

Built-in Theme Contract

Theme Names

  • basic
  • bojack
  • cartman
  • mysterion
  • c137
  • rick
  • summer
  • bruce

Variants

  • primary
  • secondary
  • anchor
  • danger
  • disabled
  • flat
  • x (canonical request-only bridge)
  • twitter
  • messenger
  • facebook
  • github
  • linkedin
  • whatsapp
  • reddit
  • pinterest
  • youtube

x is the canonical social request. The legacy closed ButtonVariant and SocialButtonVariant unions still contain twitter so exhaustive v3.1 consumers remain source-compatible; ThemedButtonProps.type accepts the request-only AwesomeButtonVariant bridge, which adds x. A custom theme's optional x style wins for an x request and otherwise falls back to its required legacy twitter style. A twitter request continues to use the legacy key.

Unknown variants fall back safely at runtime instead of crashing.

Sizes

  • icon
  • small
  • medium
  • large

API Reference

The tables below cover the primary consumer-facing props. The checked-in API Extractor report and exported AwesomeButtonProps / ThemedButtonProps types are the complete public TypeScript reference.

AwesomeButton

AttributeTypeDefaultDescription
activityColorstring#FFFFFFActivity indicator color shown during progress mode.
activeOpacitynumber1Opacity applied while the button is pressed.
animatedPlaceholderbooleantrueEnables the shimmer loop when the button has no children.
animateSizebooleantrueAnimates fixed-size geometry changes and auto-width string-label changes.
backgroundActivestringrgba(0, 0, 0, 0.15)Active overlay color rendered over the face while pressed.
backgroundColorstring#c0c0c0Main front-face background color.
backgroundDarkerstring#9f9f9fBottom-face background color used for the raised 3D effect.
backgroundPlaceholderstringrgba(0, 0, 0, 0.15)Placeholder bar background color when the button is empty.
backgroundProgressstringrgba(0, 0, 0, 0.15)Progress bar background color used during progress mode.
backgroundShadowstringrgba(0, 0, 0, 0.15)Shadow layer background color.
beforeReactNodenullContent rendered before the main label inside the button face.
afterReactNodenullContent rendered after the main label inside the button face.
extraReactNodenullContent rendered behind the active/content layers, useful for gradients and custom backgrounds.
childrenReactNodenullButton label or custom content. Plain string labels also support textTransition.
borderColorstringundefinedFront-face border color.
borderRadiusnumber4Shared border radius applied to the button face and lower layers.
borderBottomLeftRadiusnumberundefinedBottom-left radius override.
borderBottomRightRadiusnumberundefinedBottom-right radius override.
borderTopLeftRadiusnumberundefinedTop-left radius override.
borderTopRightRadiusnumberundefinedTop-right radius override.
borderWidthnumber0Front-face border width.
dangerouslySetPressablePropsAwesomeButtonPressableProps{}Escape hatch for extra Pressable props. Core onPress, onPressIn, and onPressOut remain owned by the component.
debouncedPressTimenumber0Debounces onPress in milliseconds.
disabledbooleanfalseDisables interactions and marks the internal Pressable as disabled.
heightnumber60Legacy shell height before padding. Its moving face is the shell height minus the resolved raise amount.
faceHeightnumberundefinedCanonical moving-face height bridge. Wins over legacy height.
hitSlopPressableProps['hitSlop']undefinedOptional press target expansion.
paddingHorizontalnumber16Horizontal content padding.
paddingTopnumber0Additional top padding for the content row.
paddingBottomnumber0Additional bottom padding for the content row.
progressbooleanfalseEnables the progress-button flow. onPress receives a next callback in this mode.
progressLoadingTimenumber3000Duration of the loading bar animation in progress mode.
showProgressBarbooleantrueShows or hides the face progress layer. The spinner, busy state, callbacks, and completion handle remain active when false.
raiseLevelnumber4Vertical raise distance used to render the 3D depth effect.
springReleasebooleantrueUses spring-based release animation instead of timing-based release.
stretchbooleanfalseMakes the button fill the available horizontal space.
styleStyleProp<ViewStyle>undefinedExtra style applied to the outer animated container.
containerStyleStyleProp<ViewStyle>undefinedCanonical outer layout style. Applied after legacy outer style.
buttonStyleAwesomeButtonStyleundefinedCanonical visual bridge. Its fields win over legacy top-level visual aliases; animationDuration owns direct resolved-palette changes and pressInAnimationDuration overrides press-down timing.
textColorstring#FFFFFFDefault label text color.
textFontFamilystringundefinedOptional font family for string labels.
textLineHeightnumber20Placeholder bar height and the resolved line height applied to visible and measured string labels.
textSizenumber14Default font size for string labels.
textTransitionbooleanfalseEnables the measured, grapheme-aware scramble/reveal animation for nonempty string-label replacements. Transient frames are one line; Reduced Motion settles immediately.
widthnumber | 'auto' | nullnullFixed width, measured auto width (null / 'auto'), or pair with stretch for full width. Auto-width string labels can now both grow and shrink.
onPress(next?) => voidundefinedMain press callback. In progress mode it receives the completion handler.
onLongPressPressableProps['onLongPress']undefinedDeprecated physical-only callback that receives the real press event.
onLongPressAction() => voidundefinedEventless physical and assistive long action. Wins over legacy eventful onLongPress.
accessibilityLabelstring | undefinedundefinedSpoken identity override; plain string children are inferred when absent.
accessibilityHintstring | undefinedundefinedOptional explanation for ordinary assistive activation.
accessibilityLongPressLabelstring | undefinedundefinedOptional name for the eventless assistive long action.
onPressIn(event) => voidundefinedNative press-in observer callback.
onPressOut(event) => voidundefinedNative press-out observer callback.
onPressedIn() => voidundefinedFires after committed eligibility is revalidated and before press-down visual work starts.
onPressedOut() => voidundefinedFires after the internal release animation completes.
onProgressStart() => voidundefinedFires when progress mode transitions into loading.
onProgressEnd() => voidundefinedFires when progress mode finishes and the button releases.

ThemedButton

ThemedButton accepts the AwesomeButton props plus these theme-resolution props.

AttributeTypeDefaultDescription
configAwesomeButtonThemeDefinitionundefinedExplicit theme object. When provided, it takes precedence over name and index.
flatbooleanfalseRequests the flat theme variant when available, including while disabled.
indexnumber | nullnullTheme index used by getTheme(index) when config and name are not provided.
nameThemeName | nullnullNamed built-in theme selector. Falls back safely to basic if invalid.
sizeButtonSizemediumBuilt-in theme size preset: icon, small, medium, or large.
transparentbooleanfalseMakes the visible shell layers transparent while keeping content, press, and progress feedback active.
autoWidthbooleanundefinedCanonical intrinsic-width decision. An explicit value wins over the legacy width="auto" sentinel.
typeAwesomeButtonVariantprimaryBuilt-in variant request, including canonical x.

Interaction and Lifecycle

Physical presses, long presses, keyboard activation, and accessibility actions share one eligibility, debounce, and one-shot progress contract. Callback replacements committed before dispatch remain live; release and accepted progress-completion callbacks are captured when their transition begins. Disablement, placeholder entry, pointer cancellation, and unmount terminate an active gesture once without dispatching a stale activation.

Accessibility, Reduced Motion, and Numeric Validation

The button exposes one native button element. Atomic accessibility activation shares debounce and progress ownership without fabricating held onPressIn/onPressOut callbacks. Disabled, busy, and placeholder states remove package activation actions. Custom content that does not provide a plain string should supply accessibilityLabel.

Reduced Motion snaps package-owned press, release, style, size, text, placeholder, and progress presentation while preserving callback ordering, debounce, long-press thresholds, and progress completion ownership. A progress run keeps its spinner/content lifecycle; showProgressBar={false} omits only the traveling/static face layer.

Numeric inputs never throw: non-finite optional values act as absent, non-finite required values use their declared defaults, negative geometry and durations clamp to zero, and opacity clamps to [0, 1]. Fixed width zero stays an explicit constrained width.

React Native Compatibility and Migration

The compatibility bridge keeps v3.1 behavior callable while making the shared vocabulary available. Bridge fields win conflicts; no implicit parity mode changes legacy geometry or defaults.

Current fieldCanonical replacementCurrent behavior
outer stylecontainerStyleBoth remain; containerStyle wins.
buttonStylefuture styleTyped canonical visual bridge; rename is deferred to a major.
legacy heightfaceHeight (future height)Legacy stack geometry remains; faceHeight wins when supplied.
width="auto"autoWidth={true}Sentinel remains; an explicit autoWidth decision wins.
eventful onLongPressonLongPressAction (future onLongPress)Legacy callback is physical-only; the eventless bridge owns assistive long activation.
backgroundDarkerbuttonStyle.depthColorLegacy alias remains at lower precedence.
backgroundShadowbuttonStyle.shadowColorLegacy alias remains at lower precedence.
textColorbuttonStyle.foregroundColorLegacy alias remains at lower precedence.
raiseLevelbuttonStyle.raiseAmountLegacy alias remains at lower precedence.
borderLeftBottomRadiusbuttonStyle.borderBottomLeftRadiusMisspelled alias remains at lower precedence.
activityColorbuttonStyle.activityColorLegacy alias remains at lower precedence.
activeOpacitybuttonStyle.activeOpacityLegacy alias remains at lower precedence.
backgroundActivebuttonStyle.backgroundActiveLegacy alias remains at lower precedence.
backgroundColorbuttonStyle.backgroundColorLegacy alias remains at lower precedence.
backgroundPlaceholderbuttonStyle.backgroundPlaceholderLegacy alias remains at lower precedence.
backgroundProgressbuttonStyle.backgroundProgressLegacy alias remains at lower precedence.
borderColorbuttonStyle.borderColorLegacy alias remains at lower precedence.
borderRadiusbuttonStyle.borderRadiusLegacy alias remains at lower precedence.
borderTopLeftRadiusbuttonStyle.borderTopLeftRadiusLegacy alias remains at lower precedence.
borderTopRightRadiusbuttonStyle.borderTopRightRadiusLegacy alias remains at lower precedence.
borderBottomLeftRadiusbuttonStyle.borderBottomLeftRadiusLegacy alias remains at lower precedence.
borderBottomRightRadiusbuttonStyle.borderBottomRightRadiusLegacy alias remains at lower precedence.
borderWidthbuttonStyle.borderWidthLegacy alias remains at lower precedence.
paddingHorizontalbuttonStyle.paddingHorizontalLegacy alias remains at lower precedence.
paddingTopbuttonStyle.paddingTopLegacy alias remains at lower precedence.
paddingBottombuttonStyle.paddingBottomLegacy alias remains at lower precedence.
textFontFamilybuttonStyle.textFontFamilyLegacy alias remains at lower precedence.
textLineHeightbuttonStyle.textLineHeightLegacy alias remains at lower precedence.
textSizebuttonStyle.textSizeLegacy alias remains at lower precedence.
springReleasenative release springBoth legacy values remain; the optional non-spring path is noncanonical debt.
twitterrequest-only xLegacy closed unions/maps stay unchanged; removal requires a reviewed major migration.

React Native still has explicit cross-platform debt: its legacy outer style, legacy height meaning and default geometry, 100 ms press fallback when no bridge timing is supplied, and optional non-spring release behavior. This release does not claim complete family parity.

Development

Root quality gates:

yarn release:check

The aggregate checks formatting, ESLint, TypeScript, package-owned Jest tests with informational coverage, the built package, reviewed API report, exported TSDoc summaries, and the npm tarball shape. It does not publish or modify the API baseline. See CONTRIBUTING.md, MIGRATION.md, and PERFORMANCE.md.

Demo app commands:

yarn --cwd demo install
yarn demo
yarn demo:ios
yarn demo:android
yarn demo:web

The Expo demo resolves @rcaferati/react-native-awesome-button to the local src/ folder, so you can iterate on the library without publishing it first.

Demo Application

The demo/ app is an Expo SDK 52 compatibility harness for:

  • the Themed tab, covering every registered theme, placeholder and flat states, before/after/icon slots, auto-width, stretch, and extra content
  • the Progress tab, covering progress ownership and completion
  • the Social tab, covering every social visual variant
  • the Size Changes tab, covering variant, text, and geometry transitions

See demo/README.md for demo-specific instructions.

Awesome Button Family

Awesome Button is maintained as four native packages that share product semantics while following each platform's implementation model:

Author

Created and maintained by Rafael Caferati.

License

MIT. See LICENSE.

animated
button
component
progress
react
react-native
share
social

rcaferati/react-native-awesome-button

React Native button component. Awesome Button is a 3D at 60fps, progress enabled, social ready, extendable, production ready component that renders an awesome animated set of UI buttons. 📱

TypeScript

1,279

189 commits

updated Aug 31, 2026

See the code

README

React Native Awesome Button

@rcaferati/react-native-awesome-button brings the Awesome Button interaction, progress, sizing, and theme system to React Native with native Pressable, accessibility, and animation behavior.

The library exports:

  • AwesomeButton as the default export
  • ThemedButton
  • getTheme
  • explicit TypeScript types such as AwesomeButtonProps, ThemedButtonProps, ButtonWidth, ThemeName, ButtonVariant, and ButtonSize
Blue Awesome Button theme demoRick Awesome Button theme demoCartman Awesome Button theme demo

Live Demo

Try the live package demo on expo.dev.

Open the React Native Awesome Button live Expo demo

Figma File

Explore the shared Awesome Button visual system in the Figma design file. The Figma file is a visual design reference; this package's documentation defines its behavior, accessibility, and public API contract.

Awesome Button components in the shared Figma design file

Installation

npm install @rcaferati/react-native-awesome-button

Current peer support:

  • react >= 18.2.0
  • react-native >= 0.76.0

Basic Usage

import AwesomeButton from '@rcaferati/react-native-awesome-button';

export function SaveButton() {
  return <AwesomeButton>Save</AwesomeButton>;
}

AwesomeButton supports both plain string labels and arbitrary React Native content.

Features

Size Changes

animateSize is enabled by default.

  • fixed-size changes animate with the package's 175 ms size transition
  • auto-width string labels grow and shrink when their measured target width changes
  • with textTransition plus auto width:
    • wider labels start growing immediately and begin text at 30% of the text timeline
    • narrower labels begin text immediately and start shrinking at 30%
    • every transient grapheme frame is measured before it is shown, so an unconstrained auto-width label cannot wrap or clip
  • without textTransition, wider labels keep the fitting source visible until the target fits; the target remains clipped to one line until a matching native layout commit confirms physical-pixel fit, while narrower labels swap before width shrinks
  • fixed, stretch, and externally constrained transitions stay on one clipped line; stable labels regain normal wrapping after settlement
  • text scrambling uses Unicode grapheme clusters, metric-aware Latin pools, a 7 ms slot stagger, and a native frame clock
  • animateSize={false} settles target geometry before text begins; Reduced Motion settles both immediately
  • accessibility keeps exposing the stable target label rather than randomized visual frames
  • fixed-to-auto and auto-to-fixed changes remain instant in 3.1.0
import { ThemedButton } from '@rcaferati/react-native-awesome-button';

export function SizeExample({
  isLong,
  size,
}: {
  isLong: boolean;
  size: 'small' | 'medium' | 'large';
}) {
  const label = isLong ? 'Open analytics dashboard' : 'Open';

  return (
    <>
      <ThemedButton name="basic" autoWidth textTransition>
        {label}
      </ThemedButton>
      <ThemedButton name="basic" autoWidth animateSize={false}>
        {label}
      </ThemedButton>
      <ThemedButton name="rick" size={size}>
        {size}
      </ThemedButton>
    </>
  );
}

Progress Buttons

When progress is enabled, onPress receives a next callback. Call it when your work is done to complete the progress animation and release the button.

import AwesomeButton from '@rcaferati/react-native-awesome-button';

export function SubmitButton() {
  return (
    <AwesomeButton
      progress
      onPress={(next) => {
        setTimeout(() => {
          next?.();
        }, 800);
      }}
    >
      Submit
    </AwesomeButton>
  );
}

Themed Buttons

import { ThemedButton } from '@rcaferati/react-native-awesome-button';

export function ThemeExample() {
  return (
    <>
      <ThemedButton name="rick" type="primary">
        Rick Primary
      </ThemedButton>
      <ThemedButton name="rick" type="secondary">
        Rick Secondary
      </ThemedButton>
    </>
  );
}

If you need the full registered theme object, use getTheme.

import { ThemedButton, getTheme } from '@rcaferati/react-native-awesome-button';

export function ThemeConfigExample() {
  const theme = getTheme(0);

  return (
    <ThemedButton config={theme} type="anchor">
      {theme.title}
    </ThemedButton>
  );
}

getTheme() safely falls back to the default basic theme if the provided index or name is invalid.

Before / After / Extra Content

Use before and after for inline content that should animate with the label, and extra for content rendered behind the button body.

import { StyleSheet, Text } from 'react-native';
import { AntDesign } from '@expo/vector-icons';
import { LinearGradient } from 'expo-linear-gradient';
import AwesomeButton from '@rcaferati/react-native-awesome-button';

export function ButtonContentExample() {
  return (
    <AwesomeButton
      before={<AntDesign name="arrowleft" size={18} color="#FFFFFF" />}
      after={<AntDesign name="arrowright" size={18} color="#FFFFFF" />}
      extra={
        <LinearGradient
          colors={['#4C63D2', '#BC3081', '#F47133', '#FED576']}
          style={StyleSheet.absoluteFillObject}
        />
      }
    >
      <Text style={{ color: '#FFFFFF', fontWeight: '700' }}>Continue</Text>
    </AwesomeButton>
  );
}

Transparent Buttons

transparent is supported on ThemedButton. It removes the visible shell layers while preserving the content, hit target, and active/progress feedback.

import { ThemedButton } from '@rcaferati/react-native-awesome-button';

export function TransparentExample() {
  return (
    <ThemedButton name="bruce" type="anchor" transparent>
      Transparent
    </ThemedButton>
  );
}

Built-in Theme Contract

Theme Names

  • basic
  • bojack
  • cartman
  • mysterion
  • c137
  • rick
  • summer
  • bruce

Variants

  • primary
  • secondary
  • anchor
  • danger
  • disabled
  • flat
  • x (canonical request-only bridge)
  • twitter
  • messenger
  • facebook
  • github
  • linkedin
  • whatsapp
  • reddit
  • pinterest
  • youtube

x is the canonical social request. The legacy closed ButtonVariant and SocialButtonVariant unions still contain twitter so exhaustive v3.1 consumers remain source-compatible; ThemedButtonProps.type accepts the request-only AwesomeButtonVariant bridge, which adds x. A custom theme's optional x style wins for an x request and otherwise falls back to its required legacy twitter style. A twitter request continues to use the legacy key.

Unknown variants fall back safely at runtime instead of crashing.

Sizes

  • icon
  • small
  • medium
  • large

API Reference

The tables below cover the primary consumer-facing props. The checked-in API Extractor report and exported AwesomeButtonProps / ThemedButtonProps types are the complete public TypeScript reference.

AwesomeButton

AttributeTypeDefaultDescription
activityColorstring#FFFFFFActivity indicator color shown during progress mode.
activeOpacitynumber1Opacity applied while the button is pressed.
animatedPlaceholderbooleantrueEnables the shimmer loop when the button has no children.
animateSizebooleantrueAnimates fixed-size geometry changes and auto-width string-label changes.
backgroundActivestringrgba(0, 0, 0, 0.15)Active overlay color rendered over the face while pressed.
backgroundColorstring#c0c0c0Main front-face background color.
backgroundDarkerstring#9f9f9fBottom-face background color used for the raised 3D effect.
backgroundPlaceholderstringrgba(0, 0, 0, 0.15)Placeholder bar background color when the button is empty.
backgroundProgressstringrgba(0, 0, 0, 0.15)Progress bar background color used during progress mode.
backgroundShadowstringrgba(0, 0, 0, 0.15)Shadow layer background color.
beforeReactNodenullContent rendered before the main label inside the button face.
afterReactNodenullContent rendered after the main label inside the button face.
extraReactNodenullContent rendered behind the active/content layers, useful for gradients and custom backgrounds.
childrenReactNodenullButton label or custom content. Plain string labels also support textTransition.
borderColorstringundefinedFront-face border color.
borderRadiusnumber4Shared border radius applied to the button face and lower layers.
borderBottomLeftRadiusnumberundefinedBottom-left radius override.
borderBottomRightRadiusnumberundefinedBottom-right radius override.
borderTopLeftRadiusnumberundefinedTop-left radius override.
borderTopRightRadiusnumberundefinedTop-right radius override.
borderWidthnumber0Front-face border width.
dangerouslySetPressablePropsAwesomeButtonPressableProps{}Escape hatch for extra Pressable props. Core onPress, onPressIn, and onPressOut remain owned by the component.
debouncedPressTimenumber0Debounces onPress in milliseconds.
disabledbooleanfalseDisables interactions and marks the internal Pressable as disabled.
heightnumber60Legacy shell height before padding. Its moving face is the shell height minus the resolved raise amount.
faceHeightnumberundefinedCanonical moving-face height bridge. Wins over legacy height.
hitSlopPressableProps['hitSlop']undefinedOptional press target expansion.
paddingHorizontalnumber16Horizontal content padding.
paddingTopnumber0Additional top padding for the content row.
paddingBottomnumber0Additional bottom padding for the content row.
progressbooleanfalseEnables the progress-button flow. onPress receives a next callback in this mode.
progressLoadingTimenumber3000Duration of the loading bar animation in progress mode.
showProgressBarbooleantrueShows or hides the face progress layer. The spinner, busy state, callbacks, and completion handle remain active when false.
raiseLevelnumber4Vertical raise distance used to render the 3D depth effect.
springReleasebooleantrueUses spring-based release animation instead of timing-based release.
stretchbooleanfalseMakes the button fill the available horizontal space.
styleStyleProp<ViewStyle>undefinedExtra style applied to the outer animated container.
containerStyleStyleProp<ViewStyle>undefinedCanonical outer layout style. Applied after legacy outer style.
buttonStyleAwesomeButtonStyleundefinedCanonical visual bridge. Its fields win over legacy top-level visual aliases; animationDuration owns direct resolved-palette changes and pressInAnimationDuration overrides press-down timing.
textColorstring#FFFFFFDefault label text color.
textFontFamilystringundefinedOptional font family for string labels.
textLineHeightnumber20Placeholder bar height and the resolved line height applied to visible and measured string labels.
textSizenumber14Default font size for string labels.
textTransitionbooleanfalseEnables the measured, grapheme-aware scramble/reveal animation for nonempty string-label replacements. Transient frames are one line; Reduced Motion settles immediately.
widthnumber | 'auto' | nullnullFixed width, measured auto width (null / 'auto'), or pair with stretch for full width. Auto-width string labels can now both grow and shrink.
onPress(next?) => voidundefinedMain press callback. In progress mode it receives the completion handler.
onLongPressPressableProps['onLongPress']undefinedDeprecated physical-only callback that receives the real press event.
onLongPressAction() => voidundefinedEventless physical and assistive long action. Wins over legacy eventful onLongPress.
accessibilityLabelstring | undefinedundefinedSpoken identity override; plain string children are inferred when absent.
accessibilityHintstring | undefinedundefinedOptional explanation for ordinary assistive activation.
accessibilityLongPressLabelstring | undefinedundefinedOptional name for the eventless assistive long action.
onPressIn(event) => voidundefinedNative press-in observer callback.
onPressOut(event) => voidundefinedNative press-out observer callback.
onPressedIn() => voidundefinedFires after committed eligibility is revalidated and before press-down visual work starts.
onPressedOut() => voidundefinedFires after the internal release animation completes.
onProgressStart() => voidundefinedFires when progress mode transitions into loading.
onProgressEnd() => voidundefinedFires when progress mode finishes and the button releases.

ThemedButton

ThemedButton accepts the AwesomeButton props plus these theme-resolution props.

AttributeTypeDefaultDescription
configAwesomeButtonThemeDefinitionundefinedExplicit theme object. When provided, it takes precedence over name and index.
flatbooleanfalseRequests the flat theme variant when available, including while disabled.
indexnumber | nullnullTheme index used by getTheme(index) when config and name are not provided.
nameThemeName | nullnullNamed built-in theme selector. Falls back safely to basic if invalid.
sizeButtonSizemediumBuilt-in theme size preset: icon, small, medium, or large.
transparentbooleanfalseMakes the visible shell layers transparent while keeping content, press, and progress feedback active.
autoWidthbooleanundefinedCanonical intrinsic-width decision. An explicit value wins over the legacy width="auto" sentinel.
typeAwesomeButtonVariantprimaryBuilt-in variant request, including canonical x.

Interaction and Lifecycle

Physical presses, long presses, keyboard activation, and accessibility actions share one eligibility, debounce, and one-shot progress contract. Callback replacements committed before dispatch remain live; release and accepted progress-completion callbacks are captured when their transition begins. Disablement, placeholder entry, pointer cancellation, and unmount terminate an active gesture once without dispatching a stale activation.

Accessibility, Reduced Motion, and Numeric Validation

The button exposes one native button element. Atomic accessibility activation shares debounce and progress ownership without fabricating held onPressIn/onPressOut callbacks. Disabled, busy, and placeholder states remove package activation actions. Custom content that does not provide a plain string should supply accessibilityLabel.

Reduced Motion snaps package-owned press, release, style, size, text, placeholder, and progress presentation while preserving callback ordering, debounce, long-press thresholds, and progress completion ownership. A progress run keeps its spinner/content lifecycle; showProgressBar={false} omits only the traveling/static face layer.

Numeric inputs never throw: non-finite optional values act as absent, non-finite required values use their declared defaults, negative geometry and durations clamp to zero, and opacity clamps to [0, 1]. Fixed width zero stays an explicit constrained width.

React Native Compatibility and Migration

The compatibility bridge keeps v3.1 behavior callable while making the shared vocabulary available. Bridge fields win conflicts; no implicit parity mode changes legacy geometry or defaults.

Current fieldCanonical replacementCurrent behavior
outer stylecontainerStyleBoth remain; containerStyle wins.
buttonStylefuture styleTyped canonical visual bridge; rename is deferred to a major.
legacy heightfaceHeight (future height)Legacy stack geometry remains; faceHeight wins when supplied.
width="auto"autoWidth={true}Sentinel remains; an explicit autoWidth decision wins.
eventful onLongPressonLongPressAction (future onLongPress)Legacy callback is physical-only; the eventless bridge owns assistive long activation.
backgroundDarkerbuttonStyle.depthColorLegacy alias remains at lower precedence.
backgroundShadowbuttonStyle.shadowColorLegacy alias remains at lower precedence.
textColorbuttonStyle.foregroundColorLegacy alias remains at lower precedence.
raiseLevelbuttonStyle.raiseAmountLegacy alias remains at lower precedence.
borderLeftBottomRadiusbuttonStyle.borderBottomLeftRadiusMisspelled alias remains at lower precedence.
activityColorbuttonStyle.activityColorLegacy alias remains at lower precedence.
activeOpacitybuttonStyle.activeOpacityLegacy alias remains at lower precedence.
backgroundActivebuttonStyle.backgroundActiveLegacy alias remains at lower precedence.
backgroundColorbuttonStyle.backgroundColorLegacy alias remains at lower precedence.
backgroundPlaceholderbuttonStyle.backgroundPlaceholderLegacy alias remains at lower precedence.
backgroundProgressbuttonStyle.backgroundProgressLegacy alias remains at lower precedence.
borderColorbuttonStyle.borderColorLegacy alias remains at lower precedence.
borderRadiusbuttonStyle.borderRadiusLegacy alias remains at lower precedence.
borderTopLeftRadiusbuttonStyle.borderTopLeftRadiusLegacy alias remains at lower precedence.
borderTopRightRadiusbuttonStyle.borderTopRightRadiusLegacy alias remains at lower precedence.
borderBottomLeftRadiusbuttonStyle.borderBottomLeftRadiusLegacy alias remains at lower precedence.
borderBottomRightRadiusbuttonStyle.borderBottomRightRadiusLegacy alias remains at lower precedence.
borderWidthbuttonStyle.borderWidthLegacy alias remains at lower precedence.
paddingHorizontalbuttonStyle.paddingHorizontalLegacy alias remains at lower precedence.
paddingTopbuttonStyle.paddingTopLegacy alias remains at lower precedence.
paddingBottombuttonStyle.paddingBottomLegacy alias remains at lower precedence.
textFontFamilybuttonStyle.textFontFamilyLegacy alias remains at lower precedence.
textLineHeightbuttonStyle.textLineHeightLegacy alias remains at lower precedence.
textSizebuttonStyle.textSizeLegacy alias remains at lower precedence.
springReleasenative release springBoth legacy values remain; the optional non-spring path is noncanonical debt.
twitterrequest-only xLegacy closed unions/maps stay unchanged; removal requires a reviewed major migration.

React Native still has explicit cross-platform debt: its legacy outer style, legacy height meaning and default geometry, 100 ms press fallback when no bridge timing is supplied, and optional non-spring release behavior. This release does not claim complete family parity.

Development

Root quality gates:

yarn release:check

The aggregate checks formatting, ESLint, TypeScript, package-owned Jest tests with informational coverage, the built package, reviewed API report, exported TSDoc summaries, and the npm tarball shape. It does not publish or modify the API baseline. See CONTRIBUTING.md, MIGRATION.md, and PERFORMANCE.md.

Demo app commands:

yarn --cwd demo install
yarn demo
yarn demo:ios
yarn demo:android
yarn demo:web

The Expo demo resolves @rcaferati/react-native-awesome-button to the local src/ folder, so you can iterate on the library without publishing it first.

Demo Application

The demo/ app is an Expo SDK 52 compatibility harness for:

  • the Themed tab, covering every registered theme, placeholder and flat states, before/after/icon slots, auto-width, stretch, and extra content
  • the Progress tab, covering progress ownership and completion
  • the Social tab, covering every social visual variant
  • the Size Changes tab, covering variant, text, and geometry transitions

See demo/README.md for demo-specific instructions.

Awesome Button Family

Awesome Button is maintained as four native packages that share product semantics while following each platform's implementation model:

Author

Created and maintained by Rafael Caferati.

License

MIT. See LICENSE.

animated
button
component
progress
react
react-native
share
social

Project health

Latest release

3.2.0 · Aug 31, 2026

Releases this year

4

Significant stargazers

Alexey Pyltsyn

1,272 followers · starred Apr 2018

Jesse Katsumata

441 followers · starred Jun 2020

Hein Rutjes

939 followers · starred Aug 2018

Alex Reichert

99 followers · starred May 2024