Button
Buttons help people take actions and make choices with a single tap. Follows the Material Design 3 Button specification.
Usage
import { Button } from '@onlynative/components'
import { ThemeProvider } from '@onlynative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'
export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', padding: 16 }}>
<Button variant="filled" onPress={() => console.log('pressed')}>
Save
</Button>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}
Variants
| Variant | Use case |
|---|---|
filled | Primary action, highest emphasis |
elevated | Elevated surface, medium emphasis |
outlined | Secondary action, medium emphasis |
text | Low emphasis, often in dialogs |
tonal | Secondary container fill |
import { Button } from '@onlynative/components'
import { ThemeProvider } from '@onlynative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'
export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider>
<View style={{ flex: 1, justifyContent: 'center', padding: 16, gap: 12 }}>
<Button variant="filled" onPress={() => {}}>Filled</Button>
<Button variant="elevated" onPress={() => {}}>Elevated</Button>
<Button variant="outlined" onPress={() => {}}>Outlined</Button>
<Button variant="text" onPress={() => {}}>Text</Button>
<Button variant="tonal" onPress={() => {}}>Tonal</Button>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}
With Icons
leadingIcon and trailingIcon accept three forms — a string name (resolved via MaterialCommunityIcons by default), a pre-rendered React element from any icon library, or a render function that receives the resolved { size, color }. See the Icons guide for full details, including how to register a global iconResolver for Lucide, SF Symbols, or custom SVGs.
import { Button } from '@onlynative/components'
import { ThemeProvider } from '@onlynative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'
export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider>
<View style={{ flex: 1, justifyContent: 'center', padding: 16, gap: 12 }}>
<Button leadingIcon="plus" onPress={() => {}}>Add Item</Button>
<Button trailingIcon="arrow-right" onPress={() => {}}>Continue</Button>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}
Bring your own icon library
Pass any element directly — useful for one-off icons or when you want full control over sizing and color:
import { Button } from '@onlynative/components'
import { Check, ArrowRight } from 'lucide-react-native'
<Button leadingIcon={<Check size={18} color="#fff" />}>Save</Button>
<Button trailingIcon={<ArrowRight size={18} color="#fff" />}>Continue</Button>
Or use a render function to receive the button's resolved icon size and color:
<Button
leadingIcon={({ size, color }) => <Check size={size} color={color} />}
iconSize={20}
contentColor="#fff"
>
Save
</Button>
Disabled
import { Button } from '@onlynative/components'
import { ThemeProvider } from '@onlynative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'
export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', padding: 16 }}>
<Button disabled onPress={() => {}}>Disabled</Button>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}
Props
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
children | string | - | Yes | Text label rendered inside the button. |
variant | enum | filled | No | Visual variant. Controls background, border, and text color. |
leadingIcon | IconSource | - | No | Icon rendered before the label. Accepts a string name (resolved via the theme's `iconResolver`, defaulting to `MaterialCommunityIcons`), a pre-rendered element, or a render function that receives `{ size, color }`. |
trailingIcon | IconSource | - | No | Icon rendered after the label. Accepts a string name (resolved via the theme's `iconResolver`, defaulting to `MaterialCommunityIcons`), a pre-rendered element, or a render function that receives `{ size, color }`. |
iconSize | number | 18 | No | Size of leading and trailing icons in dp. Used when resolving string icon names or invoking the render-function form. Pre-rendered elements are not resized. |
containerColor | string | - | No | Override the container (background) color. State-layer colors (hover, press) are derived automatically. |
contentColor | string | - | No | Override the content (label and icon) color. State-layer colors are derived automatically when no containerColor is set. |
labelStyle | StyleProp<TextStyle> | - | No | Additional style applied to the label text. |
style | StyleProp<ViewStyle> | - | No | Style applied to the root container. Static form only — the function form `(state) => style` is not supported because the component drives its container background through Reanimated. Use `containerColor` / `contentColor` for state-aware styling. |
onKeyDown | (event: { nativeEvent: { key?: string; }; }) => void | - | No | - |