Skip to content

Commit

Permalink
Merge pull request #275 from lad-tech/242_rating
Browse files Browse the repository at this point in the history
242 rating
  • Loading branch information
Deahrunt authored Aug 16, 2024
2 parents 5d8f063 + 8428f69 commit bb8f691
Show file tree
Hide file tree
Showing 14 changed files with 1,861 additions and 1 deletion.
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],

plugins: [
'react-native-reanimated/plugin',
[
Expand Down
119 changes: 119 additions & 0 deletions docs/docs/components/core/others/Rating.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import ReactPlayer from 'react-player';

Reusable Rating component

## Example

```tsx
import {
createStyles,
IStatusState,
Typography,
useStyles,
View,
} from '@shared/ui';
import Header from '@shared/ui/Header';
import Rating from '@lad-tech/mobydick-core';

export const RatingWidget = () => {
const [styles] = useStyles(stylesFn);

return (
<View>
<Header title={'Rating'} />
<View style={styles.container}>
<Typography>Style</Typography>
<View style={styles.row}>
<Rating
setCurrentRate={setRate}
count={5}
iconSize={25}
iconStyle={styles.rating}
fillColor={IStatusState.red}
currentRate={rate}
/>
</View>
<Typography>Default</Typography>
<View style={styles.row}>
<Rating setCurrentRate={setRate} count={5} currentRate={rate} />
</View>
</View>
</View>
);
};

const stylesFn = createStyles(({spaces}) => ({
container: {
gap: spaces.Space16,
alignItems: 'center',
},
row: {
flexDirection: 'row',
gap: spaces.Space16,
},
rating: {
margin: spaces.Space1,
},
}));


```

## `Props`

### <div class="label required basic">Required</div>**`count`**

| TYPE |
|:-------|
| number |

Amount of elements

### `setCurrentRate`

| TYPE |
|:-------|
| () => void |

Return active element

### `iconSize`

| TYPE |
|:-------|
| number |

Star icon Size

### `fillColor`

| TYPE |
|:-------|
| string |

Color for star elements

### `iconStyle`

| TYPE |
|:-----------------------------------------------------------------|
| [ViewStyle](https://reactnative.dev/docs/view-style-props#props) |

Custom styles for icon container

### `disabled`

| TYPE |
|:-------|
| boolean |

Make changing rating disabled

### `currentRate`

| TYPE |
|:-------|
| number |

Initial rating for component

56 changes: 56 additions & 0 deletions packages/core/src/other/components/Rating/Rating.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {FC} from 'react';
import {View} from 'react-native';

import {createStyles, px} from '../../../styles';
import useStyles from '../../../styles/hooks/useStyles';

import Star from './components/Star';
import {TRating} from './types';

const Rating: FC<TRating> = ({
setCurrentRate,
count,
iconStyle,
iconSize = px(40),
fillColor,
currentRate = 0,
disabled,
}) => {
const [styles] = useStyles(stylesCreate);
const ratingCount = Array(count).fill(0);

const handleRating = (startId: number) => {
if (!setCurrentRate) {
return;
}
if (currentRate === startId) {
setCurrentRate(currentRate + 1);
return;
}
setCurrentRate(startId);
};

const stars = ratingCount.map((_, index) => (
<Star
key={'rating' + index}
filled={index <= currentRate - 1}
starId={index}
setRating={handleRating}
currentSelected={currentRate}
iconStyle={iconStyle}
iconSize={iconSize}
fillColor={fillColor}
disabled={disabled}
/>
));

return <View style={styles.container}>{stars}</View>;
};

const stylesCreate = createStyles(_ => ({
container: {
flexDirection: 'row',
},
}));

export default Rating;
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import {act, fireEvent, render} from '@testing-library/react-native';

import {Rating} from '../index';
import {LABELS} from '../../../constants';

describe('Rating', () => {
test('render rating 0', () => {
const onPress = jest.fn();
const {toJSON} = render(
<Rating count={0} setCurrentRate={onPress} currentRate={0} />,
);
expect(toJSON()).toMatchSnapshot();
});
test('render rating 1', () => {
const onPress = jest.fn();
const {toJSON} = render(
<Rating count={1} setCurrentRate={onPress} currentRate={1} />,
);
expect(toJSON()).toMatchSnapshot();
});
test('render rating 2', () => {
const onPress = jest.fn();
const {toJSON} = render(
<Rating count={2} setCurrentRate={onPress} currentRate={2} />,
);
expect(toJSON()).toMatchSnapshot();
});
test('render rating 3', () => {
const onPress = jest.fn();
const {toJSON} = render(
<Rating count={3} setCurrentRate={onPress} currentRate={3} />,
);
expect(toJSON()).toMatchSnapshot();
});
test('render rating 4', () => {
const onPress = jest.fn();
const {toJSON} = render(
<Rating count={4} setCurrentRate={onPress} currentRate={4} />,
);
expect(toJSON()).toMatchSnapshot();
});
test('render rating 5', () => {
const onPress = jest.fn();
const {toJSON} = render(
<Rating count={5} setCurrentRate={onPress} currentRate={5} />,
);
expect(toJSON()).toMatchSnapshot();
});
test('change rating', () => {
const onPress = jest.fn();
const {toJSON, getByLabelText} = render(
<Rating count={5} setCurrentRate={onPress} currentRate={2} />,
);
const setRatingButton = getByLabelText(`${LABELS.ratingStarButton}4`);

act(() => {
fireEvent.press(setRatingButton);
});

expect(setRatingButton.props.accessibilityState).toHaveProperty(
'disabled',
undefined,
);
expect(onPress).toHaveBeenCalledWith(4);

expect(toJSON()).toMatchSnapshot();
});
test('change rating is disabled', () => {
const onPress = jest.fn();
const {toJSON, getByLabelText} = render(
<Rating
count={5}
setCurrentRate={onPress}
disabled={true}
currentRate={5}
/>,
);
const setRatingButton = getByLabelText(`${LABELS.ratingStarButton}4`);

act(() => {
fireEvent.press(setRatingButton);
});

expect(setRatingButton.props.accessibilityState).toHaveProperty(
'disabled',
true,
);

expect(toJSON()).toMatchSnapshot();
});
});
Loading

0 comments on commit bb8f691

Please sign in to comment.