@atlaskit/atlassian-navigation
Version:
A horizontal navigation component for Atlassian apps.
101 lines (99 loc) • 3.32 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
/**
* @jsxRuntime classic
* @jsx jsx
*/
import React, { useCallback, useState } from 'react';
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
import { css, jsx } from '@emotion/react';
import Popup from '@atlaskit/popup';
import { WidthObserver } from '@atlaskit/width-detector';
import { OverflowProvider } from '../../controllers/overflow/overflow-provider';
import { useOverflowController } from '../../controllers/overflow/use-overflow-controller';
import { PrimaryDropdownButton } from '../PrimaryDropdownButton';
const containerStyles = css({
display: 'flex',
height: '100%',
position: 'relative',
alignItems: 'stretch',
flexBasis: 0,
flexGrow: 1,
flexShrink: 0,
// eslint-disable-next-line @atlaskit/design-system/no-nested-styles, @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
'& > *': {
margin: `0 ${"var(--ds-space-050, 4px)"}`,
flexShrink: 0
}
});
const widthObserverContainerStyles = css({
width: '100%',
minWidth: '1px',
margin: '0px',
position: 'relative',
flexShrink: 1
});
const overflowItemsStyles = css({
color: "var(--ds-text, #292A2E)"
});
// Internal only
// eslint-disable-next-line @repo/internal/react/require-jsdoc
export const PrimaryItemsContainer = ({
moreLabel,
items,
create: Create,
testId
}) => {
const [isMoreOpen, setIsMoreOpen] = useState(false);
const {
updateWidth,
visibleItems,
overflowItems
} = useOverflowController(items);
const onMoreClick = useCallback(() => {
setIsMoreOpen(!isMoreOpen);
}, [isMoreOpen, setIsMoreOpen]);
const onMoreClose = useCallback(() => {
setIsMoreOpen(false);
}, []);
const openOverflowMenu = useCallback(() => {
setIsMoreOpen(true);
}, []);
const trigger = useCallback(triggerProps => jsx(PrimaryDropdownButton, _extends({
onClick: onMoreClick,
isSelected: isMoreOpen,
testId: testId ? `${testId}-overflow-menu-trigger` : 'overflow-menu-trigger'
}, triggerProps), moreLabel), [moreLabel, onMoreClick, isMoreOpen, testId]);
const content = useCallback(() => jsx(OverflowProvider, {
isVisible: false,
openOverflowMenu: openOverflowMenu,
closeOverflowMenu: onMoreClose
}, jsx("div", {
css: overflowItemsStyles
}, overflowItems)),
// Overflow items has an unstable reference - so we will only recalculate
// content if `overflowItems` length changes.
// eslint-disable-next-line react-hooks/exhaustive-deps
[overflowItems.length, openOverflowMenu, onMoreClose]);
return jsx("div", {
css: containerStyles,
"data-testid": testId && `${testId}-primary-actions`,
role: "list"
}, jsx(OverflowProvider, {
isVisible: true,
openOverflowMenu: openOverflowMenu,
closeOverflowMenu: onMoreClose
}, visibleItems), overflowItems.length > 0 && jsx(Popup, {
shouldRenderToParent: true,
placement: "bottom-start",
content: content,
isOpen: isMoreOpen,
onClose: onMoreClose,
trigger: trigger,
testId: testId ? `${testId}-overflow-menu-popup` : 'overflow-menu-popup'
}), Create && jsx(Create, null), jsx("div", {
css: widthObserverContainerStyles
}, jsx(WidthObserver, {
offscreen: true,
setWidth: updateWidth
})));
};