Button
Pressable with the full set of shadcn variants and sizes.
Installation
Terminal
npx magic-native-ui@latest add buttonUsage
The example running in the preview above. Imports use the default aliases from components.json.
button-demo.tsx
import { View } from 'react-native'
import { Button } from '@/components/ui/button'
import { Text } from '@/components/ui/text'
export function ButtonDemo() {
return (
<View className="w-full gap-3">
<Button>
<Text>Default</Text>
</Button>
<Button variant="secondary">
<Text>Secondary</Text>
</Button>
<Button variant="destructive">
<Text>Destructive</Text>
</Button>
<Button variant="outline">
<Text>Outline</Text>
</Button>
<Button variant="ghost">
<Text>Ghost</Text>
</Button>
<Button variant="link">
<Text>Link</Text>
</Button>
<View className="flex-row items-center gap-2">
<Button size="sm">
<Text>Small</Text>
</Button>
<Button size="lg">
<Text>Large</Text>
</Button>
</View>
<Button disabled>
<Text>Disabled</Text>
</Button>
</View>
)
}Component source
What the CLI copies into your project. Once it is there, the code is yours to edit.
registry/ui/button.tsx
import * as React from 'react'
import { Pressable } from 'react-native'
import { cva, type VariantProps } from 'class-variance-authority'
import { TextClassContext } from '@/registry/ui/text'
import { cn } from '@/registry/lib/utils'
const buttonVariants = cva(
'flex-row items-center justify-center gap-2 rounded-md disabled:opacity-50',
{
variants: {
variant: {
default: 'bg-primary active:opacity-90',
destructive: 'bg-destructive active:opacity-90',
outline: 'border border-input bg-background active:bg-accent',
secondary: 'bg-secondary active:opacity-80',
ghost: 'active:bg-accent',
link: '',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
)
/**
* Text classes are handed to nested `<Text>` through `TextClassContext` rather
* than inherited, because React Native has no CSS inheritance.
*/
const buttonTextVariants = cva('text-sm font-medium', {
variants: {
variant: {
default: 'text-primary-foreground',
destructive: 'text-destructive-foreground',
outline: 'text-foreground',
secondary: 'text-secondary-foreground',
ghost: 'text-foreground',
link: 'text-primary underline',
},
size: {
default: '',
sm: '',
lg: 'text-base',
icon: '',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
})
type ButtonProps = React.ComponentProps<typeof Pressable> & VariantProps<typeof buttonVariants>
function Button({ className, variant, size, ...props }: ButtonProps) {
return (
<TextClassContext.Provider value={buttonTextVariants({ variant, size })}>
<Pressable
role="button"
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
</TextClassContext.Provider>
)
}
export { Button, buttonTextVariants, buttonVariants }
export type { ButtonProps }