Button
A versatile button component built for React Native with web support, featuring multiple variants, sizes, and states.
The Button component is a flexible and accessible button built with React Native's Pressable component. It supports multiple visual variants, sizes, border radius options, loading states, and is fully compatible with both React Native and web platforms.
Preview
Installation
The Button component is part of the novaui-components package. Make sure you have the required peer dependencies installed:
npx novaui-cli add buttonImport
import { Button } from 'novaui-components'Basic Usage
The Button component accepts label prop or children for the button text:
import { Button } from 'novaui-components'
export function MyComponent() {
return (
<>
<Button label="Click me" />
<Button>Or use children</Button>
</>
)
}Variants
The Button component supports six visual variants, each designed for different use cases:
Default
The primary button variant, perfect for main actions:
<Button variant="default" label="Default Button" />Destructive
Use for dangerous or destructive actions like delete or remove:
<Button variant="destructive" label="Delete" />Outline
A button with an outlined border, great for secondary actions:
<Button variant="outline" label="Outline Button" />Secondary
A secondary button variant with a subtle background:
<Button variant="secondary" label="Secondary Button" />Ghost
A minimal button with no background, ideal for subtle actions:
<Button variant="ghost" label="Ghost Button" />Link
A text-only button styled like a link:
<Button variant="link" label="Link Button" />Sizes
Control the button size with the size prop:
Default
The standard button size:
<Button size="default" label="Default Size" />Small
Compact size for tight spaces:
<Button size="sm" label="Small Button" />Large
Larger size for prominent actions:
<Button size="lg" label="Large Button" />Icon
Square button perfect for icon-only buttons:
<Button size="icon" label="🚀" />Border Radius
Customize the button's border radius with the radius prop:
<Button radius="none" label="No Radius" />
<Button radius="sm" label="Small Radius" />
<Button radius="md" label="Medium Radius" />
<Button radius="lg" label="Large Radius" />
<Button radius="xl" label="Extra Large Radius" />
<Button radius="2xl" label="2XL Radius" />
<Button radius="full" label="Full Radius" />Loading State
Display a loading indicator while an action is in progress:
import { useState } from 'react'
import { Button } from 'novaui-components'
export function LoadingButton() {
const [isLoading, setIsLoading] = useState(false)
const handlePress = async () => {
setIsLoading(true)
// Simulate async operation
await new Promise(resolve => setTimeout(resolve, 2000))
setIsLoading(false)
}
return (
<Button
label="Submit"
isLoading={isLoading}
onPress={handlePress}
/>
)
}When isLoading is true, the button automatically:
- Shows an
ActivityIndicatorspinner - Disables interaction
- Adjusts the spinner color based on the variant
Disabled State
Disable the button to prevent user interaction:
<Button label="Disabled Button" disabled />The button will be visually dimmed and non-interactive when disabled.
Custom Styling
Custom Class Names
Apply custom styles using the className prop:
<Button
label="Custom Button"
className="bg-purple-500 active:bg-purple-600"
/>Custom Label Styling
Style the button label separately using labelClasses:
<Button
label="Styled Label"
labelClasses="font-bold text-lg"
/>Advanced Examples
Button with Icon
Combine the Button with icons or other components:
import { Button } from 'novaui-components'
import { Heart } from 'lucide-react-native'
export function IconButton() {
return (
<Button size="icon" className="bg-red-500">
<Heart size={20} color="white" />
</Button>
)
}Full Width Button
Make a button span the full width:
<Button
label="Full Width Button"
className="w-full"
/>Button Group
Create a group of buttons:
<View className="flex-row gap-2">
<Button variant="outline" label="Cancel" />
<Button variant="default" label="Confirm" />
</View>Props API
ButtonProps
Extends React.ComponentPropsWithoutRef<typeof Pressable> and includes:
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' | 'default' | The visual style variant of the button |
size | 'default' | 'sm' | 'lg' | 'icon' | 'default' | The size of the button |
radius | 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full' | 'md' | The border radius of the button |
label | string | - | The text content of the button (alternative to children) |
labelClasses | string | - | Additional CSS classes for the label text |
isLoading | boolean | false | Shows a loading spinner and disables the button |
disabled | boolean | false | Disables the button interaction |
className | string | - | Additional CSS classes for the button container |
children | React.ReactNode | - | Button content (alternative to label) |
All standard Pressable props are also supported, including:
onPress- Callback when button is pressedonPressIn- Callback when press startsonPressOut- Callback when press endsonLongPress- Callback for long pressaccessibilityLabel- Accessibility label- And all other React Native
Pressableprops
Accessibility
The Button component includes built-in accessibility features:
- Role: Automatically sets
role="button"for screen readers - Hit Slop: Includes default hit slop (10px on all sides) for easier tapping on small devices
- Disabled State: Properly handles disabled state for accessibility
- Focus States: Web-specific focus-visible states for keyboard navigation
Platform Support
The Button component is designed to work seamlessly across platforms:
- React Native: Full support with native touch interactions
- Web: Enhanced with hover states, focus rings, and keyboard navigation
- Responsive: Adapts sizing for different screen sizes (native vs web)
Best Practices
-
Use appropriate variants: Choose variants that match the action's importance
defaultfor primary actionsoutlineorsecondaryfor secondary actionsdestructivefor dangerous actionsghostorlinkfor tertiary actions
-
Loading states: Always use
isLoadingfor async operations to provide user feedback -
Accessibility: Always provide meaningful labels and accessibility descriptions for icon-only buttons
-
Touch targets: The component includes default hit slop, but ensure buttons are at least 44x44 points for optimal touch interaction
-
Consistent sizing: Use consistent button sizes throughout your app for better UX
Related Components
- Consider using Button in combination with other form components
- Use Button groups for related actions
- Combine with icons from
lucide-react-nativefor enhanced visual communication