UNPKG

@atlaskit/atlassian-navigation

Version:

A horizontal navigation component for Atlassian apps.

101 lines (99 loc) 3.32 kB
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 }))); };