import * as React from "react"; import { View, StyleSheet, StyleProp, ViewStyle, Pressable, } from "react-native"; import { withTheme } from "@draftbit/theme"; import type { ReadTheme } from "@draftbit/theme"; import type { IconSlot } from "../interfaces/Icon"; type Props = { starSize?: number; maxStars?: number; rating?: number; defaultValue?: number; isEditable?: boolean; activeColor?: string; inactiveColor?: string; theme: ReadTheme; style?: StyleProp; onPress?: (newValue: number) => void; } & IconSlot; const StarRating: React.FC> = ({ Icon, starSize = 16, maxStars = 5, rating = 0, defaultValue, isEditable = false, activeColor, inactiveColor, style, onPress, ...rest }) => { const [localRating, setLocalRating] = React.useState( rating || defaultValue || 0 ); React.useEffect(() => { if (rating != null) { setLocalRating(rating); } }, [rating]); React.useEffect(() => { if (defaultValue != null) { setLocalRating(defaultValue); } }, [defaultValue]); const ratingHandler = React.useCallback( (r: number) => { setLocalRating(r); !!onPress && onPress(r); }, [onPress] ); const ratingRounded = Math.round(localRating * 2) / 2; return ( {[...Array(maxStars)].map((_, i) => ( i ? activeColor : inactiveColor} /> {isEditable && ( ratingHandler(i + 0.5)} /> ratingHandler(i + 1)} /> )} ))} ); }; const styles = StyleSheet.create({ container: { flexDirection: "row", alignItems: "center", }, touchContainer: { display: "flex", flexDirection: "row", position: "absolute", top: 0, right: 0, left: 0, bottom: 0, zIndex: 1, }, pressable: { flex: 1, height: "100%", width: "50%", }, }); export default withTheme(StarRating);