( navWidth: number, moreMenuWidth: number, childArray: Array<React.ReactElement>, childWidthArray: ChildWidthArray, noIconChildWidthArray: ChildWidthArray, updateListAndMenu: (props: ResponsiveProps, iconsVisible: boolean) => void, )
| 60 | ` |
| 61 | |
| 62 | const overflowEffect = ( |
| 63 | navWidth: number, |
| 64 | moreMenuWidth: number, |
| 65 | childArray: Array<React.ReactElement>, |
| 66 | childWidthArray: ChildWidthArray, |
| 67 | noIconChildWidthArray: ChildWidthArray, |
| 68 | updateListAndMenu: (props: ResponsiveProps, iconsVisible: boolean) => void, |
| 69 | ) => { |
| 70 | let iconsVisible = true |
| 71 | if (childWidthArray.length === 0) { |
| 72 | updateListAndMenu({items: childArray, menuItems: []}, iconsVisible) |
| 73 | } |
| 74 | const numberOfItemsPossible = calculatePossibleItems(childWidthArray, navWidth) |
| 75 | const numberOfItemsWithoutIconPossible = calculatePossibleItems(noIconChildWidthArray, navWidth) |
| 76 | // We need to take more menu width into account when calculating the number of items possible |
| 77 | const numberOfItemsPossibleWithMoreMenu = calculatePossibleItems( |
| 78 | noIconChildWidthArray, |
| 79 | navWidth, |
| 80 | moreMenuWidth || MORE_BTN_WIDTH, |
| 81 | ) |
| 82 | const items: Array<React.ReactElement> = [] |
| 83 | const menuItems: Array<React.ReactElement> = [] |
| 84 | |
| 85 | // First, we check if we can fit all the items with their icons |
| 86 | if (childArray.length <= numberOfItemsPossible) { |
| 87 | items.push(...childArray) |
| 88 | } else if (childArray.length <= numberOfItemsWithoutIconPossible) { |
| 89 | // if we can't fit all the items with their icons, we check if we can fit all the items without their icons |
| 90 | iconsVisible = false |
| 91 | items.push(...childArray) |
| 92 | } else { |
| 93 | // if we can't fit all the items without their icons, we keep the icons hidden and show the ones that doesn't fit into the list in the overflow menu |
| 94 | iconsVisible = false |
| 95 | |
| 96 | /* Below is an accessibility requirement. Never show only one item in the overflow menu. |
| 97 | * If there is only one item left to display in the overflow menu according to the calculation, |
| 98 | * we need to pull another item from the list into the overflow menu. |
| 99 | */ |
| 100 | const numberOfItemsInMenu = childArray.length - numberOfItemsPossibleWithMoreMenu |
| 101 | const numberOfListItems = |
| 102 | numberOfItemsInMenu === 1 ? numberOfItemsPossibleWithMoreMenu - 1 : numberOfItemsPossibleWithMoreMenu |
| 103 | for (const [index, child] of childArray.entries()) { |
| 104 | if (index < numberOfListItems) { |
| 105 | items.push(child) |
| 106 | } else { |
| 107 | const ariaCurrent = child.props['aria-current'] |
| 108 | const isCurrent = Boolean(ariaCurrent) && ariaCurrent !== 'false' |
| 109 | // We need to make sure to keep the selected item always visible. |
| 110 | // 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.) |
| 111 | if (isCurrent && numberOfListItems > 0) { |
| 112 | // If selected item couldn't make in to the list, we swap it with the last item in the list. |
| 113 | const indexToReplaceAt = numberOfListItems - 1 // because we are replacing the last item in the list |
| 114 | // 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. |
| 115 | const propsectiveAction = items.splice(indexToReplaceAt, 1, child)[0] |
| 116 | menuItems.push(propsectiveAction) |
| 117 | } else { |
| 118 | menuItems.push(child) |
| 119 | } |
no test coverage detected