Files
streamyfin/components/Badge.tsx

135 lines
3.0 KiB
TypeScript

import { BlurView } from "expo-blur";
import { Platform, StyleSheet, View, type ViewProps } from "react-native";
import { GlassEffectView } from "react-native-glass-effect-view";
import { useScaledTVTypography } from "@/constants/TVTypography";
import { Text } from "./common/Text";
interface Props extends ViewProps {
text?: string | number | null;
variant?: "gray" | "purple";
iconLeft?: React.ReactNode;
}
export const Badge: React.FC<Props> = ({
iconLeft,
text,
variant = "purple",
...props
}) => {
const typography = useScaledTVTypography();
const content = (
<View style={styles.content}>
{iconLeft && <View style={styles.iconLeft}>{iconLeft}</View>}
<Text
className={`
text-xs
${variant === "purple" && "text-white"}
`}
>
{text}
</Text>
</View>
);
if (Platform.OS === "ios" && !Platform.isTV) {
return (
<View {...props} style={[styles.container, props.style]}>
<GlassEffectView style={{ borderRadius: 100 }}>
{content}
</GlassEffectView>
</View>
);
}
// On TV, use BlurView for consistent styling
if (Platform.isTV) {
return (
<BlurView
intensity={10}
tint='light'
style={{
borderRadius: 8,
overflow: "hidden",
alignSelf: "flex-start",
flexShrink: 1,
flexGrow: 0,
}}
>
<View
style={[
{
paddingVertical: 10,
paddingHorizontal: 16,
flexDirection: "row",
alignItems: "center",
backgroundColor: "rgba(0,0,0,0.3)",
},
props.style,
]}
>
{iconLeft && <View style={{ marginRight: 8 }}>{iconLeft}</View>}
<Text
style={{
fontSize: typography.callout,
color: "#E5E7EB",
}}
>
{text}
</Text>
</View>
</BlurView>
);
}
return (
<View
{...props}
style={[
{
borderRadius: 4,
padding: 4,
paddingHorizontal: 6,
flexShrink: 1,
flexGrow: 0,
alignSelf: "flex-start",
flexDirection: "row",
alignItems: "center",
backgroundColor: variant === "purple" ? "#9333ea" : "#262626",
},
props.style,
]}
>
{iconLeft && <View style={{ marginRight: 4 }}>{iconLeft}</View>}
<Text
style={{
fontSize: 12,
color: "#fff",
}}
>
{text}
</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
overflow: "hidden",
alignSelf: "flex-start",
flexShrink: 1,
flexGrow: 0,
},
content: {
flexDirection: "row",
alignItems: "center",
paddingHorizontal: 10,
paddingVertical: 4,
borderRadius: 50,
backgroundColor: "transparent",
},
iconLeft: {
marginRight: 4,
},
});