Button
A springy pill button, five variants, four sizes, spring scale and a haptic tick on every press.
Prerequisites
The button only needs the basics. expo install pins the versions that match your SDK, and the CLI tells you exactly which ones are missing when you add the component.
npx expo install react-native-reanimated expo-haptics expo-blur expo-glass-effect react-native-css @hugeicons/react-native @hugeicons/core-free-icons
Install
npx @rslab/cli add button
Usage
import { Button } from '@/components/ui/Button';
<Button onPress={submit}>Get started</Button>
<Button variant="secondary" size="sm">Cancel</Button>
<Button variant="destructive" loading={deleting} onPress={remove}>
Delete
</Button>
Pass a plain string and it becomes a styled label. Pass any node and it renders as-is, so an icon plus a label is just children order:
<Button>
<SymbolView name="plus" size={16} tintColor="#fafafa" />
New item
</Button>
<Button variant="outline" size="icon">
<SymbolView name="heart" size={17} tintColor={color} />
</Button>
Buttons stretch to their parent by default (column layouts). Put them in a flex-row or pass className="self-start" to make them hug their content.
Props
variant?'primary''secondary''outline''ghost''glass''destructive''primary'Visual style. glass is real Liquid Glass on iOS 26 (expo-glass-effect) with a blur fallback everywhere else; put it over content, it looks flat on plain backgrounds.
size?'sm''md''lg''icon''md'loading?booleanfalseA rotating spinner slides in next to the label, press disabled.
success?booleanfalseAn animated checkmark pops in next to the label with a spring scale.
haptic?booleantrueLight haptic tick on press-in. Set false to mute it.
className?string-Extend or override the container styles.
labelClassName?string-Extend or override the label styles.
Everything else a Pressable takes is forwarded.
See exactly how this works with an RSLAB subscription.
Get Pro