-
Notifications
You must be signed in to change notification settings - Fork 392
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
Make arrow panels more versatile. #4692
base: main
Are you sure you want to change the base?
Conversation
This PR implements some changes to the arrow panel code which make arrow panels usable for the dropped functions panel in the call tree settings. With the previous implementation, I encountered these issues: - When the source view was open, the panel would be clipped to the call tree bounds and could not overlap the source view. The overflow:auto clip from the splitter view was applying to the panel. - With a narrow viewport or an unusually positioned anchor element, the panel would sometimes be positioned partially offscreen. - It was tricky to enforce a maximum height on the panel in a way that squished the list box inside the panel. - The panel would reposition itself based on the size of the anchor element *while the panel was open*. E.g. you would click an "x" button to remove a dropped function, and the anchor button's label would change from "10 dropped functions" to "9 dropped functions", causing the button to shrink. Then the panel would shift slightly to the left, moving the "x" button out from under the mouse cursor. This commit fixes all of these issues. The most important change is the switch to position:fixed: Now the panel will no longer be clipped by overflow:hidden/auto ancestor of the button that opens the panel. Furthermore, the panel position is only computed during opening and then remains unchanged while the panel is open. And there is some logic to make the panel fit onscreen (while also making sure that the arrow still points at the right place).
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #4692 +/- ##
=======================================
Coverage 88.33% 88.34%
=======================================
Files 299 299
Lines 26709 26724 +15
Branches 7206 7209 +3
=======================================
+ Hits 23594 23608 +14
- Misses 2902 2903 +1
Partials 213 213
☔ View full report in Codecov by Sentry. |
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 looks good to me, but I noticed an issue when the permalink window auto opens after uploading, but only when we sanitize the profile by unchecking some checkbox. I believe this is because there's a transition, and then some computations are not correct anymore at the end of the transition (probably anchorRectRelativeToPage.top
but maybe others too). It's not clear to me how to fix this with this new logic though... What do you think?
left: panelLeft, | ||
top: anchorPoint.top, | ||
width: adjustedPanelWidth, | ||
height: 0, // ignored |
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 need this one at all if we don't use 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.
We don't need it except to make the types happy. I'm putting it in a state field called panelRect
. What would you suggest instead? I could change it to instead have three fields, panelLeft
etc, but I'm not sure if that's better.
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.
Yeah I was wondering about removing height
everywhere if we don't use it... Did you have other ideas about 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.
We use anchorRectRelativeToViewport.height
.
display: flex; | ||
flex-flow: column nowrap; | ||
padding-top: var(--internal-arrow-clip-height); | ||
margin-bottom: 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.
It's not clear to me what this margin-bottom does, can you please explain?
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.
Oops, leftover from something I was trying. It does nothing, I'll remove it.
color: black; | ||
line-height: 1.3; | ||
pointer-events: none; | ||
text-align: left; |
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.
It's not clear to me why there's a text-align here?
If you decide to keep it, what do you think about using start
instead?
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 don't remember why I put a text-align there. I'll remove it.
--internal-approx-distance-to-bottom: 100px; | ||
min-height: 0; | ||
flex-flow: column nowrap; | ||
flex-shrink: 1; |
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.
optional: For this I'd use flex: auto
which is IMO more explicit.
// from the right edge of the panel. | ||
// If set to "left", the arrow will be positioned `distanceFromEdge` pixels | ||
// from the left edge of the panel. | ||
anchorEdge: 'left' | 'right', |
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 it be easy to support 'start' | 'end'
instead?
Ugh good catch, that's indeed a problem. I'll have to think about it a bit. (What I really want is a way to get the location of an element "as if all ancestor transforms were reset to the identity transform", but I don't think I get to have that.) |
Maybe we can just delay the opening until after the transition completes. Do you know where the code that opens the permalink panel in this case lives? |
left: anchorRectRelativeToPage.left - win.scrollX, | ||
top: anchorRectRelativeToPage.top - win.scrollY, |
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.
It's not super clear to me why we remove scrollX/scrollY.
According to MDN left/top are already relative to the viewport, and we need to add them to get values relative to the document.
We use this property
This value comes from this reducer: Lines 195 to 209 in 2c3253c
The "profile sanitized" action is dispatched here: profiler/src/actions/publish.js Lines 291 to 306 in 2c3253c
The profiler/src/components/app/ProfileViewer.css Lines 65 to 68 in 2c3253c
This one is controlled by this state: profiler/src/reducers/publish.js Lines 185 to 203 in 2c3253c
So maybe we can indeed tweak For width and height you could always use offsetWidth/offsetHeight, but I don't have an idea for top and left. |
Maybe |
This PR implements some changes to the arrow panel code which make arrow panels usable for the dropped functions panel in the call tree settings.
With the previous implementation, I encountered these issues:
This commit fixes all of these issues.
The most important change is the switch to position:fixed: Now the panel will no longer be clipped by overflow:hidden/auto ancestor of the button that opens the panel.
Furthermore, the panel position is only computed during opening and then remains unchanged while the panel is open.
And there is some logic to make the panel fit onscreen (while also making sure that the arrow still points at the right place).
┆Issue is synchronized with this Jira Task