UNPKG

@ggmdev/react-native-rating-bar

Version:

A React Native component for generating and displaying interactive Tap or Swipe enabled Ratings.

274 lines (216 loc) 26 kB
<h1 align="center"> React Native Rating Bar </h1> A React Native component for generating and displaying interactive Tap or Swipe enabled Ratings supporting custom icons from [vector icons](https://github.com/oblador/react-native-vector-icons) and images. <div align="center"> [![npm](https://img.shields.io/npm/v/@aashu-dubey/react-native-rating-bar?style=flat-square)](https://www.npmjs.com/package/@aashu-dubey/react-native-rating-bar) [![Install Size](https://packagephobia.now.sh/badge?p=@aashu-dubey/react-native-rating-bar)](https://www.npmjs.com/package/@aashu-dubey/react-native-rating-bar) [Installation](#-installation) [Usage](#-usage) [Examples](#-examples) [Demo](./example) </div> ## 🚀 Installation Install the package using yarn or npm: ```sh yarn add @aashu-dubey/react-native-rating-bar ``` Or ```sh npm install --save @aashu-dubey/react-native-rating-bar ``` And you also need to install [`react-native-gesture-handler`](https://github.com/software-mansion/react-native-gesture-handler), as we're using it for Swipe/Tap gestures: ```sh yarn add react-native-gesture-handler ``` then wrap your App's entry point with `GestureHandlerRootView` (see [official doc](https://docs.swmansion.com/react-native-gesture-handler/docs/next/installation#js)) in order for drag to rate feature to work ```JSX export default function App() { return ( <GestureHandlerRootView style={{ flex: 1 }}> {/* content */} </GestureHandlerRootView> ); } ``` For more info see gesture-handler's [official Installation guide](https://docs.swmansion.com/react-native-gesture-handler/docs/installation) ## 💪🏼 Usage ### Props #### RatingBar | prop | default | type | description | | -------------------------------------------------------- | ------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | <span id="tableRateStylesProp">rateStyles</span> | undefined | object ([RateStyles](#ratestyless-object)) | Provide custom styles for View containing whole rating group or single rating item. | | itemCount | 5 | number | Total number of Rating items to display. | | minRating | 0 | number | Minimum rating value allowed. Should be `>= 0` | | maxRating | `itemCount` | number | Miximum rating value allowed. Should be `>= minRating >= 0` | | layoutDirection | device's layout direction | 'ltr' or 'rtl' | Layout Direction to show the ratings on, left-to-right (`ltr`) or right-to-left (`rtl`) | | unratedColor | 'rgba(0, 0, 0, 0.38)' | string (ColorValue) | Color for items that are not rated yet, usually when `index >= rating`. | | <span id="tableAllowHalfRating">allowHalfRating</span> | false | boolean | If `true`, rating will increase/decrease by fraction of `0.5` instead of default `1`. | | <span id="tableDirectionProp">direction</span> | 'horizontal' | 'horizontal' \| 'vertical' \| 'vertical-reverse' | Direction to show the ratings items in | | | | 'horizontal' | shows the rating items horizontally. To see them in reverse horizontally set `layoutDirection="rtl"` | | | | 'vertical' | Shows the rating items vertically, top to bottom. | | | | 'vertical-reverse' | Shows the rating itmes vertically, bottom to top. | | glow | true | boolean | If true, Rating items will glow when being touched or dragged.<br><br>Note:- iOS only | | glowColor | '#FFC107' | string (ColorValue) | Defines color for glow | | glowRadius | 2 | number | Defines the radius of glow | | ignoreGestures | false | boolean | Ignore user gestures to make rating bar view only<br>Alternatively you can use `RatingBarIndicator` component. | | initialRating | 0 | number | Defines the initial rating to be set to the rating bar. | | itemPadding | 0 | number | The amount of space by which to inset each rating item. | | itemSize | 40 | number | Defines width and height of each rating item in the bar. | | tapOnlyMode | false | boolean | If `true`, will disable drag to rate feature and only allow taps to change ratings. | | <span id="tableUpdateOnDragProp">updateOnDrag</span> | false | boolean | Defines whether or not the [`onRatingUpdate`](#tableOnRatingUpdateProp) updates while dragging. | | useSolution | 1 | 1 or 2 (number) | There are two implemented solutions for the drag to rate feature, choose whichever works best for you.<br><br>You won't usually notice any difference, unless ratings are vertical, see [`direction`](#tableDirectionProp) props. | | <span id="tableOnRatingUpdateProp">onRatingUpdate</span> | undefined | function(rating: number) | Return current rating whenever rating is updated.<br><br>[`updateOnDrag`](#tableUpdateOnDragProp) can be used to change the behaviour how the callback reports the update.<br>By Default it only returns update when the touch ends, either when tapping or dragging. | | <span id="tableRatingView">ratingView</span> | undefined | object ([RatingView](#ratingviews-object)) | Properties for rating view that updates with current rating.<br>By default it shows `Rating: {rating} / {itemCount}` | | <span id="tableItemBuilder">itemBuilder<span> | undefined | function(index: number) => JSX.Element | Function to return your custom components to be used as rating items, usually Image or Icon component from [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons).<br>You can either pass single component or different components based on `index` property from param.<br><br>index - Provides Rating bar item's index position as param. | | <span id="tableRatingElement">ratingElement</span> | undefined | object ([RatingElement](#ratingelements-object)) | Define 3 different states of rating.<br>`empty`, `half` and `full`. | ##### [`ratingElement`'s Object](#tableRatingElement) - | key | type | description | | ----- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | empty | JSX.Element | Defines Element to be used as rating bar item when item is unrated. | | half | JSX.Element | Defines Element to be used when as rating bar item when only half portion of item is rated.<br>**Note**:- [allowHalfRating](#tableAllowHalfRating) needs to be set to true | | full | JSX.Element | Defines Element to be used when as rating bar item when item is completely rated. | ##### [`rateStyles`'s Object](#tableRateStylesProp) - | key | type | description | | ------------- | --------------------------------------------------------------- | ---------------------------------------------------- | | container | object (ViewStyle) | Custom styles for View contaning whole rating group. | | starContainer | object (ViewStyle) \| ((index: number) => StyleProp<ViewStyle>) | Custom styles for View contaning Sigle rating item. | ##### [`ratingView`'s Object](#tableRatingView) - | key | type | description | | -------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | showRating | boolean | Whether to show Rating indicator. By default view doesn't show. | | position | 'top' \| 'bottom' | Whether to show indicator on `top` or `bottom` of Rating bar. By default it shows on `top`. | | titleText | string | Custom title that shows at the start, before `{currentRating} / {itemCount}`.<br>Default is `"Rating: "`. | | containerStyle | object (ViewStyle) | Style for main view container. | | titleStyle | object (TextStyle) | Style for text showing before ratings, at the start. | | ratingStyle | object (TextStyle) | Style for text showing current rating. | | totalStyle | object (TextStyle) | Style for text showing total allowed rating. | | custom | ReactElement | Pass custom component replacing the default one, can be emoji, image or text etc.<br>Passing this will make above props irrelevent, except `showRating` and `position`.<br><br>Note:- You have to handle updates based on rating yourself. | > **Note**:- To make the component work you must pass either of `itemBuilder` or `ratingElement` with valid values. #### RatingBarIndicator This is view only alternative to `RatingBar` with no Tap or Swipe capability and From above props **RatingBarIndicator** contains `layoutDirection`, `unratedColor`, `direction`, `itemCount`, `itemPadding`, `itemSize`, `rating` and `itemBuilder` with same specific uses. ### 📲 Examples #### Using RatingBar Component There are few different ways to use Rating Bar component ###### Using [`ratingElement`](#tableRatingElement) prop: <img width="248" alt="image" src="https://user-images.githubusercontent.com/86477859/169906569-f937a04a-0bbc-40b9-ad79-6eaefcb58c0c.png"> ```JSX <RatingBar initialRating={3.5} direction="horizontal" allowHalfRating itemCount={5} itemPadding={4} ratingElement={{ full: ( <Image style={{ width: 30, height: 30, tintColor: '#54D3C2' }} resizeMode="contain" source={require('./assets/heart.png')} /> ), half: ( <Image style={{ width: 30, height: 30, tintColor: '#54D3C2' }} resizeMode="contain" source={require('./assets/heart_half.png')} /> ), empty: ( <Image style={{ width: 30, height: 30, tintColor: '#54D3C2' }} resizeMode="contain" source={require('./assets/heart_border.png')} /> ), }} onRatingUpdate={value => console.log(value)} /> ``` Assets are available [here](./example/src/assets).<br> Or you can use Icon component from [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons): <img width="248" alt="image" src="https://user-images.githubusercontent.com/86477859/169905930-0fbdd3d0-df05-4e87-b328-79f891ec0e7a.png"> ```JSX <RatingBar initialRating={3.5} direction="horizontal" allowHalfRating itemCount={5} itemPadding={4} ratingElement={{ full: <Icon name="star-rate" color="#54D3C2" size={40} />, half: <Icon name="star-half" color="#54D3C2" size={40} />, empty: <Icon name="star-border" color="#54D3C2" size={40} />, }} onRatingUpdate={value => console.log(value)} /> ``` ###### Using [`itemBuilder`](#tableItemBuilder) prop: <img width="248" alt="image" src="https://user-images.githubusercontent.com/86477859/169903719-224b225e-e45b-4dec-b4b8-3b0d4230e709.png"> ```JSX <RatingBar initialRating={2.5} minRating={1} direction="horizontal" allowHalfRating unratedColor="rgba(255, 193, 7, 0.2)" itemCount={5} itemPadding={4} itemSize={40} itemBuilder={() => <Icon name="star" color="#FFC107" size={40} />} onRatingUpdate={value => console.log(value)} /> ``` ###### Based on [`itemBuilder`](#tableItemBuilder) prop's index param: Passing different component in `itemBuilder` based on index param value: <img width="248" alt="image" src="https://user-images.githubusercontent.com/86477859/169907826-2388a362-b5fe-457c-9573-f749c2014c6a.png"> ```JSX <RatingBar initialRating={3} itemCount={5} itemPadding={4} itemBuilder={index => { switch (index) { case 0: return ( <Icon name="sentiment-very-dissatisfied" color="#F44336" size={40} /> ); case 1: return <Icon name="sentiment-dissatisfied" color="#FF5252" size={40} />; case 2: return <Icon name="sentiment-neutral" color="#FFC107" size={40} />; case 3: return <Icon name="sentiment-satisfied" color="#8BC34A" size={40} />; case 4: return ( <Icon name="sentiment-very-satisfied" color="#4CAF50" size={40} /> ); default: return <View />; } }} onRatingUpdate={value => console.log(value)} /> ``` #### Using `RatingBarIndicator` Component <img width="248" alt="image" src="https://user-images.githubusercontent.com/86477859/169963092-a600f105-5d7c-458f-9bb6-862175d5f840.png"> ```JSX <RatingBarIndicator rating={3.37} itemBuilder={() => <Icon name="star" color="#FFC107" />} itemCount={5} itemSize={50} unratedColor="rgba(255, 193, 7, 0.2)" direction="horizontal" // Or "vertical", "vertical-reverse" /> ``` #### Vertical Mode | <img width="154" alt="image" src="https://user-images.githubusercontent.com/86477859/169964817-4cfbb2d6-1c15-4769-8099-23cd450a0d8f.png"> | <img width="154" alt="image" src="https://user-images.githubusercontent.com/86477859/169964900-1e8d3a8e-b3fd-45ac-9d2d-3a80ce219205.png"> | | :---------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | | <b>vertical</b> | <b>vertical-reverse</b> | ## 🚧 Issue You may notice, especially in Android drag to rate is a little slower, this is a dev only problem, if you run your build on release mode or even debug with JS dev mode disabled it will run way way faster, something related to [this](https://github.com/facebook/hermes/issues/48). That being said, I'm trying to fix this. ## 🌻 Motivation This project was initially started as I needed to implement a rating component for [Hotel Booking UI](https://github.com/Aashu-Dubey/React-Native-UI-Templates/blob/main/react_native_UI_Templates/res/hotel/hotel_booking.png) template in my other open source project for learning [React-Native-UI-Templates](https://github.com/Aashu-Dubey/React-Native-UI-Templates), and failing to find a proper solution that works same as the original Project in Flutter, I decided to replicate the Rating library used in the Flutter project.<br> So this package is initially inspired from Flutter package [flutter_rating_bar](https://github.com/sarbagyastha/flutter_rating_bar) (including the demo 😅) with some extra added functionalities. ## 🙋‍♀️ Contributing See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. ## 📜 License MIT