Description
//update your dist/components/star.js component with code below...
import React, { useState } from "react";
import { StyleSheet, Animated, TouchableOpacity } from "react-native";
const STAR_IMAGE = require("../images/airbnb-star.png");
const STAR_SELECTED_IMAGE = require("../images/airbnb-star-selected.png");
const STAR_SIZE = 40;
const Star = ({ starImage= STAR_IMAGE,
selectedColor= "#f1c40f",
unSelectedColor= "#BDC3C7",...props}) => {
const [selected, setSelected] = useState(false);
const springValue = new Animated.Value(1);
const spring = () => {
const { position, starSelectedInPosition } = props;
springValue.setValue(1.2);
Animated.spring(springValue, {
toValue: 1,
friction: 2,
tension: 1,
useNativeDriver: true
}).start();
setSelected(!selected);
starSelectedInPosition(position);
};
const { fill, size, isDisabled, starStyle } = props;
const starSource = fill && selectedColor === null ? STAR_SELECTED_IMAGE : starImage;
return (
<Animated.Image source={starSource} style={[
styles.starStyle,
{
tintColor: fill && selectedColor ? selectedColor : unSelectedColor,
width: size || STAR_SIZE,
height: size || STAR_SIZE,
transform: [{ scale: springValue }]
},
starStyle
]}/>
);
};
export default Star;
const styles = StyleSheet.create({
starStyle: {
margin: 3
}
});
//update your src/star.tsx component with code below...
import React, { useState } from "react";
import {
StyleSheet,
Animated,
TouchableOpacity,
StyleProp,
ViewStyle
} from "react-native";
const STAR_IMAGE = require( "../images/airbnb-star.png" );
const STAR_SELECTED_IMAGE = require( "../images/airbnb-star-selected.png" );
const STAR_SIZE = 40;
export type StarProps = {
starImage?: string;
fill?: boolean;
size?: number;
selectedColor?: string;
unSelectedColor?: string;
isDisabled?: boolean;
starStyle?: StyleProp;
position?: number;
starSelectedInPosition?: ( number ) => void;
};
const Star: React.FunctionComponent = ({ starImage= STAR_IMAGE,
selectedColor= "#f1c40f",
unSelectedColor= "#BDC3C7",...props}) => {
const [selected, setSelected] = useState( false );
const springValue = new Animated.Value( 1 );
const spring = () => {
const { position, starSelectedInPosition } = props;
springValue.setValue( 1.2 );
Animated.spring( springValue, {
toValue: 1,
friction: 2,
tension: 1,
useNativeDriver: true
} ).start();
setSelected( !selected );
starSelectedInPosition( position );
};
const {
fill,
size,
isDisabled,
starStyle
} = props;
const starSource =
fill && selectedColor === null ? STAR_SELECTED_IMAGE : starImage;
return (
<Animated.Image
source={starSource}
style={[
styles.starStyle,
{
tintColor: fill && selectedColor ? selectedColor : unSelectedColor,
width: size || STAR_SIZE,
height: size || STAR_SIZE,
transform: [{ scale: springValue }]
},
starStyle
]}
/>
);
};
export default Star;
const styles = StyleSheet.create( {
starStyle: {
margin: 3
}
} );
//update your src/TapRating.tsx component with code below...
import _ from "lodash";
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, View, StyleProp, ViewStyle } from "react-native";
import Star from "./components/Star";
export type TapRatingProps = {
/**
- Total number of ratings to display
- Default is 5
*/
count?: number;
/**
- Labels to show when each value is tapped
- e.g. If the first star is tapped, then value in index 0 will be used as the label
- Default is ['Terrible', 'Bad', 'Okay', 'Good', 'Great']
*/
reviews?: string[];
/**
- Determines if to show the reviews above the rating
- Default is true
*/
showRating?: boolean;
/**
- Color value for review.
- Default is #f1c40f
*/
reviewColor?: string;
/**
- Size value for review.
- Default is 40
*/
reviewSize?: number;
/**
- Initial value for the rating
- Default is 3
*/
defaultRating?: number;
/**
- Style for star container
- Default is none
*/
starContainerStyle?: StyleProp;
/**
- Style for rating container
- Default is none
*/
ratingContainerStyle?: StyleProp;
/**
- Callback method when the user finishes rating. Gives you the final rating value as a whole number
*/
onFinishRating?: ( number ) => void;
/**
- Whether the rating can be modiefied by the user
- Default is false
*/
isDisabled?: boolean;
/**
- Color value for filled stars.
- Default is #004666
*/
selectedColor?: string;
/**
- Size of rating image
- Default is 40
*/
size?: number;
/**
- Pass in a custom base image source
*/
starImage?: string;
};
const TapRating: React.FunctionComponent = ({ defaultRating=3,
reviews= ["Terrible", "Bad", "Okay", "Good", "Great"],
count= 5,
showRating= true,
reviewColor= "rgba(230, 196, 46, 1)",
reviewSize= 25,...props}) => {
const [position, setPosition] = useState(defaultRating );
useEffect( () => {
if ( defaultRating === null || defaultRating === undefined ) {
setPosition( 3 );
} else {
setPosition( defaultRating );
}
}, [defaultRating] );
const renderStars = rating_array => {
return _.map( rating_array, star => {
return star;
} );
};
const starSelectedInPosition = position => {
const { onFinishRating } = props;
if ( typeof onFinishRating === "function" ) {
onFinishRating( position );
}
setPosition( position );
};
const rating_array = [];
const starContainerStyle = [styles.starContainer];
if ( props.starContainerStyle ) {
starContainerStyle.push( props.starContainerStyle );
}
const ratingContainerStyle = [styles.ratingContainer];
if ( props.ratingContainerStyle ) {
ratingContainerStyle.push( props.ratingContainerStyle );
}
_.times( count, index => {
rating_array.push(
<Star
key={index}
position={index + 1}
starSelectedInPosition={value => {
starSelectedInPosition( value );
}}
fill={position >= index + 1}
{...props}
/>
);
} );
return (
{showRating &&
<Text
style={[
styles.reviewText,
{ fontSize: reviewSize, color: reviewColor }
]}
>
{reviews[position - 1]}
}
{renderStars( rating_array )}
);
};
const styles = StyleSheet.create( {
ratingContainer: {
backgroundColor: "transparent",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
},
reviewText: {
fontWeight: "bold",
margin: 10
},
starContainer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center"
}
} );
export default TapRating;
//update your dist/TapRating.js component with code below...
import _ from "lodash";
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, View } from "react-native";
import Star from "./components/Star";
const TapRating = ({ defaultRating=3,
reviews= ["Terrible", "Bad", "Okay", "Good", "Great"],
count= 5,
showRating= true,
reviewColor= "rgba(230, 196, 46, 1)",
reviewSize= 25,...props}) => {
const [position, setPosition] = useState(defaultRating);
useEffect(() => {
if (defaultRating === null || defaultRating === undefined) {
setPosition(3);
}
else {
setPosition(defaultRating);
}
}, [defaultRating]);
const renderStars = rating_array => {
return _.map(rating_array, star => {
return star;
});
};
const starSelectedInPosition = position => {
const { onFinishRating } = props;
if (typeof onFinishRating === "function") {
onFinishRating(position);
}
setPosition(position);
};
const rating_array = [];
const starContainerStyle = [styles.starContainer];
if (props.starContainerStyle) {
starContainerStyle.push(props.starContainerStyle);
}
const ratingContainerStyle = [styles.ratingContainer];
if (props.ratingContainerStyle) {
ratingContainerStyle.push(props.ratingContainerStyle);
}
_.times(count, index => {
rating_array.push(<Star key={index} position={index + 1} starSelectedInPosition={value => {
starSelectedInPosition(value);
}} fill={position >= index + 1} {...props}/>);
});
return (<View style={ratingContainerStyle}>
{showRating &&
<Text style={[
styles.reviewText,
{ fontSize: reviewSize, color: reviewColor }
]}>
{reviews[position - 1]}
</Text>}
<View style={starContainerStyle}>{renderStars(rating_array)}</View>
</View>);
};
const styles = StyleSheet.create({
ratingContainer: {
backgroundColor: "transparent",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
},
reviewText: {
fontWeight: "bold",
margin: 10
},
starContainer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center"
}
});
export default TapRating;