Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scroll bar is gone with using CascadingHoverMenus #37

Open
Yangeok opened this issue Sep 2, 2020 · 10 comments
Open

Scroll bar is gone with using CascadingHoverMenus #37

Yangeok opened this issue Sep 2, 2020 · 10 comments

Comments

@Yangeok
Copy link

Yangeok commented Sep 2, 2020

The hover menu was ported with nextjs + typescript.

When hover, scrollbar disappears and occurs under the new css attribute of body padding-right: 20px; overflow: hidden;. I used the example 'CascadingHoverMenus'.

The first status is position: static and when scroll down, position: fixed. I changed it to position: sticky and the symptoms were the same.

Attaching the GIF below:

Kapture 2020-09-02 at 15 02 38

The code i wrote is as follows:

import React, { Fragment } from 'react'
import Link from 'next/link'
import styled from 'styled-components'

import { HoverMenu, MenuItem } from '@Components/Basic'
import { ExpandMore, ChevronRight } from '@Components/Icons'
import PopupState, { bindHover, bindMenu } from 'material-ui-popup-state'

import { IDesktopMenu } from './DesktopMenu'

const getPopupId = (str: string) => str.toLocaleLowerCase().replace(/\s/g, '-')

const TextWrapper = styled.div`
  color: ${(props: any) => props.theme.colors.black};
`

// FIXME: to change ParentPopupState type
const ParentPopupState: any = React.createContext(null)

const CascadingHoverMenus: React.FunctionComponent<IDesktopMenu.IProps> = ({ menuItem, hideOnScroll }): JSX.Element => {
  // TODO: to convert to recursive function
  return (
    <PopupState style={{ overflow: 'hidden' }} variant="popover" popupId={getPopupId(menuItem.name)}>
      {popupState => {
        return (
          <Fragment>
            <MenuItem {...bindHover(popupState)}>
              <TextWrapper>
                {menuItem.name}
                <ExpandMore />
              </TextWrapper>
            </MenuItem>
            <ParentPopupState.Provider value={popupState}>
              <HoverMenu
                {...bindMenu(popupState)}
                anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
                transformOrigin={{ vertical: 'top', horizontal: 'left' }}
                getContentAnchorEl={null}
              >
                {menuItem.items.map(lv2 => {
                  if (!lv2.items) {
                    return (
                      <Link href={lv2.link}>
                        <MenuItem onClick={popupState.close}>{lv2.name}</MenuItem>
                      </Link>
                    )
                  }
                  return (
                    <Submenu popupId={getPopupId(lv2.name)} title={lv2.name}>
                      {lv2.items.map(lv3 => {
                        if (!lv3.items) {
                          return (
                            <Link href={lv3.link}>
                              <MenuItem onClick={popupState.close}>{lv3.name}</MenuItem>
                            </Link>
                          )
                        }
                      })}
                    </Submenu>
                  )
                })}
              </HoverMenu>
            </ParentPopupState.Provider>
          </Fragment>
        )
      }}
    </PopupState>
  )
}

export default CascadingHoverMenus

// FIXME: to change Submenu type
const Submenu: any = React.forwardRef(({ title, popupId, children, ...props }: { title: any; popupId: any; children: any }, ref: any) => (
  <ParentPopupState.Consumer>
    {parentPopupState => (
      <PopupState variant="popover" popupId={getPopupId(popupId)} parentPopupState={parentPopupState}>
        {popupState => (
          <ParentPopupState.Provider value={popupState}>
            <MenuItem {...bindHover(popupState)} selected={popupState.isOpen} ref={ref}>
              <span>{title}</span>
              <ChevronRight />
            </MenuItem>
            <HoverMenu
              {...bindMenu(popupState)}
              anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
              transformOrigin={{ vertical: 'top', horizontal: 'left' }}
              getContentAnchorEl={null}
              {...props}
            >
              {children}
            </HoverMenu>
          </ParentPopupState.Provider>
        )}
      </PopupState>
    )}
  </ParentPopupState.Consumer>
))

I'd appreciate it if you could tell me the solution.

@jedwards1211
Copy link
Member

This happens only with the cascading hover menus, not with the other examples?

I'm not sure what could be causing it in this library since the only CSS I inject in this case is pointerEvents: auto...

@oliviertassinari any idea about this? Since Popover mounts a full-viewport invisible backdrop element I assume that's somehow causing this.

@jedwards1211
Copy link
Member

@oliviertassinari click-away detection could be implemented with a capture listener on document.body instead of an invisible backdrop. And suppressing hover events while the popover is open (if desired, it's not always desirable) could also be implemented with a capture listener that stops propagation.

@oliviertassinari
Copy link

@jedwards1211 There are a couple of open issues about this problem on the main repository, I believe we had discussed this problem in more details already. However, there are no open effort to improve this, as far as I know.

@Yangeok
Copy link
Author

Yangeok commented Sep 3, 2020

@jedwards1211
If it's hard to know with CSS, what do you need to know to solve this issue?

I don't know if it's the right word choice though. Even if injected overflow: hidden into the component covers the above code, equally body element has a margin-right: 20pxwhen I hover the menu.

@jedwards1211
Copy link
Member

@oliviertassinari does disablePortal disable rendering the backdrop too? If not, how would you feel about a disableBackdrop property?

@oliviertassinari
Copy link

oliviertassinari commented Dec 2, 2020

@jedwards1211 The jump can be fixed by adding the .mui-fixed class name. I think that the proper solution is no to use the modal.

@jedwards1211
Copy link
Member

jedwards1211 commented Dec 3, 2020

@oliviertassinari

I think that the proper solution is no to use the modal.

Do you mean to not use Popover or Menu for hover menus?

@oliviertassinari
Copy link

Yes, we need to refactor the Popover to be able to work like a non modal

@ruiaraujo012
Copy link

I had the same problem and I fixed it by adding the prop disableScrollLock on HoverPopover component.

This is my HoverPopover:

  <HoverPopover
      PaperProps={{
        sx: [
          {
            border: (theme) => `solid 1px ${alpha(theme.palette.grey[500], 0.08)}`,
            minWidth: 200,
            ml: 0.5,
            overflow: 'inherit',
          },
        ],
      }}
      anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
      disableScrollLock
      transformOrigin={{ horizontal: 'right', vertical: 'top' }}
      {...other}
    >
      <ArrowStyle className='arrow' />

      {children}
    </HoverPopover>

@beefs
Copy link

beefs commented Feb 1, 2023

I had the same problem and I fixed it by adding the prop disableScrollLock on HoverPopover component.

This is my HoverPopover:

  <HoverPopover
      PaperProps={{
        sx: [
          {
            border: (theme) => `solid 1px ${alpha(theme.palette.grey[500], 0.08)}`,
            minWidth: 200,
            ml: 0.5,
            overflow: 'inherit',
          },
        ],
      }}
      anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
      disableScrollLock
      transformOrigin={{ horizontal: 'right', vertical: 'top' }}
      {...other}
    >
      <ArrowStyle className='arrow' />

      {children}
    </HoverPopover>

it works, Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants