Skip to content

Conversation

pst67662
Copy link
Contributor

@pst67662 pst67662 commented Dec 25, 2019

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:

  • Included link to corresponding Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exist for this component).
  • Looked at the Accessibility Standard and/or talked to @mijordan about Accessibility for this feature.

📝 Test Instructions:

🧢 Your Team:

@adobe-bot
Copy link

Build successful! View the storybook

@adobe-bot
Copy link

Build successful! View the storybook

@pst67662 pst67662 changed the title RSP-1387: Improve Breadcrumbs auto collapse behavior RSP-1387|RSP-1393: Improve Breadcrumbs auto collapse behavior Dec 30, 2019
let domRef = useDOMRef(ref);
let lsitRef = useRef(null);
Copy link
Member

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

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.

Copy link
Member

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

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

@adobe-bot
Copy link

Build successful! View the storybook

@adobe-bot
Copy link

Build successful! View the storybook

@adobe-bot
Copy link

Build successful! View the storybook

@adobe-bot
Copy link

Build successful! View the storybook

window.removeEventListener('resize', onResize);
};
}, [domRef, isCollapsible]);
let {visibleItems} = useBreadcrumbsState(props, listRef);
Copy link
Member

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

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

Copy link
Member

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.

Copy link
Member

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 :)

Copy link
Contributor Author

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

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

Copy link
Contributor Author

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?

@adobe-bot
Copy link

Build successful! View the storybook

@adobe-bot
Copy link

Build successful! View the storybook

Copy link
Member

@snowystinger snowystinger left a 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?

Copy link
Member

@LFDanLu LFDanLu left a comment

Choose a reason for hiding this comment

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

LGTM

@adobe-bot
Copy link

Build successful! View the storybook

@dannify dannify merged commit b473e14 into master Feb 1, 2020
@dannify dannify deleted the RSP-1387 branch February 1, 2020 01:41
@pst67662
Copy link
Contributor Author

pst67662 commented Feb 3, 2020

@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)

devongovett pushed a commit that referenced this pull request Jul 25, 2024
* 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>
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.

6 participants