Files
klatab/common/ThemeTypes.tsx

139 lines
4.3 KiB
TypeScript
Raw Normal View History

2024-09-15 14:36:20 +02:00
import React, { useState } from 'react';
2024-09-15 18:35:08 +02:00
import { TouchableOpacity, Text, GestureResponderEvent, ColorValue, Switch, TextInput, View, StyleSheet, Platform } from 'react-native';
2024-09-15 14:36:20 +02:00
import { useColors } from './colors';
import { MaterialCommunityIcons } from '@expo/vector-icons';
type ThemeTextType = {
style?: Object,
children?: any,
numberOfLines?: number,
}
export const ThemeText = ({ style, children, numberOfLines }: ThemeTextType) => {
const colors = useColors();
return (
<Text style={[style, { color: colors.text }]} numberOfLines={numberOfLines}>{children}</Text>
);
};
type ThemeButtonType = {
style?: Object,
children?: React.ReactNode,
onPress?: (event: GestureResponderEvent) => void,
color?: ColorValue,
disabled?: boolean,
}
export const ThemeButton = ({ style, children, onPress, color, disabled }: ThemeButtonType) => {
const colors = useColors();
return (
<TouchableOpacity
style={[
style,
{
backgroundColor: color ? color : colors.primary,
padding: 8,
height: 40,
borderRadius: 5,
opacity: disabled ? 0.5 : 1,
alignItems: 'center',
justifyContent: 'center',
}
]}
onPress={disabled ? undefined : onPress}
disabled={disabled}
>
{children}
</TouchableOpacity>
);
};
type ThemeSwitchType = {
style?: Object,
value?: boolean,
disabled?: boolean,
onValueChange?: (value: boolean) => void | Promise<void>,
}
export const ThemeSwitch = ({ style, value, disabled, onValueChange }: ThemeSwitchType) => {
const colors = useColors();
return (
<Switch
style={style}
trackColor={{
false: colors.backSecondary,
true: colors.backSecondary,
}}
thumbColor={disabled ? colors.textAccent : value ? colors.primary : colors.text}
// @ts-expect-error - Für Web, TS kennt activeThumbColor nicht
activeThumbColor={colors.primary}
onValueChange={onValueChange}
value={value}
disabled={disabled}
/>
);
};
type ThemeTextInputType = {
style?: Object,
value?: string,
disabled?: boolean,
onValueChange?: (value: string) => void | Promise<void>,
secureTextEntry?: boolean,
placeholder?: string,
}
export const ThemeTextInput = ({ style, value, disabled, onValueChange, secureTextEntry, placeholder }: ThemeTextInputType) => {
const colors = useColors();
const [showPassword, setShowPassword] = useState(!secureTextEntry);
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 8,
paddingRight: 14,
paddingLeft: 8,
2024-09-15 18:21:28 +02:00
paddingVertical: 1,
2024-09-19 10:41:30 +02:00
marginVertical: 5,
2024-09-15 14:36:20 +02:00
borderColor: disabled ? colors.textDisabled : colors.text,
borderWidth: 1,
},
input: {
flex: 1,
paddingVertical: 10,
paddingRight: 10,
2024-09-15 18:35:08 +02:00
height: 45, ...(Platform.OS === 'web' ? { outlineStyle: 'none' } : {}),
...(Platform.OS === 'web' ? { outlineStyle: 'none' } : {}),
2024-09-15 14:36:20 +02:00
backgroundColor: colors.backPrimary,
color: disabled ? colors.textDisabled : colors.text,
},
icon: {
marginLeft: 10,
},
});
return (
<View style={styles.container}>
<TextInput
style={styles.input}
editable={!disabled}
value={value}
onChangeText={onValueChange}
placeholder={placeholder}
placeholderTextColor={colors.textAccent}
secureTextEntry={!showPassword}
autoCapitalize='none'
/>
{
secureTextEntry && <MaterialCommunityIcons
name={showPassword ? 'eye-off' : 'eye'}
size={24}
color="#aaa"
style={styles.icon}
onPress={() => setShowPassword(!showPassword)}
/>
}
</View>
);
};