Tally UI
UI

Button

A pressable button with multiple visual variants and sizes, built on React Native Pressable.

Import

import { Button, Text } from '@tallyui/components';

Usage

<Button variant="default" onPress={() => console.log('pressed')}>
  <Text>Click me</Text>
</Button>

Button uses TextClassContext to automatically style descendant Text, Icon, and Loader components. You don't need to pass color props to children -- they inherit the right foreground color from the button variant.

Variants

VariantClass
defaultbg-primary active:opacity-90
destructivebg-destructive active:opacity-90
outlineborder border-input bg-background active:bg-accent
secondarybg-secondary active:opacity-80
ghostactive:bg-accent
linkweb:underline-offset-4 web:hover:underline

Sizes

SizeClass
defaulth-10 px-4 py-2
smh-9 rounded-md px-3
lgh-11 rounded-md px-8
iconh-10 w-10

Props

PropTypeDefaultDescription
variant'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link''default'Visual style of the button
size'default' | 'sm' | 'lg' | 'icon''default'Controls height and padding
asChildbooleanfalseWhen true, renders as a Slot instead of Pressable, merging props onto the child element
disabledbooleanfalseDisables the button, applying opacity-50 and blocking pointer events on web
classNamestring-Additional NativeWind classes merged via cn()

Plus all React Native PressableProps (onPress, onLongPress, accessibilityLabel, etc.).

TextClassContext

Button wraps its children in a TextClassContext.Provider so that any Text, Icon, or Loader rendered inside automatically picks up the correct foreground color and font size for the current variant and size combination.

The text classes applied per variant:

VariantText Class
defaulttext-primary-foreground
destructivetext-destructive-foreground
outlinetext-foreground
secondarytext-secondary-foreground
ghosttext-foreground
linktext-primary

The lg size additionally applies text-base; all other sizes use the default text-sm font-medium.

Examples

Basic variants

<Button>
  <Text>Default</Text>
</Button>

<Button variant="destructive">
  <Text>Delete</Text>
</Button>

<Button variant="outline">
  <Text>Outline</Text>
</Button>

With an icon

import { Button, Text, Icon } from '@tallyui/components';
import { Plus } from 'lucide-react-native';

<Button variant="secondary" size="sm">
  <Icon><Plus /></Icon>
  <Text>Add Item</Text>
</Button>

Icon-only button using the icon size

<Button variant="ghost" size="icon">
  <Icon><Settings /></Icon>
</Button>
import { Link } from 'expo-router';

<Button asChild variant="link">
  <Link href="/settings">
    <Text>Go to settings</Text>
  </Link>
</Button>

Disabled state

<Button disabled>
  <Text>Can't touch this</Text>
</Button>

On this page