toolbarWrapper: {
display: 'flex',
overflow: 'hidden',
- padding: '0 20px',
+ padding: '0 0px 0 20px',
width: '100%',
},
overflowStyle: {
order: 99,
position: 'sticky',
right: '-2rem',
- backgroundColor: 'white',
+ width: 0,
},
});
type WrapperProps = {
children: OverflowChild[];
+ menuLength: number;
};
export const IntersectionObserverWrapper = withStyles(styles)((props: WrapperProps & WithStyles<CssRules>) => {
- const { classes, children } = props;
-
+ const { classes, children, menuLength } = props;
+ const lastEntryId = (children[menuLength - 1] as any).props['data-targetid'];
const navRef = useRef<any>(null);
- const [visibilityMap, setVisibilityMap] = useState({});
-
+ const [visibilityMap, setVisibilityMap] = useState<Record<string, boolean>>({});
+ const [numHidden, setNumHidden] = useState(() => findNumHidden(visibilityMap));
+ const prevNumHidden = useRef(numHidden);
+
const handleIntersection = (entries) => {
- const updatedEntries = {};
+ const updatedEntries: Record<string, boolean> = {};
entries.forEach((entry) => {
- const targetid = entry.target.dataset.targetid;
+ const targetid = entry.target.dataset.targetid as string;
+ //if true, the element is visible
if (entry.isIntersecting) {
updatedEntries[targetid] = true;
} else {
setVisibilityMap((prev) => ({
...prev,
...updatedEntries,
+ [lastEntryId]: Object.keys(updatedEntries)[0] === lastEntryId,
}));
};
+
+ //ensures that the last element is always visible if the second to last is visible
+ useEffect(() => {
+ if ((prevNumHidden.current > 1 || prevNumHidden.current === 0) && numHidden === 1) {
+ setVisibilityMap((prev) => ({
+ ...prev,
+ [lastEntryId]: true,
+ }));
+ }
+ prevNumHidden.current = numHidden;
+ }, [numHidden, lastEntryId]);
+
+ useEffect(() => {
+ setNumHidden(findNumHidden(visibilityMap));
+ }, [visibilityMap]);
+
useEffect((): any => {
+ setVisibilityMap({});
const observer = new IntersectionObserver(handleIntersection, {
root: navRef.current,
- rootMargin: '0px -20px 0px 0px',
+ rootMargin: '0px -30px 0px 0px',
threshold: 1,
});
// We are adding observers to child elements of the container div
return () => {
observer.disconnect();
};
- }, []);
+ // eslint-disable-next-line
+ }, [menuLength]);
+
+ function findNumHidden(visMap: {}) {
+ return Object.values(visMap).filter((x) => x === false).length;
+ }
return (
<div
}),
});
})}
- <OverflowMenu
- visibilityMap={visibilityMap}
- className={classes.overflowStyle}
- >
- {children}
- </OverflowMenu>
+ {numHidden >= 2 && (
+ <OverflowMenu
+ visibilityMap={visibilityMap}
+ className={classes.overflowStyle}
+ >
+ {children.filter((child) => !child.props['data-targetid'].includes("Divider"))}
+ </OverflowMenu>
+ )}
</div>
);
});