Search code examples
reactjsreact-bootstrap

Navbar Dropdown with overflow hidden


I'm creating a Bootstrap Navbar using the react-bootstrap library that is meant to be horizontally scrollable when it would otherwise overflow off the page.

The horizontal scroll I've created requires that the Navbar have overflow-x: hidden applied to it. This has caused the dropdowns to become partially hidden behind it.

Before:

enter image description here

After:

enter image description here

Is there a way to maintain the scrolling functionality and display these dropdowns correctly? Also does anyone know how I can prevent the vertical scrolling that the dropdown is causing when it's open?

   

Stackblitz Website View: https://react-ts-jtybfz.stackblitz.io/

Stackblitz Editor View: https://stackblitz.com/edit/react-ts-jtybfz?file=index.tsx,NavBar.tsx,index.html

index.ts:

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

root.render(<NavBar />);

NavBar Component:

export const NavBar = () => {
  const scrollRef: MutableRefObject<HTMLElement | null> = useRef(null);
  const onWheel = (e: WheelEvent) => {
    e.preventDefault();
    e.stopPropagation();
    const container = scrollRef.current;
    const scrollPos = container.scrollLeft;

    container.scrollTo({
      top: 0,
      left: scrollPos + e.deltaY,
    });
  };

  const spam = Array(35).fill(<NavLink to="">Example</NavLink>);

  return (
    <Navbar bg="light" ref={scrollRef} onWheel={onWheel}>
      <Container>
        <Nav className="me-auto">
          <NavDropdown title="Dropdown" id="basic-nav-dropdown">
            <NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
            <NavDropdown.Item href="#action/3.2">
              Another action
            </NavDropdown.Item>
            <NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
            <NavDropdown.Divider />
            <NavDropdown.Item href="#action/3.4">
              Separated link
            </NavDropdown.Item>
          </NavDropdown>
          {spam}
        </Nav>
      </Container>
    </Navbar>
  );
};

Required CSS:

nav.navbar {
  overflow-x: hidden;
  overflow-y: visible;
}

Edit: Here is a gif showing the issue. You can scroll just fine until you click the dropdown, and then the dropdown is not visible and the scrolling also scrolls vertically. I want this dropdown to not affect the parents height and be visible while maintaining the scrolling functionality.

enter image description here


Solution

  • You could try doing it via the ref. Just changing the overflow prop

    <NavDropdown
            onClick={() => {
             
              getComputedStyle(scrollRef.current).overflowX === 'hidden'
                ? (scrollRef.current.style.overflowX = 'visible')
                : (scrollRef.current.style.overflowX = 'hidden');
            }}
            title="Dropdown"
            id="basic-nav-dropdown"
          >