-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[Collapsible] functional component and no jank when opening #3606
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
9fef20b to
d42b27e
Compare
|
🟡 This pull request modifies 6 files and might impact 6 other files. This is an average splash zone for a change, remember to tophat areas that could be affected. Details:All files potentially affected (total: 6)
📄
|
681e249 to
378b54c
Compare
|
Yay hookification. Not reviewed this but could you update #1995 when it gets merged? |
5aab10e to
3538e5d
Compare
0a5bed9 to
35c04d4
Compare
| useEffect(() => { | ||
| if (open === isOpen) { | ||
| return; | ||
| } | ||
|
|
||
| requestAnimationFrame(() => { | ||
| const heightNode = this.heightNode.current; | ||
| switch (animationState) { | ||
| case 'idle': | ||
| break; | ||
| case 'measuring': | ||
| this.setState({ | ||
| animationState: wasOpen ? 'closingStart' : 'openingStart', | ||
| height: wasOpen && heightNode ? heightNode.scrollHeight : 0, | ||
| }); | ||
| break; | ||
| case 'closingStart': | ||
| this.setState({ | ||
| animationState: 'closing', | ||
| height: 0, | ||
| }); | ||
| break; | ||
| case 'openingStart': | ||
| this.setState({ | ||
| animationState: 'opening', | ||
| height: heightNode ? heightNode.scrollHeight : 0, | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
| setHeight(collapisbleContainer.current.scrollHeight); | ||
| }, [open]); |
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 useEffect measured the component and applies the height. For open this is the only effect ran as it measures and applies, this causes the transition from 0 -> measured height. For closing we do the same thing but then use the second useEffect to transition to 0.
| if (animationState === 'idle' && open) { | ||
| return open ? 'none' : undefined; | ||
| } | ||
| getComputedStyle(collapisbleContainer.current).height; |
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 needed otherwise the rendering engine measures and applies the height then set the new height causing no transition. This causes the rendering engine to apply the 0 height on the next cycle causing the transition to run.
| } | ||
| ``` | ||
|
|
||
| ### Nested collapsible |
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 there a way to exclude examples from the styleguide? This isn't best practice but is important that it works.
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'd need something like <!-- example-for: none --> but I don't think we have one at the moment
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.
Would be great if we could grab context from the admin where nested collapsible are used to provide context on valid use cases. Unfortunately, I can't remember where it's being used, only that is 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.
Add ../src/components/**/*.stories.tsx to https://github.com/Shopify/polaris-react/blob/master/.storybook/main.js#L18
Then create a Collapsible.stories.tsx and dump your storybook stories in there using the standard CSF format
|
@AndrewMusgrave @kyledurand this should be good now. |
6236a7c to
c01feb7
Compare
|
Maybe the smallest regression. Not sure if it's a blocker https://screenshot.click/screencast_2020-11-13_16-02-48.mp4 |
c01feb7 to
ea47fa2
Compare
kyledurand
left a comment
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.
Code looks good 👍
| overflow: hidden; | ||
| will-change: height; | ||
| transition-property: height; | ||
| transition-duration: duration(fast); |
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.
Do we want to use var(--p-duration-1-0-0) here instead?
Edit: nvm looks like we need to use tokens to match some JS below
| } | ||
| ``` | ||
|
|
||
| ### Nested collapsible |
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'd need something like <!-- example-for: none --> but I don't think we have one at the moment
|
Would we ever want it to finish the animation before closing? I think you would want it to respond instantly on click. I could be wrong though.. |
AndrewMusgrave
left a comment
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 animation was acting oddly when opening/closing the collapsible quickly. Sometimes it didn't do anything, other times the animation would jank. It's an edge case so, whatever you think is best. Keep in mind the animation is at 10% speed.
Left a note about rendering children. Some tests in web expect on that - not sure about their implementations though. Just something to keep in mind when releasing this.
| } | ||
| ``` | ||
|
|
||
| ### Nested collapsible |
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.
Would be great if we could grab context from the admin where nested collapsible are used to provide context on valid use cases. Unfortunately, I can't remember where it's being used, only that is it 😕
| expect(collapsible.contains('content')).toBe(false); | ||
| }); | ||
|
|
||
| it('does not render its children when going from open to closed', () => { |
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.
Unfortunately, this is an important test. Some consumer implementations rely on this - I'm sure you're going to see some tests failing in web
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 it necessary to not render or tests will now fail?
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.
Tests will probably fail (unless the code has been refactored 🤞 ) - it might be easier to release a rc and run CI with that branch. I don't think UI will break - but it would be worthwhile checking the failed tests.
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'd like to remind y'all about https://buildkite.com/shopify/polaris-react-system-integration-test which runs a pass of the web CI on arbitary polaris branches.
It runs by default on our master branch, but it'd be trivial to trigger a manual build that points at this branch.
No faffing with RCs needed if you just want to test unit tests.
Co-authored-by: Andrew Musgrave <andrew.musgrave@shopify.com>
|
Looks great!! Thanks for the storyboard link @alex-page. How is duration determined? If the value is fixed, a 500px collapse will be perceived as 10x the speed of a 50px collapse. Dynamic containers benefit from dynamically determined durations. @AndrewMusgrave and I collaborated once to create a dynamic interpolation with normalized speed and clamped min/max values. Could that perhaps be applied? |
|
@johanstromqvist made a new issue for this #3682 |


WHY are these changes introduced?
Fixes #3390
WHAT is this pull request doing?
How to 🎩
🎩 checklist
README.mdwith documentation changes