diff --git a/.changeset/gentle-queens-rest.md b/.changeset/gentle-queens-rest.md new file mode 100644 index 00000000000..b3566b02286 --- /dev/null +++ b/.changeset/gentle-queens-rest.md @@ -0,0 +1,5 @@ +--- +'@primer/react': patch +--- + +UnderlineNav2: Handle the case when container is too small to render any items diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-Counters-Loading-State-dark-high-contrast-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-Counters-Loading-State-dark-high-contrast-linux.png index fe4babaf36d..4a389c8cb9e 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-Counters-Loading-State-dark-high-contrast-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-Counters-Loading-State-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-Counters-Loading-State-light-high-contrast-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-Counters-Loading-State-light-high-contrast-linux.png index c3eebcd09e6..486f5efb9a5 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-Counters-Loading-State-light-high-contrast-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-Counters-Loading-State-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-colorblind-Keep-selected-item-visible-vrt-3-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-colorblind-Keep-selected-item-visible-vrt-3-linux.png index 364e6a09c7c..15ca88883fe 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-colorblind-Keep-selected-item-visible-vrt-3-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-colorblind-Keep-selected-item-visible-vrt-3-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-1-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-1-linux.png index 8a3d5396e58..0f745f476a2 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-1-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-1-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-3-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-3-linux.png index b7c8b739818..96bbc3a0b0c 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-3-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-3-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-4-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-4-linux.png index 69e89eef9c2..ea7150490d0 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-4-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Keep-selected-item-visible-vrt-4-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-2-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-2-linux.png index 9d6830a58e1..8914315c6ca 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-2-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-2-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-3-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-3-linux.png index 35e33183a50..2d27f1ad9c0 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-3-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-3-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-4-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-4-linux.png index d1f6497f0d1..bb012280b50 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-4-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-dark-high-contrast-Overflow-interaction-vrt-4-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-1-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-1-linux.png index e0703212e55..bba1c91e71c 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-1-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-1-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-3-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-3-linux.png index be6e01e8e8f..34684d182bf 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-3-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-3-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-4-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-4-linux.png index 663d4febe9d..4bbad74c3da 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-4-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Keep-selected-item-visible-vrt-4-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-2-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-2-linux.png index efb7d40c768..fd400743a5c 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-2-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-2-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-3-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-3-linux.png index 51b1cd2fada..9433c669d7a 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-3-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-3-linux.png differ diff --git a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-4-linux.png b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-4-linux.png index 6eff9873b45..cd24730a373 100644 Binary files a/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-4-linux.png and b/.playwright/snapshots/components/UnderlineNav.test.ts-snapshots/UnderlineNav-UnderlineNav-Interactions-light-high-contrast-Overflow-interaction-vrt-4-linux.png differ diff --git a/src/UnderlineNav2/UnderlineNav.tsx b/src/UnderlineNav2/UnderlineNav.tsx index 2db11b07916..1f03aaf1e99 100644 --- a/src/UnderlineNav2/UnderlineNav.tsx +++ b/src/UnderlineNav2/UnderlineNav.tsx @@ -35,6 +35,8 @@ export type UnderlineNavProps = { // When page is loaded, we don't have ref for the more button as it is not on the DOM yet. // However, we need to calculate number of possible items when the more button present as well. So using the width of the more button as a constant. const MORE_BTN_WIDTH = 86 +// The height is needed to make sure we don't have a layout shift when the more button is the only item in the nav. +const MORE_BTN_HEIGHT = 45 // Needed this because passing a ref using HTMLULListElement to `Box` causes a type error const NavigationList = styled.ul` @@ -43,6 +45,8 @@ const NavigationList = styled.ul` const MoreMenuListItem = styled.li` display: flex; + align-items: center; + height: ${MORE_BTN_HEIGHT}px; ` const overflowEffect = ( @@ -94,7 +98,8 @@ const overflowEffect = ( const ariaCurrent = child.props['aria-current'] const isCurrent = Boolean(ariaCurrent) && ariaCurrent !== 'false' // We need to make sure to keep the selected item always visible. - if (isCurrent) { + // To do that, we swap the selected item with the last item in the list to make it visible. (When there is at least 1 item in the list to swap.) + if (isCurrent && numberOfListItems > 0) { // If selected item couldn't make in to the list, we swap it with the last item in the list. const indexToReplaceAt = numberOfListItems - 1 // because we are replacing the last item in the list // splice method modifies the array by removing 1 item here at the given index and replace it with the "child" element then returns the removed item. @@ -251,6 +256,8 @@ export const UnderlineNav = forwardRef( }, []) const actions = responsiveProps.actions + // This is the case where the viewport is too narrow to show any list item with the more menu. In this case, we only show the dropdown + const onlyMenuVisible = responsiveProps.items.length === 0 const [childWidthArray, setChildWidthArray] = useState([]) const setChildrenWidth = useCallback((size: ChildSize) => { setChildWidthArray(arr => { @@ -336,7 +343,7 @@ export const UnderlineNav = forwardRef( {responsiveProps.items} {actions.length > 0 && ( - + {!onlyMenuVisible && } | React.KeyboardEvent) => { - swapMenuItemWithListItem(action, index, event, updateListAndMenu) + // When there are no items in the list, do not run the swap function as we want to keep everything in the menu. + !onlyMenuVisible && swapMenuItemWithListItem(action, index, event, updateListAndMenu) setSelectEvent(event) closeOverlay() focusOnMoreMenuBtn() diff --git a/src/UnderlineNav2/UnderlineNavItem.tsx b/src/UnderlineNav2/UnderlineNavItem.tsx index 919e34502bc..66b596ab211 100644 --- a/src/UnderlineNav2/UnderlineNavItem.tsx +++ b/src/UnderlineNav2/UnderlineNavItem.tsx @@ -105,7 +105,14 @@ export const UnderlineNavItem = forwardRef( setChildrenWidth({text, width: domRect.width}) setNoIconChildrenWidth({text, width: domRect.width - iconWidthWithMargin}) - if (selectedLink === undefined && Boolean(ariaCurrent) && ariaCurrent !== 'false') { + // When an item has aria-current !== false while rendering, we should be sure to select it. + // It can happen when the page is loaded (selectedLink === undefined) + // or if the item is coming out of the menu when there is enough space to show items along with the more menu. (selectedLink.current === null) + if ( + (selectedLink === undefined || selectedLink.current === null) && + Boolean(ariaCurrent) && + ariaCurrent !== 'false' + ) { setSelectedLink(ref as RefObject) } diff --git a/src/UnderlineNav2/styles.ts b/src/UnderlineNav2/styles.ts index cf39342086f..dd14ce0d0a5 100644 --- a/src/UnderlineNav2/styles.ts +++ b/src/UnderlineNav2/styles.ts @@ -61,6 +61,7 @@ export const getDividerStyle = (theme?: Theme) => ({ width: '1px', borderLeftColor: `${theme?.colors.border.muted}`, marginRight: 1, + height: '24px', // The height of the divider - reference from Figma }) export const moreBtnStyles = {