@atlaskit/navigation-system
Version:
The latest navigation system for Atlassian apps.
50 lines • 2.19 kB
JavaScript
import { startTransition, useState } from 'react';
import { useLayoutEffect } from '@atlaskit/ds-lib/use-layout-effect';
export function useMeasuredTopNavBreakpoints(topNav, remProbe) {
const [breakpoints, setBreakpoints] = useState({
belowSm: false,
hasMeasured: false
});
useLayoutEffect(() => {
const view = topNav === null || topNav === void 0 ? void 0 : topNav.ownerDocument.defaultView;
if (!topNav || !view) {
return;
}
const updateWidth = width => {
const rootFontSize = parseFloat(view.getComputedStyle(topNav.ownerDocument.documentElement).fontSize) || 16;
const belowSm = width < 48 * rootFontSize;
// Navigation can still be hydrating inside Suspense. An urgent context
// update would discard its server DOM and show the loading fallback.
startTransition(() => {
setBreakpoints(previous => previous.hasMeasured && previous.belowSm === belowSm ? previous : {
belowSm,
hasMeasured: true
});
});
};
let width = topNav.getBoundingClientRect().width;
updateWidth(width);
if (!view.ResizeObserver) {
return;
}
const observer = new view.ResizeObserver(entries => {
for (const entry of entries) {
if (entry.target === topNav) {
var _entry$borderBoxSize$, _entry$borderBoxSize, _entry$borderBoxSize$2;
width = (_entry$borderBoxSize$ = (_entry$borderBoxSize = entry.borderBoxSize) === null || _entry$borderBoxSize === void 0 ? void 0 : (_entry$borderBoxSize$2 = _entry$borderBoxSize[0]) === null || _entry$borderBoxSize$2 === void 0 ? void 0 : _entry$borderBoxSize$2.inlineSize) !== null && _entry$borderBoxSize$ !== void 0 ? _entry$borderBoxSize$ : topNav.getBoundingClientRect().width;
}
}
// The rem probe resizes when the root font changes, even if the header
// stays the same pixel width. Reevaluate against the last measured width.
updateWidth(width);
});
observer.observe(topNav, {
box: 'border-box'
});
if (remProbe) {
observer.observe(remProbe);
}
return () => observer.disconnect();
}, [topNav, remProbe]);
return breakpoints;
}