Semantic-UI-React
Semantic-UI-React copied to clipboard
Dropdown menus do not pop over sidebars but instead result in scrollbars in the sidebar
Bug Report
Dropdown menus do not pop over sidebars but instead result in scrollbars in the sidebar.
Steps
- Create a Sidebar
- Add a Dropdown menu with content wider than the Sidebar
- Click on the Dropdown
Expected Result
The menu options should be displayed over the Sidebar.
Actual Result
The menu options fill the Sidebar which now shows horizontal and/or vertical scrollbars.
Version
2.0.3
Testcase
https://codesandbox.io/s/prod-cookies-ilvo5
Have you had any progress on this topic? I see using Portal as a potential solution to this problem. Overlay could capture scroll events and close the Dropdown.
https://codesandbox.io/s/react-semantic-ui-dropdown-issue-irg52
@radulle no
the solution: this one support portal npm install --save react-dropdown-select
here solution, enjoy: wrap your component with
<DropdownPortal >
<Dropdown
....
function DropdownPortal( props:{children:React.ReactElement<DropdownProps>}) {
const { children } = props;
const [ state, setState ] = useState({ open:false });
const [ node, setNode ] = useState<HTMLElement | null>( null );
const [ root, setRoot ] = useState<HTMLElement | null>( null );
const dropdownref = useRef<React.Component<DropdownProps, HTMLElement>>( null );
const clone = useMemo( () => {
const { onOpen, onClose } = children.props;
return cloneElement( children, {
ref: dropdownref,
onOpen: ( ...args )=>{
setState({ open:true });
onOpen?.call( children, ...args );
},
onClose: ( ...args )=>{
setState({ open:false });
onClose?.call( children, ...args );
},
});
}, [ children ]);
useEffect( () => {
const target = dropdownref.current?.ref.current;
if ( target && target.lastChild && target.lastChild instanceof HTMLElement ) {
setNode( target.lastChild );
setRoot( target );
}
}, [ ]);
useEffect( () => {
if ( node && root ) {
if ( state.open ) {
const bounds = node.getBoundingClientRect();
document.body.appendChild( node );
node.style.position = 'absolute';
node.style.background = 'red';
node.style.top = bounds.top + 'px';
node.style.left = bounds.left + 'px';
} else {
root.append( node );
node.style.position = '';
node.style.background = '';
node.style.top = '';
node.style.left = '';
}
}
}, [state]);
return (
<>
{clone}
</>
);
}
not work with simple
flag
Any chance this becomes a regular behavior? I mean, any popout, modal or dropdown should render on a portal, right? It just feels like the best modern approach :)
Any chance this becomes a regular behavior? I mean, any popout, modal or dropdown should render on a portal, right? It just feels like the best modern approach :)
I'm currently doing a menuPortalTarget props on the dropdown, just posted yesterday, it might be close to finished. I'm trying to gather informations before making the pull request.