-
Notifications
You must be signed in to change notification settings - Fork 1.3k
RSP-1387|RSP-1393: Improve Breadcrumbs auto collapse behavior #148
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
Build successful! View the storybook |
Build successful! View the storybook |
let domRef = useDOMRef(ref); | ||
let lsitRef = useRef(null); |
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 think you meant listRef
?
setHidden(domRef.current.scrollWidth > domRef.current.offsetWidth); | ||
if (isCollapsible && lsitRef.current) { | ||
let containterRect = lsitRef.current.getBoundingClientRect(); | ||
let index = childrenRect.findIndex(childRect => childRect.right > containterRect.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.
you'll need to loop over the childrenRect's during onResize to get their Bounding Client Rect's.
check out the storybook for this, you'll see that items disappear from the list much too quickly.
the reason for this is that the 'right' value for each of the items is whatever they started at, then, as the window shrinks, the left and right of the containing ul move to the left because it's centered and 50vw.
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 should add some tests for this as well
...otherProps | ||
} = props; | ||
let {styleProps} = useStyleProps(otherProps); | ||
|
||
let isCollapsible = maxVisibleItems === 'auto'; | ||
let childArray = React.Children.toArray(children); | ||
|
||
const [hidden, setHidden] = useState(false); | ||
const [visibleItems, setVisibleItems] = useState(isCollapsible ? childArray.length : maxVisibleItems); |
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 state should probably be in stately
calculating bounding rects should stay in this file
and this should probably be over in stately as well along with an rtl control
let [visibleItems, setVisibleItems] = useState(isCollapsible ? childArray.length : maxVisibleItems);
function setState(childrenRects, containerRect, direction='rtl') {
let index = childrenRects.findIndex(childRect => direction === 'rtl' ? childRect.right > containerRect.right : childRect.left < containerRect.left);
let visibleItemsCount;
let minVisibleItems = showRoot ? MIN_VISIBLE_ITEMS + 1 : MIN_VISIBLE_ITEMS;
if (index === -1) {
visibleItemsCount = childArray.length;
} else if (index < minVisibleItems) {
visibleItemsCount = minVisibleItems;
} else {
visibleItemsCount = index;
}
setVisibleItems(visibleItemsCount);
}
return [visibleItems, setState];
something along those lines anyways
Build successful! View the storybook |
Build successful! View the storybook |
Build successful! View the storybook |
Build successful! View the storybook |
window.removeEventListener('resize', onResize); | ||
}; | ||
}, [domRef, isCollapsible]); | ||
let {visibleItems} = useBreadcrumbsState(props, listRef); |
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 tempting to just pass the listRef in, however, we really need to keep anything DOM associated out of the the stately hooks, otherwise we can't use them in environments (ie native/uxp)
Lets pass the values that we'll use to calculate the state and not the whole dom ref
} | ||
}; | ||
|
||
window.addEventListener('resize', onResize); |
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.
resize should stay out in @react-spectrum instead of being stately because it's specific to web
please refer back to my original comment for what should be moved from @react-spectrumt to stately, it shouldn't be a lot of code, really just the state and maybe a minimal amount of logic to dictate how collapsing is calculated
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 think @react-aria is probably the right place for this useEffect
block entirely.
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.
@devongovett can you explain more? I get that react-aria is for interactions, but i thought that was for direct interactions, not indirect ones like window resize.
I'm happy to have this put into react-aria, just want some clarification :)
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.
@snowystinger I moved useEffect block to react-aria (and left minimal state logic here), but that means passing listRef to useBreadcrumbs and doing dom related calculations there... please check if thats OK
const [visibleItems, setVisibleItems] = useState(isCollapsible ? childArray.length : maxVisibleItems); | ||
|
||
useEffect(() => { | ||
let listItems = Array.from(ref.current.children); |
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 wonder if it's better to do ref.current.children
or for each breadcrumb to expose via useImperativeHandle their own width
thoughts for later, i'm fine with doing it this way right now
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.
like the idea, but I would definitely need some help with useImperativeHandle... is it OK if I address this in additional task?
Build successful! View the storybook |
Build successful! View the storybook |
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.
Looks really good! thank you!
Last question I promise, the dropdown, it should contain every item regardless of its visibility in the breadcrumbs that aren't collapsed?
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.
LGTM
Build successful! View the storybook |
@snowystinger from XD guidelines it seems like the dropdown contains every item, which is kinda confusing... maybe to advice with the design team? (that there is an option to only show collapsed items in a dropdown) |
* initial Breadcrumbs work * improve link styles * simplify styles * add flex to macro * fix multiline * more style improvements * allow more link props * pass down link props * remove s2 link context and styles added * remove underline for disabled link * review follow-up * use marginStart: text-to-visual for chevron * remove design link * remove shorthand flex from theme * remove nav wrapper * update styles * spread props onto RAC breadcrumbs * add onAction story * add styles to Heading * ad Heading story to Breadcrumbs * fixing breadcrumb vertical padding when multiline only had to change the height, the gap between the top and current breadcrumb is already provided by the row gap of 4 which equals the breadcrumbs-start-edge-to-truncated-menu value in the spec. This value is also moreaccurate than the 9px they have for top-text-to-to-bottom-text since it starts at the bottom of the breadcrumb box * fix active style, chevron centering, and tentative styles for multiline see comments for uncertainties with margins and multiline in design * update default, wrapper padding, and isMultiLine sizing as per design feedback * review comments * fix Safari focus ring cut off * get rid of default heading styling for now --------- Co-authored-by: Reid Barber <reid@reidbarber.com> Co-authored-by: danilu <danilu@adobe.com>
https://jira.corp.adobe.com/browse/RSP-1387
When there isn't enough space, the breadcrumbs shouldn't immediately collapse into a single
dropdown but move one by one into the dropdown until it fits.
Stories:
https://jira.corp.adobe.com/browse/RSP-1393
The collapse behavior should work with the multi-line variant
Story:
NOTE: needs design review (should last/selected item be visible?)
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Team: