stadtwerke/innungsapp/apps/mobile/components/ui/Button.tsx

71 lines
1.9 KiB
TypeScript

import { Text, TouchableOpacity, ActivityIndicator } from 'react-native'
import { cn } from '../../lib/utils'
interface ButtonProps {
label: string
onPress: () => void
variant?: 'primary' | 'secondary' | 'ghost' | 'destructive' | 'outline'
size?: 'default' | 'sm' | 'lg'
loading?: boolean
disabled?: boolean
className?: string
}
export function Button({
label,
onPress,
variant = 'primary',
size = 'default',
loading,
disabled,
className,
}: ButtonProps) {
const isDisabled = disabled || loading
return (
<TouchableOpacity
onPress={onPress}
disabled={isDisabled}
className={cn(
'flex-row items-center justify-center rounded-xl',
{
'bg-primary shadow-sm': variant === 'primary',
'bg-secondary border border-border': variant === 'secondary',
'bg-transparent': variant === 'ghost',
'bg-destructive': variant === 'destructive',
'bg-background border border-input': variant === 'outline',
'h-10 px-4 py-2': size === 'default',
'h-9 rounded-md px-3': size === 'sm',
'h-11 rounded-md px-8': size === 'lg',
'opacity-50': isDisabled,
},
className
)}
activeOpacity={0.8}
>
{loading ? (
<ActivityIndicator
color={variant === 'primary' || variant === 'destructive' ? 'white' : 'black'}
/>
) : (
<Text
className={cn(
'text-sm font-medium',
{
'text-primary-foreground': variant === 'primary',
'text-secondary-foreground': variant === 'secondary',
'text-primary': variant === 'ghost',
'text-destructive-foreground': variant === 'destructive',
'text-foreground': variant === 'outline',
}
)}
>
{label}
</Text>
)}
</TouchableOpacity>
)
}