Jump Bar Overflow Accordion Effect
Description
This PR introduces an initial implementation of an accordion-like effect for displaying file paths in the tab bar. The goal is to improve usability when file paths are too long to fit in the available space.
Current (Draft) Behavior:
- The accordion effect is always shown, regardless of whether the file path is truncated.
Expected Behavior:
- The accordion effect should only be triggered when a file path is truncated due to limited space in the scroll view.
- If the file path fits within the visible area, the full path should be shown without any animation or effect.
Request for Feedback:
- I would appreciate guidance on the best way to detect when a file path is actually truncated, so the effect only triggers in those cases.
- Feedback on the user experience and any edge cases to consider is also welcome.
Related Issues
- Related to #241
Checklist
- [x] I read and understood the contributing guide as well as the code of conduct
- [x] The issues this PR addresses are related to each other
- [x] My changes generate no new warnings
- [x] My code builds and runs on my machine
- [x] My changes are all related to the related issue above
- [x] I documented my code
Screenshots
https://github.com/user-attachments/assets/7ed81d9a-b4ea-4b4b-b97d-b68863e00e87
@austincondiff — would love your input on this!
@swiftlysingh Thanks so much for putting this together! This is a great start and really exciting to see it in action. Watching the screen recording, I think you're definitely on the right track. The basic accordion behavior is there, and the hover interaction feels pretty good, especially when you get to the animation.
As you mentioned, the accordion behavior should only kick in when the content overflows. You’ll want to detect when the full breadcrumb path exceeds the available width of the container.
A few things you might consider:
- Use
.background(GeometryReader { proxy in ... })to measure the actual width of the rendered text. - Compare that to the width of the container (likely via another
GeometryReaderor a.framemodifier bound to a@State). - If the content is wider, toggle a
@Statevariable likeisTruncated = trueand show the shadow/text fade-out. - And as you are aware, when there’s enough room, we should render the full text without any icon-only compression.
- Make sure the last item gets priority and hides last.
When you do expand on hover, to make it feel smooth:
withAnimation(.easeInOut(duration: 0.2)) {
// toggle view state
}
Thanks again for your work here! Happy to additional help if needed. Feel free to reach out on Discord in the help channel if you need another resource.
Got everything working! 🎉
I've attached a screen recording for reference:
https://github.com/user-attachments/assets/0d32f9c8-d086-4cbb-b885-718acade94ce
We can further tweak the curve at which the crumbs collapse, as well as set the minimum threshold for the crumb width.
Big thanks to @austincondiff for your help and input!
Feedback and suggestions are always welcome.
That looks very nice, @swiftlysingh. Great work!
Minor feedback: If you compare to Xcode, you see how the text fades out at the trailing edge when truncated. I'd try to do something similar if you can. Also, layout priority is as follows:
- Last item
- First item
- Items in between
If there is enough room, I have gotten it in a state where all the items in between the first and last are icons, the first and last are fully visible. As I resize it to be smaller, the first item starts to be truncated until they are all icons except the last item.
When hovering over any of the truncated items, there is a fade out at the trailing edge of the last item.
You are super close, really happy with the results. 👏
Updated the jump bar behavior with the following changes:
- Added a
firstCrumbWidthproperty to allow independent width adjustment for the first crumb. - Implemented a gradient mask on each crumb when its text is truncated, improving visual indication of truncation.
See the visual example here:
https://github.com/user-attachments/assets/5053587c-d7d5-4d9b-955a-3629d3f9f2a1
Thank you for your suggestions. I have incorporated the changes.
Do we know why this test is failing?
On my local environment, the test is passing. Can we retry running the tests?