MCPcopy
hub / github.com/JedWatson/react-select / getMenuPlacement

Function getMenuPlacement

packages/react-select/src/components/Menu.tsx:59–219  ·  view source on GitHub ↗
({
  maxHeight: preferredMaxHeight,
  menuEl,
  minHeight,
  placement: preferredPlacement,
  shouldScroll,
  isFixedPosition,
  controlHeight,
}: PlacementArgs)

Source from the content-addressed store, hash-verified

57}
58
59export function getMenuPlacement({
60 maxHeight: preferredMaxHeight,
61 menuEl,
62 minHeight,
63 placement: preferredPlacement,
64 shouldScroll,
65 isFixedPosition,
66 controlHeight,
67}: PlacementArgs): CalculatedMenuPlacementAndHeight {
68 const scrollParent = getScrollParent(menuEl!);
69 const defaultState: CalculatedMenuPlacementAndHeight = {
70 placement: 'bottom',
71 maxHeight: preferredMaxHeight,
72 };
73
74 // something went wrong, return default state
75 if (!menuEl || !menuEl.offsetParent) return defaultState;
76
77 // we can't trust `scrollParent.scrollHeight` --> it may increase when
78 // the menu is rendered
79 const { height: scrollHeight } = scrollParent.getBoundingClientRect();
80 const {
81 bottom: menuBottom,
82 height: menuHeight,
83 top: menuTop,
84 } = menuEl.getBoundingClientRect();
85
86 const { top: containerTop } = menuEl.offsetParent.getBoundingClientRect();
87 const viewHeight = isFixedPosition
88 ? window.innerHeight
89 : normalizedHeight(scrollParent);
90 const scrollTop = getScrollTop(scrollParent);
91
92 const marginBottom = parseInt(getComputedStyle(menuEl).marginBottom, 10);
93 const marginTop = parseInt(getComputedStyle(menuEl).marginTop, 10);
94 const viewSpaceAbove = containerTop - marginTop;
95 const viewSpaceBelow = viewHeight - menuTop;
96 const scrollSpaceAbove = viewSpaceAbove + scrollTop;
97 const scrollSpaceBelow = scrollHeight - scrollTop - menuTop;
98
99 const scrollDown = menuBottom - viewHeight + scrollTop + marginBottom;
100 const scrollUp = scrollTop + menuTop - marginTop;
101 const scrollDuration = 160;
102
103 switch (preferredPlacement) {
104 case 'auto':
105 case 'bottom':
106 // 1: the menu will fit, do nothing
107 if (viewSpaceBelow >= menuHeight) {
108 return { placement: 'bottom', maxHeight: preferredMaxHeight };
109 }
110
111 // 2: the menu will fit, if scrolled
112 if (scrollSpaceBelow >= menuHeight && !isFixedPosition) {
113 if (shouldScroll) {
114 animatedScrollTo(scrollParent, scrollDown, scrollDuration);
115 }
116

Callers 1

MenuPlacerFunction · 0.85

Calls 5

getScrollParentFunction · 0.90
normalizedHeightFunction · 0.90
getScrollTopFunction · 0.90
animatedScrollToFunction · 0.90
scrollToFunction · 0.90

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…