Skip to content

Conversation

@alex-page
Copy link
Member

@alex-page alex-page commented Nov 5, 2020

WHY are these changes introduced?

Fixes #3390

WHAT is this pull request doing?

  • Convert collapsible to a functional component
  • Fix janky movement when opening collapsible filters
  • Remove opacity from animation
  • Support nested collapsible elements

How to 🎩

  1. Go to the collapsible example
  2. Go to the filters example and open and close the filters

🎩 checklist

  • Tested on mobile
  • Tested on multiple browsers
  • Tested for accessibility
  • Updated the component's README.md with documentation changes
  • Tophatted documentation changes in the style guide
  • For visual design changes, pinged one of @ HYPD, @ mirualves, @ sarahill, or @ ry5n to update the Polaris UI kit

@alex-page alex-page self-assigned this Nov 5, 2020
@github-actions
Copy link
Contributor

github-actions bot commented Nov 5, 2020

🟡 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)
📄 UNRELEASED.md (total: 0)

Files potentially affected (total: 0)

📄 scripts/build-validate.js (total: 0)

Files potentially affected (total: 0)

🎨 src/components/Collapsible/Collapsible.scss (total: 6)

Files potentially affected (total: 6)

🧩 src/components/Collapsible/Collapsible.tsx (total: 5)

Files potentially affected (total: 5)

📄 src/components/Collapsible/README.md (total: 0)

Files potentially affected (total: 0)

🧩 src/components/Collapsible/tests/Collapsible.test.tsx (total: 0)

Files potentially affected (total: 0)

@alex-page alex-page force-pushed the collapsible-fix branch 2 times, most recently from 681e249 to 378b54c Compare November 5, 2020 23:29
@BPScott
Copy link
Member

BPScott commented Nov 6, 2020

Yay hookification. Not reviewed this but could you update #1995 when it gets merged?

@alex-page alex-page mentioned this pull request Nov 6, 2020
@alex-page alex-page changed the title Collapsible functional component and no jank [Collapsible] functional component and no jank when opening Nov 6, 2020
@alex-page alex-page requested a review from emmaorhun November 6, 2020 18:34
Comment on lines 57 to 63
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]);
Copy link
Member Author

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;
Copy link
Member Author

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
Copy link
Member Author

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.

Copy link
Member

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

Copy link
Member

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 😕

Copy link
Member

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

@alex-page
Copy link
Member Author

@AndrewMusgrave @kyledurand this should be good now.

@Shopify Shopify deleted a comment from kyledurand Nov 13, 2020
@Shopify Shopify deleted a comment from AndrewMusgrave Nov 13, 2020
@kyledurand
Copy link
Member

Maybe the smallest regression. Not sure if it's a blocker https://screenshot.click/screencast_2020-11-13_16-02-48.mp4

Copy link
Member

@kyledurand kyledurand left a 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);
Copy link
Member

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
Copy link
Member

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

@alex-page
Copy link
Member Author

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..

Copy link
Member

@AndrewMusgrave AndrewMusgrave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Recording 2020-11-20 at 11 46 32 AM

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
Copy link
Member

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', () => {
Copy link
Member

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

Copy link
Member Author

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?

Copy link
Member

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.

Copy link
Member

@BPScott BPScott Dec 15, 2020

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>
@johanstromqvist
Copy link
Contributor

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?

@alex-page
Copy link
Member Author

@johanstromqvist made a new issue for this #3682

@johanstromqvist
Copy link
Contributor

johanstromqvist commented Dec 7, 2020

The interruptibility seems wonky when the transition is triggered a second time before it has finished. Only on collapse.
toggle wonk 30

@alex-page alex-page closed this Jan 7, 2021
@alex-page alex-page deleted the collapsible-fix branch January 7, 2021 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Collapsible] Open filters animation is janky

5 participants