ButtonUpdated

Interactive component that triggers an action when pressed.

Import

import { Button } from 'heroui-native';

Anatomy

<Button>
  <Button.Label>...</Button.Label>
</Button>
  • Button: Main container that handles press interactions, animations, and variants. Renders string children as label or accepts compound components for custom layouts.
  • Button.Label: Text content of the button. Inherits size and variant styling from parent Button context.

Usage

Basic Usage

The Button component accepts string children that automatically render as label.

<Button>Basic Button</Button>

With Compound Parts

Use Button.Label for explicit control over the label component.

<Button>
  <Button.Label>Click me</Button.Label>
</Button>

With Icons

Combine icons with labels for enhanced visual communication.

<Button>
  <Icon name="add" size={20} />
  <Button.Label>Add Item</Button.Label>
</Button>

<Button>
  <Button.Label>Download</Button.Label>
  <Icon name="download" size={18} />
</Button>

Icon Only

Create square icon-only buttons using the isIconOnly prop.

<Button isIconOnly>
  <Icon name="heart" size={18} />
</Button>

Sizes

Control button dimensions with three size options.

<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>

Variants

Choose from six visual variants for different emphasis levels.

<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="tertiary">Tertiary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="danger">Danger</Button>
<Button variant="danger-soft">Danger Soft</Button>

Feedback Variants

Choose between highlight, ripple, or no feedback effects for press interactions.

{
  /* Highlight feedback (default) */
}
<Button pressableFeedbackVariant="highlight">Highlight Effect</Button>;

{
  /* Ripple feedback */
}
<Button pressableFeedbackVariant="ripple">Ripple Effect</Button>;

{
  /* No feedback overlay (only scale animation) */
}
<Button pressableFeedbackVariant="none">No Overlay</Button>;

{
  /* Customize highlight animation */
}
<Button
  pressableFeedbackVariant="highlight"
  pressableFeedbackHighlightProps={{
    animation: {
      backgroundColor: { value: '#3b82f6' },
      opacity: { value: [0, 0.2] },
    },
  }}
>
  Custom Highlight
</Button>;

{
  /* Customize ripple animation */
}
<Button
  pressableFeedbackVariant="ripple"
  pressableFeedbackRippleProps={{
    animation: {
      backgroundColor: { value: '#3b82f6' },
      opacity: { value: [0, 0.3, 0] },
    },
  }}
>
  Custom Ripple
</Button>;

Loading State with Spinner

Transform button to loading state with spinner animation.

const themeColorAccentForeground = useThemeColor('accent-foreground');

<Button
  layout={LinearTransition.springify()}
  variant="primary"
  onPress={() => {
    setIsDownloading(true);
    setTimeout(() => {
      setIsDownloading(false);
    }, 3000);
  }}
  isIconOnly={isDownloading}
  className="self-center"
>
  {isDownloading ? (
    <Spinner entering={FadeIn.delay(50)} color={themeColorAccentForeground} />
  ) : (
    'Download now'
  )}
</Button>;

Custom Background with LinearGradient

Add gradient backgrounds using absolute positioned elements. Use pressableFeedbackVariant="none" to disable the default highlight overlay, or add a custom ripple effect.

import { Button, PressableFeedback } from 'heroui-native';
import { LinearGradient } from 'expo-linear-gradient';
import { StyleSheet } from 'react-native';

{
  /* Gradient with no feedback overlay */
}
<Button pressableFeedbackVariant="none">
  <LinearGradient
    colors={['#9333ea', '#ec4899']}
    start={{ x: 0, y: 0 }}
    end={{ x: 1, y: 0 }}
    style={StyleSheet.absoluteFill}
  />
  <Button.Label className="text-white font-bold">Gradient</Button.Label>
</Button>;

{
  /* Gradient with custom ripple effect */
}
<Button pressableFeedbackVariant="none">
  <LinearGradient
    colors={['#0d9488', '#ec4899']}
    start={{ x: 0, y: 0 }}
    end={{ x: 1, y: 0 }}
    style={StyleSheet.absoluteFill}
  />
  <PressableFeedback.Ripple
    animation={{
      backgroundColor: { value: 'white' },
      opacity: { value: [0, 0.5, 0] },
    }}
  />
  <Button.Label className="text-white font-bold" pointerEvents="none">
    Gradient with Ripple
  </Button.Label>
</Button>;

Example

import { Button, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View } from 'react-native';

export default function ButtonExample() {
  const [
    themeColorAccentForeground,
    themeColorAccentSoftForeground,
    themeColorDangerForeground,
    themeColorDefaultForeground,
  ] = useThemeColor([
    'accent-foreground',
    'accent-soft-foreground',
    'danger-foreground',
    'default-foreground',
  ]);

  return (
    <View className="gap-4 p-4">
      <Button variant="primary">
        <Ionicons name="add" size={20} color={themeColorAccentForeground} />
        <Button.Label>Add Item</Button.Label>
      </Button>

      <View className="flex-row gap-4">
        <Button size="sm" isIconOnly>
          <Ionicons name="heart" size={16} color={themeColorAccentForeground} />
        </Button>
        <Button size="sm" variant="secondary" isIconOnly>
          <Ionicons
            name="bookmark"
            size={16}
            color={themeColorAccentSoftForeground}
          />
        </Button>
        <Button size="sm" variant="danger" isIconOnly>
          <Ionicons name="trash" size={16} color={themeColorDangerForeground} />
        </Button>
      </View>

      <Button variant="tertiary">
        <Button.Label>Learn More</Button.Label>
        <Ionicons
          name="chevron-forward"
          size={18}
          color={themeColorDefaultForeground}
        />
      </Button>
    </View>
  );
}

You can find more examples in the GitHub repository.

API Reference

Button

Button extends all props from PressableFeedback component with additional button-specific props.

proptypedefaultdescription
variant'primary' | 'secondary' | 'tertiary' | 'ghost' | 'danger' | 'danger-soft''primary'Visual variant of the button
size'sm' | 'md' | 'lg''md'Size of the button
isIconOnlybooleanfalseWhether the button displays an icon only (square aspect ratio)
pressableFeedbackVariant'highlight' | 'ripple' | 'none''highlight'Variant of pressable feedback effect
pressableFeedbackHighlightPropsPressableFeedbackHighlightProps-Props for PressableFeedback.Highlight component
pressableFeedbackRipplePropsPressableFeedbackRippleProps-Props for PressableFeedback.Ripple component

For inherited props including animation (for root scale animation), isDisabled, className, children, and all Pressable props, see PressableFeedback API Reference.

Button.Label

proptypedefaultdescription
childrenReact.ReactNode-Content to be rendered as label
classNamestring-Additional CSS classes
...TextPropsTextProps-All standard Text props are supported

Hooks

useButton

Hook to access the Button context values. Returns the button's size, variant, and disabled state.

import { useButton } from 'heroui-native';

const { size, variant, isDisabled } = useButton();

Return Value

propertytypedescription
size'sm' | 'md' | 'lg'Size of the button
variant'primary' | 'secondary' | 'tertiary' | 'ghost' | 'danger' | 'danger-soft'Visual variant of the button
isDisabledbooleanWhether the button is disabled

Note: This hook must be used within a Button component. It will throw an error if called outside of the button context.

On this page