Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Added support for ordering rating summary and fixed minor issues #17

Merged
merged 2 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Props that can be passed to the component are listed below:
</tr>
<tr>
<td><code><b>ratingAverageIconProps?:</b> object</code></td>
<td>An object defining the fill color and background color for customizing the appearance of star icon in the average rating section.</td>
<td>An object defining the fill color ( fillColor?: string ) and background color ( bgColor?: string ) for customizing the appearance of star icon in the average rating section.</td>
<td><code>undefined</code></td>
</tr>
<tr>
Expand All @@ -189,6 +189,11 @@ Props that can be passed to the component are listed below:
<td>A string used to customize the text accompanying the star rating average which provides additional information about the total number of reviews.</td>
<td><code>'reviews'</code></td>
</tr>
<tr>
<td><code><b>order?:</b> 'ORIGINAL' | 'REVERSE'</code></td>
<td>The order prop dictates the summary section's display order. Possible values are: 'ORIGINAL' or 'REVERSE'. For numeric ratingIds, it sorts in ascending (ORIGINAL) or descending (REVERSE) order. For string based ratingIds, it reflects the original/reversed order of keys in the ratings prop.</td>
<td><code>'REVERSE'</code></td>
</tr>
</tbody>
</table>

Expand Down Expand Up @@ -247,22 +252,22 @@ import RatingSummary from '@keyvaluesystems/react-star-rating-summary';
function App() {

const countColors = {
1: 'red',
2: 'yellow',
3: 'blue',
4: 'orange',
5: 'white'
1: 'red',
2: 'yellow',
3: 'blue',
4: 'orange',
5: 'white'
};

return (
<RatingSummary
ratings={{
1: 100,
2: 200,
3: 300,
4: 400,
5: 500
}}
1: 100,
2: 200,
3: 300,
4: 400,
5: 500
}}
styles={{
Average: { color: 'purple' },
AverageStarIcon: {
Expand Down
1 change: 0 additions & 1 deletion src/assets/star-grey.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export enum Elements {
Label = 'Label',
LabelStarIcon = 'LabelStarIcon'
}

export enum ORDER {
ORIGINAL = 'ORIGINAL',
REVERSE = 'REVERSE'
}

export const INTERNATIONAL_NUMBER_SYSTEM_REGEX = /\B(?=(\d{3})+(?!\d))/g;

export const DEFAULT_BAR_COLORS = {
Expand Down
7 changes: 1 addition & 6 deletions src/rating-average/star/Star.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ const Star: FC<StarProp> = (props) => {
const { fillColor, bgColor, colorFilledFraction, id } = props;

return (
<svg
width="100%"
height="auto"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
>
<svg width="100%" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id={id} shapeRendering="crispEdges">
<stop offset={colorFilledFraction} stopColor={fillColor} />
Expand Down
56 changes: 30 additions & 26 deletions src/rating-summary/RatingSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { FC } from 'react';
import { ISummaryProp, RatingRanks } from './types';
import RatingLabel from '../rating-label';
import RatingDistributionItem from '../rating-distribution-item';
import { Elements, GenericElements } from '../constants';
import { Elements, GenericElements, ORDER } from '../constants';
import { getStyles, getTotalRatingCount } from '../utils';
import RatingAverage from '../rating-average';
import classes from './styles.module.scss';
Expand All @@ -23,7 +23,8 @@ const RatingSummary: FC<ISummaryProp> = (props) => {
averageRatingPrecision = 1,
ratingAverageIconProps = {},
thousandsSeparator,
ratingAverageSubText = 'reviews'
ratingAverageSubText = 'reviews',
order = ORDER.REVERSE
} = props;

const getRatingRanks = (): RatingRanks => {
Expand All @@ -39,6 +40,11 @@ const RatingSummary: FC<ISummaryProp> = (props) => {

const ranks: RatingRanks = getRatingRanks();

const ratingKeys =
order === ORDER.REVERSE
? Object.keys(ratings).reverse()
: Object.keys(ratings);

return (
<div className={classes.container} style={styles[GenericElements.Root]}>
{showAverageRating && (
Expand All @@ -58,30 +64,28 @@ const RatingSummary: FC<ISummaryProp> = (props) => {
style={styles[GenericElements.SummaryContainer]}
id="ratings-container"
>
{Object.keys(ratings)
.reverse()
.map((ratingId) => (
<div
key={ratingId}
className={classes.ratingWrapper}
style={getStyles(styles, Elements.SummaryItemContainer, ratingId)}
>
{(renderLabel && <>{renderLabel(ratingId)}</>) || (
<RatingLabel ratingId={ratingId} styles={styles} />
)}
<RatingDistributionItem
currentRatingId={ratingId}
currentRatingValue={ratings[ratingId]}
totalRatingCount={getTotalRatingCount(ratings)}
showCount={showCount}
showAnimation={showAnimation}
styles={styles}
barColors={barColors}
onBarClick={onBarClick}
thousandsSeparator={thousandsSeparator}
/>
</div>
))}
{ratingKeys.map((ratingId) => (
<div
key={ratingId}
className={classes.ratingWrapper}
style={getStyles(styles, Elements.SummaryItemContainer, ratingId)}
>
{(renderLabel && <>{renderLabel(ratingId)}</>) || (
<RatingLabel ratingId={ratingId} styles={styles} />
)}
<RatingDistributionItem
currentRatingId={ratingId}
currentRatingValue={ratings[ratingId]}
totalRatingCount={getTotalRatingCount(ratings)}
showCount={showCount}
showAnimation={showAnimation}
styles={styles}
barColors={barColors}
onBarClick={onBarClick}
thousandsSeparator={thousandsSeparator}
/>
</div>
))}
</div>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion src/rating-summary/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ReactElement } from 'react';

import { Elements, GenericElements } from '../constants';
import { Elements, GenericElements, ORDER } from '../constants';

export type StyleObjectType = React.CSSProperties;

Expand Down Expand Up @@ -48,4 +48,5 @@ export type ISummaryProp = {
ratingAverageIconProps?: RatingAverageIconProps;
thousandsSeparator?: string;
ratingAverageSubText?: string;
order?: ORDER;
};
10 changes: 10 additions & 0 deletions src/stories/RatingSummary.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export default {
fillColor: '#919191',
bgColor: '#F2F2F2'
}
},
order: {
control: { type: 'radio' },
options: ['ORIGINAL', 'REVERSE']
}
}
} as ComponentMeta<typeof Component>;
Expand Down Expand Up @@ -205,3 +209,9 @@ VariantWithCustomRanks.args = {
},
ratingAverageSubText: 'total'
};

export const VariantWithOriginalOrder = Template.bind({});
VariantWithOriginalOrder.args = {
...VariantWithStringBasedRatings.args,
order: 'ORIGINAL'
};
6 changes: 5 additions & 1 deletion src/tests/ratingSummary.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import { render, queryByAttribute } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

import RatingSummary from '../rating-summary';
import { IRatings } from '../rating-summary/types';
import { ORDER } from '../constants';

const getById = queryByAttribute.bind(null, 'id');
describe('RatingSummary', () => {
Expand All @@ -15,7 +17,9 @@ describe('RatingSummary', () => {
};
const total = 575;
it('should render the RatingSummary component', () => {
const { container } = render(<RatingSummary ratings={ratings} />);
const { container } = render(
<RatingSummary ratings={ratings} order={ORDER.ORIGINAL} />
);
const ratingSummaryComponent = getById(container, 'ratings-container');
if (!ratingSummaryComponent) throw Error('No Component present');
});
Expand Down
Loading