-
Notifications
You must be signed in to change notification settings - Fork 686
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
MiniCart Height Fix #1387
MiniCart Height Fix #1387
Conversation
* Uses window.innerHeight instead of 100vh to declare height of component * This ensures the content will always stay in the viewport
This pull request is automatically deployed with Now. Latest deployment for this branch: https://venia-git-supernova-1071croppedcheckout2.magento-research1.now.sh |
|
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.
One comment, otherwise this looks good!
My only concern is that we are using resize events to update a css property which means repaint. This may cause a resize to stutter. Perhaps this is a good time to try to debounce so that we update the size on the last value after of a bunch of resize events.
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.
So my major concern with introducing hooks such as useWindowSize
is that they'll be used because they're expedient, rather than as an absolute last resort. In this case, it would be more ideal and much faster for CSS to handle the sizing on its own.
Is there literally any other way to set a fixed element to be full height that does respect browser chrome? I can be the person to experiment with that, if necessary.
Totally agree.
Based on the CSS Tricks article the problem is that the mobile browsers have calculated I'm not aware of any property like that in CSS though, so I went with JS |
Great idea but I don't actually know where we'd do that. Here are the relevant bits: const { innerHeight: viewportHeight } = useWindowSize();
const rootStyle = {
'--minicart-height-unit': `${viewportHeight * 0.01}px`
};
// then...
<aside className={rootClass} style={rootStyle}> I don't think we can wrap Where were you thinking? |
We can't debounce the hook but we can debounce the update of const { innerHeight } = useWindowSize();
const [debouncedHeight, setDebouncedHeight] = useState(window.innerHeight);
useEffect(() => {
_.debounce(() => { // obvs we could write our own or use lodash.
setDebouncedHeight(innerHeight)
}, 50);
}, [innerHeight]);
const rootStyle = {
'--minicart-height-unit: `${debouncedHeight * 0.01}px`'
}
return (
<aside className={rootClass} style={rootStyle}>
//...
</aside>
) That's just rough code but the idea applies I think. |
|
PR Updated:
This one was interesting! Turns out timing events (used by Here's some great reading: https://overreacted.io/making-setinterval-declarative-with-react-hooks/. The code is therefore not quite as straightforward as we'd like but I added some comments to mitigate confusion. It works great! |
@@ -32,7 +32,7 @@ export const useRestApi = endpoint => { | |||
receiveError(error.baseMessage); | |||
} | |||
}, | |||
[receiveError, receiveResponse, setLoading] | |||
[endpoint, receiveError, receiveResponse, setLoading] |
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 change has nothing to do with this PR but it failed linting and I couldn't push without 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.
cough --no-verify
cough I mean what? Good job thanks!
// So we use this ref instead to ensure we always have the latest value. | ||
setViewportHeight(innerHeightMutableRef.current); | ||
}, 1000); | ||
const setViewportHeightDebouncedRef = useRef(setViewportHeightDebounced); |
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 didn't add a comment in the code here but just FYI we also had to make the debounced function a ref because otherwise a new debounced function would get created each time through this function and they would ALL fire after the debounce delay.
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.
Can we not just useMemo
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.
Good question - I had that thought too but for some reason tried useRef
first. Since it worked I didn't try useMemo
.
If you think it's better I can switch 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.
Isn't this also going to multiple references to setViewportHeightDebounced
and only invoke one? As in whichever is attached to the ref
last? It just feels overly confusing currently but I can see now how my original example would have queued a bunch of useEffect
callbacks too...
@supernova-at That's a great article from Dan. I would have expected us to debounce things inside Also, I think |
Didn't we talk about this and decide that we didn't want to enforce this? I don't know how much time each additional use of |
I just looked through #1193 and didn't see any discussion of it. The context provider publishes an updated value on each resize event, which causes every consumer to determine whether to re-render. To optimize this, we'd want to debounce in the provider so we were doing less of that determining. (In other words, subscribers don't control the "stream" of updates. Context updates are distributed via push, not pull, and consumers can't conditionally call The only reason not to debounce in the provider is to protect the edge case in which a hypothetical consumer legitimately needs maximum granularity—literally every resize event. I don't anticipate seeing that edge case in our application. |
@jimbo @supernova-at using It also breaks the |
Yes, this is where Edit: Nevermind, I'll take a look at #1449 instead. |
Addressed as part of #1449 |
Description
This PR updates the measurement the MiniCart uses to compute its
height
to usewindow.innerHeight
instead of100vh
as described by https://css-tricks.com/the-trick-to-viewport-units-on-mobile/.As described in the attached issue #1071,
100vh
often doesn't account for browser address bars or other frames.This PR takes advantage of the new useWindowSize hook to update this value even after resize events occur.
Related Issue
Closes #1071 .
Verification Steps
Run the verification steps above on a variety of phones.
How Have YOU Tested this?
yarn test
.Screenshots / Screen Captures (if appropriate):
Before Fix
After Fix
Proposed Labels for Change Type/Package
Checklist: