-
Notifications
You must be signed in to change notification settings - Fork 195
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(rating): address inconsistent hover behavior #3196
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 82cbeeb The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🚀 Deployed on https://pr-3196--spectrum-css.netlify.app |
File metricsSummaryTotal size: 4.30 MB* Table reports on changes to a package's main file. Other changes can be found in the collapsed Details section below.
Detailsrating
* Results are not gzipped or minified. * An ASCII character in UTF-8 is 8 bits or 1 byte. |
3a4f7ca
to
878ed6c
Compare
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.
When testing, I'm seeing a couple issues:
-
The focus ring should not be appearing on click. The existing
is-focused
is actually just for keyboard focus.Really
.is-focused
should be named.is-keyboardFocused
or even better the selector could be&:has(:focus-visible), &.is-keyboardFocused { ... }
, though I'm not sure we want to do that sort of renaming now? If we're already doing a breaking change, we could, though I'm hesitant to increase the scope of this work.I'd definitely reword the docs sentence that says "When the rating receives focus" to "When the rating receives keyboard focus".
-
Clicking on any of the ratings on the Docs page doesn't update something with the current value; the underline will show in the wrong place.
-
The
is-hovered
class gets leftover on elements when Rating is no longer being hovered
components/rating/index.css
Outdated
@@ -168,6 +157,16 @@ | |||
display: block; | |||
} | |||
} | |||
|
|||
&.is-hovered { |
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 requirement for this class and how it should be used needs to be included in usage notes within the documentation. Within the PR description would be helpful as well.
As I am understanding it, previously CSS would set all stars filled on hover of the whole component, and then all stars following the hovered star unfilled using the subsequent-sibling combinator (~
). And that will not work when you hover on the gap between items. And with this change you are looking at having a class that the implementation will apply to the hovered star as well as all previous stars? And those classes should stay until hover or focus leaves the component?
I think that could work. Perhaps this class should be something like .is-hoverSelection
? It seems odd to also have is-hovered
on elements that aren't actually hovered. It might also be worth adding the hover pseudo to the selector :hover, &.is-hoverSelection
.
Another option would be using padding instead of gaps, but I don't know if we want to go that route or not.
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.
Got it! I'll add this to the PR description and will look for the usage notes.
That is an accurate description of the issue — I first approached it using CSS but there's an issue with one of our postcss plugins when trying to style one of the stars based on the hover state of the next: saulhardman/postcss-hover-media-feature#35.
I've updated the selector to use :hover, .is-hoverSelection
. The latter is now removed from all child icons on mouseout
of the parent component.
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.
I've updated is-focused
to be is-keyboardFocused
and changed the state in the stories and templates too.
Clicking on any of the ratings on the Docs page doesn't update something with the current value; the underline will show in the wrong place.
I need to look at this a bit more — it doesn't look like the instance in the docs is making it into the @change
handler that updates this (as it works in the stories for the component):
@change=${function(e) {
const rating = e.target.closest(`.${rootClass}`);
if (!rating) return;
const input = rating.closest(`.${rootClass}-input`);
if (!input) return;
if (!isReadOnly && !isDisabled) {
updateArgs({ value: parseInt(input.value, 10) });
}
}}
8470a26
to
610396a
Compare
6147f91
to
f0255e7
Compare
01f2393
to
634d93d
Compare
9ea3c8e
to
ff42950
Compare
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.
I had a brainstorm while I was reviewing this- we could totally put a little disclaimer on the docs page that the rating components "have limited functionality" or "are not fully functional." Then add a "visit the default story for extended functionality" line or something (with a link to the default story page). What do you think about that? I did that with breadcrumbs actually.
@@ -59,7 +61,7 @@ export default { | |||
}; | |||
|
|||
/** | |||
* A initial value of three is used for the following examples, to demonstrate both active and inactive stars. | |||
* An initial value of three is used for the following examples, to demonstrate both active and inactive stars. |
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.
👏 love a typo fix
@@ -18,8 +18,8 @@ export const RatingGroup = Variants({ | |||
isDisabled: true, | |||
}, | |||
{ | |||
testHeading: "Focused", | |||
isFocused: true, | |||
testHeading: "Keyboard focused", |
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.
Just personal preference here- I'd probably hyphenate this. I'm not sure we have a very strong convention for that either way though, so you can disregard if you want.
/* All stars following the hovered star */ | ||
&:hover ~ .spectrum-Rating-icon { | ||
&:hover, | ||
&.is-hoverSelection { |
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.
Is the intention here that this new .is-hoverSelection
class (which gets added in your JS) sort of replaces this sibling combinator ~
? Or no- this change removes the functionality of hovering over any part of the component and all stars fill?
Why does that change reverse the display
values for the active & inactive stars?
}); | ||
|
||
icon.addEventListener("mouseleave", function(event) { | ||
if (!rating.contains(event.relatedTarget)) { |
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.
I'm not sure I've seen relatedTarget
. Could you explain what this if
is checking for? (I'll have to look it up!)
if (index <= hoverIndex || | ||
(index <= selectedIndex && hoverIndex === -1) | ||
) { | ||
icon.classList.add("is-hoverSelection"); | ||
activeStar.style.display = "block"; | ||
inactiveStar.style.display = "none"; | ||
} |
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.
Aren't hoverIndex
and selectedIndex
set to -1, which means that index
will always be greater than them initially? It's working (don't get me wrong), but how is that working? I'm totally missing something here 🤦♀️
/* When the entire component is hovered, show all solid icons */ | ||
&:hover { | ||
.spectrum-Rating-starActive { | ||
display: block; | ||
} | ||
|
||
.spectrum-Rating-starInactive { | ||
display: none; | ||
} | ||
} |
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.
Did we need to double check with design or anybody else that we can completely remove this? I agree with the removal, but it certainly seems like it was intentional. Also because I'm nosy I'd love to get the context around that decision hahahaha
@@ -0,0 +1,8 @@ | |||
--- | |||
"@spectrum-css/rating": major |
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.
@pfulton I'm a bit anxious about introducing such a large bump to an S1 component with the current progress on foundations work. What do you think? Should we try to scale back the scope of this work, hold it until after foundations, or move forward as-is?
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.
I agree on the anxiousness around S1/S2 timing. On the plus side, though, this is a component that is not currently available in SWC, so the downstream impact of a big change might not be as large as it could have been if it was already implemented there. That said: it's still a major, and we want to respect what that means for all potential consumers.
I think we should pause on this one for now until after Foundations goes in. After that, we can work through rebasing this one and getting it merged in. The scope of changes are only within this particular component, so hopefully any potential conflicts won't be too terrible to resolve when the time comes.
ff42950
to
bea4f25
Compare
10a21fa
to
f3e2a45
Compare
Marking this as |
f3e2a45
to
4b70482
Compare
Co-authored-by: Marissa Huysentruyt <[email protected]>
Co-authored-by: Marissa Huysentruyt <[email protected]>
4b70482
to
82cbeeb
Compare
Description
Provides more granular control over the hover behavior of child stars within the rating component to prevent hovering in space adjacent to the component from highlighting all stars.
CSS-735
How and where has this been tested?
Verified in local Storybook story for rating component.
Validation steps
Regression testing
Validate:
Screenshots
To-do list