-
Notifications
You must be signed in to change notification settings - Fork 203
[Clov-406][BpkRating] Improve BpkRating component to allow its subtitle text truncation in edge cases #3872
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
Conversation
|
||
expect(screen.getByText('Excellent')).toBeVisible() | ||
expect(screen.getByText('672 reviews')).toBeVisible() | ||
expect(screen.getByLabelText('4.6 Excellent 672 reviews')).toBeInTheDocument(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we do not recommend using toMatchSnapshot
, changed it to use jest expect
element.
const defaultProps = { | ||
ratingScale: RATING_SCALES.zeroToFive, | ||
size: RATING_SIZES.base, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added default props for testing.
expect(asFragment()).toMatchSnapshot(); | ||
|
||
expect(screen.getByLabelText('6.7 Average might recommend')).toHaveClass('bpk-rating'); | ||
expect(screen.getByText('/5')).toHaveClass('bpk-rating__scale'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the ratingScale: RATING_SCALES.zeroToFive
, it displays the max value.
expect(screen.getByText('Low')).toBeVisible(); | ||
expect(screen.getByText('Bad option')).toBeVisible(); | ||
expect(screen.getByLabelText('-1.3 Low bad option')).toBeInTheDocument(); | ||
expect(screen.getByText('/5')).toHaveClass('bpk-rating__scale'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the ratingScale: RATING_SCALES.zeroToFive
, it displays the max value.
expect(screen.getByText('Smashing')).toBeVisible(); | ||
expect(screen.getByText('Doubleplusgood')).toBeVisible(); | ||
expect(screen.getByLabelText('10 Super, smashing, great')).toBeInTheDocument(); | ||
expect(screen.getByText('/5')).toHaveClass('bpk-rating__scale'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the ratingScale: RATING_SCALES.zeroToFive
, it displays the max value 5
.
Visit https://backpack.github.io/storybook-prs/3872 to see this build running in a browser. |
@@ -34,6 +34,7 @@ | |||
|
|||
&__text-wrapper { | |||
display: flex; | |||
min-width: 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -61,6 +62,12 @@ | |||
} | |||
|
|||
&__subtitle { | |||
min-width: 0; | |||
max-width: 100%; | |||
flex: 1 1 auto; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The __subtitle
is the second flex item in the flex container text-wrapper
.
The flex: 1 1 auto;
is to occupy the remaining space, can be reduced, with three sets of triggering ellipsis.
- When
flex-direction: row;
intext-wrapper
min-width:0
-> to make its min-width 0, not use the defaultmin-width: auto
- When
flex-direction: column;
intext-wrapper
max-width: 100%;
-> As flex direction is changed, they now take care of the height, not the width we want to truncate. So we can add a max-content to the container horizontally
See the related CSS spec https://www.w3.org/TR/css-flexbox-1/#min-size-auto
color: tokens.$bpk-text-secondary-day; | ||
text-overflow: ellipsis; | ||
white-space: nowrap; | ||
overflow: hidden; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 sets of triggering text ellipsis.
showScale: true, | ||
title: null, | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the propTypes
and defaultProps
and use TS type definition solution.
Visit https://backpack.github.io/storybook-prs/3872 to see this build running in a browser. |
The Percy failure https://percy.io/09e69e44/web/backpack/builds/41384044?utm_campaign=09e69e44&utm_content=backpack&utm_source=github_status_public came from the flaky test. A slight change that does not involve visuals. |
A stupid question: |
Yes. Good catch! I made a mistake. Corrected it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR improves the BpkRating
component by enabling subtitle text truncation in constrained containers and refactors the code and tests to modern patterns.
- Adds CSS rules to truncate the subtitle with an ellipsis when there's insufficient width.
- Refactors
BpkRating
to use inline default props, removesprop-types
, and adds a catch-all type for extra props. - Updates tests to use
@testing-library/react
’sscreen
queries and removes legacy snapshots.
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
packages/bpk-component-rating/src/accessibility-test.tsx | Introduces defaultProps and updates accessibility test render |
packages/bpk-component-rating/src/BpkRating.tsx | Removes PropTypes , adds inline defaults and rest index signature |
packages/bpk-component-rating/src/BpkRating.module.scss | Adds min-width: 0 and ellipsis styles for subtitle truncation |
packages/bpk-component-rating/src/BpkRating-test.tsx | Replaces snapshots with screen -based assertions |
packages/bpk-component-rating/src/snapshots/* | Deletes outdated snapshot file |
it('should not have programmatically-detectable accessibility issues', async () => { | ||
const { container } = render( | ||
<BpkRating | ||
{...defaultProps} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The accessibility test render is missing the required value
prop on <BpkRating>
, which may lead to runtime errors or unexpected output. Add a value
prop (e.g., value={3.6}
) to the rendered component.
Copilot uses AI. Check for mistakes.
ariaLabel="4.9 Awesome It is a fantanstic place" | ||
title="Awesome" | ||
subtitle="It is a fantanstic place" | ||
value={4.9} | ||
showScale={false} | ||
/>, | ||
); | ||
expect(asFragment()).toMatchSnapshot(); | ||
|
||
expect(screen.queryByText('4.9')).not.toHaveClass('bpk-rating__scale'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assertion checks the class on the numeric value element rather than verifying the absence of the scale element. To confirm the scale is not rendered, use something like expect(screen.queryByText('/5')).toBeNull()
.
expect(screen.queryByText('4.9')).not.toHaveClass('bpk-rating__scale'); | |
expect(screen.queryByText('/5')).toBeNull(); |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a special case as it will display 4.9
because of the ratingScale: RATING_SCALES.zeroToFive
. The bpk-rating__scale
is for the case when showScale=true
@@ -55,20 +54,20 @@ type Props = { | |||
subtitle?: string, | |||
title?: string | ReactNode, | |||
value: string | number, | |||
[rest: string]: any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The index signature [rest: string]: any
is very permissive and can hide invalid props. Consider extending React.HTMLAttributes<HTMLDivElement>
(or the appropriate element interface) to provide stronger typing for spread props.
[rest: string]: any |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it won't trigger TS check. The reason why I added is beacuse it is used in the below code.
<div className={classNames} aria-label={ariaLabel} role="figure" {...rest}> |
And also referred to the similar code written.
[rest: string]: any; |
<span className={titleStyles}> | ||
<BpkText | ||
textStyle={titleTextSize} | ||
tagName="span" | ||
aria-hidden="true" | ||
> | ||
{title} | ||
</BpkText> | ||
</span> | ||
)} | ||
|
||
{subtitle && ( | ||
{subtitle && (<span className={subtitleStyles}> | ||
<BpkText | ||
textStyle={subtitleTextSize} | ||
tagName="span" | ||
aria-hidden="true" | ||
> | ||
<span className={subtitleStyles}>{subtitle}</span> | ||
{subtitle} | ||
</BpkText> | ||
</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The extra wrapper <span>
around <BpkText>
adds redundant markup. If BpkText
supports a className
or wrapperClassName
prop, apply titleStyles
directly to it to simplify the DOM structure.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not expect to make obvious changes to the DOM structure at this time. I don't know why it's designed as a nested SPAN here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add storybooks for the truncated case?
Hi @GCpigsic No strong need to add new case for that. Because we can see that in the current storybook use case if you click this link https://backpack.github.io/storybook-prs/3872/?path=/story/bpk-component-rating--visual-test-with-zoom&globals=viewport:mobile1. |
Visit https://backpack.github.io/storybook-prs/3872 to see this build running in a browser. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
We have received feedback that in real production,

BpkRating
may not display all subtitle text content when the component is placed in a width-limited container.Ideally, BpkRating only has 1~2 words in the subtitle. But it could be text overflow in a long language.
This PR is to improve this question. The solution is to make its subtitle truncated when the container width is not enough to display all the content. One condition is not to limit the width of its own component.
Remember to include the following changes:
[Clover-123][BpkButton] Updating the colour
README.md
(If you have created a new component)README.md