* Extended functionalities
* Added different UIs
This commit is contained in:
90
meal-plan-frontend-mobile/src/components/Button.tsx
Normal file
90
meal-plan-frontend-mobile/src/components/Button.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
type PressableProps,
|
||||
} from 'react-native';
|
||||
import { useAppearance } from '@/src/context/AppearanceContext';
|
||||
|
||||
type Variant = 'primary' | 'secondary' | 'ghost' | 'danger';
|
||||
|
||||
interface ButtonProps extends Omit<PressableProps, 'style'> {
|
||||
title: string;
|
||||
loading?: boolean;
|
||||
variant?: Variant;
|
||||
style?: PressableProps['style'];
|
||||
}
|
||||
|
||||
export function Button({
|
||||
title,
|
||||
loading,
|
||||
variant = 'primary',
|
||||
disabled,
|
||||
style: externalStyle,
|
||||
...rest
|
||||
}: ButtonProps) {
|
||||
const { colors } = useAppearance();
|
||||
const isDisabled = disabled || loading;
|
||||
|
||||
const backgroundColor =
|
||||
variant === 'primary'
|
||||
? colors.brand
|
||||
: variant === 'danger'
|
||||
? colors.danger
|
||||
: variant === 'secondary'
|
||||
? colors.brandLight
|
||||
: 'transparent';
|
||||
|
||||
const textColor =
|
||||
variant === 'primary' || variant === 'danger'
|
||||
? '#ffffff'
|
||||
: variant === 'secondary'
|
||||
? colors.brand
|
||||
: colors.brand;
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
disabled={isDisabled}
|
||||
style={(state) => {
|
||||
const resolvedExternal =
|
||||
typeof externalStyle === 'function' ? externalStyle(state) : externalStyle;
|
||||
return [
|
||||
styles.base,
|
||||
{
|
||||
backgroundColor,
|
||||
borderColor: variant === 'ghost' ? colors.border : backgroundColor,
|
||||
opacity: isDisabled ? 0.6 : state.pressed ? 0.85 : 1,
|
||||
},
|
||||
variant === 'ghost' && styles.ghost,
|
||||
resolvedExternal,
|
||||
];
|
||||
}}
|
||||
{...rest}
|
||||
>
|
||||
{loading ? (
|
||||
<ActivityIndicator color={textColor} />
|
||||
) : (
|
||||
<Text style={[styles.label, { color: textColor }]}>{title}</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
minHeight: 48,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
ghost: {
|
||||
borderWidth: 1,
|
||||
},
|
||||
label: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user