MCPcopy Index your code
hub / github.com/primer/react / overflowEffect

Function overflowEffect

packages/react/src/UnderlineNav/UnderlineNav.tsx:62–124  ·  view source on GitHub ↗
(
  navWidth: number,
  moreMenuWidth: number,
  childArray: Array<React.ReactElement>,
  childWidthArray: ChildWidthArray,
  noIconChildWidthArray: ChildWidthArray,
  updateListAndMenu: (props: ResponsiveProps, iconsVisible: boolean) => void,
)

Source from the content-addressed store, hash-verified

60`
61
62const 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 }

Callers 1

UnderlineNav.tsxFile · 0.70

Calls 1

calculatePossibleItemsFunction · 0.70

Tested by

no test coverage detected