className?: string;
closeOnClick?: boolean;
id: string;
- isPortal?: boolean;
onClose?: VoidFunction;
onOpen?: VoidFunction;
openDropdown?: boolean;
render() {
const { open } = this.state;
- const {
- allowResizing,
- className,
- closeOnClick = true,
- id,
- isPortal,
- size = 'full',
- zLevel,
- } = this.props;
+ const { allowResizing, className, closeOnClick = true, id, size = 'full', zLevel } = this.props;
const a11yAttrs: A11yAttrs = {
'aria-controls': `${id}-dropdown`,
'aria-expanded': open,
aria-labelledby={`${id}-trigger`}
className={className}
id={`${id}-dropdown`}
- isPortal={isPortal}
onRequestClose={this.handleClose}
open={open}
overlay={
import { ActionsDropdown, Dropdown } from '../Dropdown';
import { ButtonSecondary } from '../buttons';
-describe('Dropdown with Portal Wrapper', () => {
- it('renders', async () => {
- const { user } = setupWithChildren();
- expect(screen.getByRole('button')).toBeInTheDocument();
-
- await user.click(screen.getByRole('button'));
- expect(screen.getByRole('menu')).toBeInTheDocument();
- });
-
- it('toggles with render prop', async () => {
- const { user } = setupWithChildren(({ onToggleClick }) => (
- <ButtonSecondary onClick={onToggleClick} />
- ));
-
- await user.click(screen.getByRole('button'));
- expect(screen.getByRole('menu')).toBeVisible();
- });
-
- function setupWithChildren(children?: Dropdown['props']['children']) {
- return renderWithRouter(
- <Dropdown id="test-menu" isPortal overlay={<div id="overlay" />}>
- {children ?? <ButtonSecondary />}
- </Dropdown>
- );
- }
-});
-
describe('Dropdown', () => {
it('renders', async () => {
const { user } = setupWithChildren();
return renderWithRouter(
<Dropdown id="test-menu" overlay={<div id="overlay" />}>
{children ?? <ButtonSecondary />}
- </Dropdown>
+ </Dropdown>,
);
}
});
return renderWithRouter(
<ActionsDropdown id="test-menu">
<div id="overlay" />
- </ActionsDropdown>
+ </ActionsDropdown>,
);
}
});
import classNames from 'classnames';
import { throttle } from 'lodash';
import React, { AriaRole } from 'react';
-import { createPortal, findDOMNode } from 'react-dom';
+import { findDOMNode } from 'react-dom';
import tw from 'twin.macro';
import { THROTTLE_SCROLL_DELAY } from '../helpers/constants';
import { PopupPlacement, PopupZLevel, popupPositioning } from '../helpers/positioning';
interface PopupProps extends Omit<PopupBaseProps, 'style'> {
allowResizing?: boolean;
children: React.ReactNode;
- isPortal?: boolean;
overlay: React.ReactNode;
}
const { height, left, top, width } = popupPositioning(
toggleNode,
this.popupNode.current,
- placement
+ placement,
);
// save width and height (and later set in `render`) to avoid resizing the popup element,
return (
<>
{this.props.children}
- {this.props.overlay &&
- (this.props.isPortal ? (
- <PortalWrapper>
- <PopupWithRef
- placement={placement}
- ref={this.popupNode}
- style={style}
- {...popupProps}
- >
- {overlay}
- </PopupWithRef>
- </PortalWrapper>
- ) : (
- <PopupWithRef placement={placement} ref={this.popupNode} style={style} {...popupProps}>
- {overlay}
- </PopupWithRef>
- ))}
+ {this.props.overlay && (
+ <PopupWithRef placement={placement} ref={this.popupNode} style={style} {...popupProps}>
+ {overlay}
+ </PopupWithRef>
+ )}
</>
);
}
[PopupZLevel.Global]: tw`sw-z-global-popup`,
[PopupZLevel.Content]: tw`sw-z-content-popup`,
[PopupZLevel.Absolute]: tw`sw-z-global-popup`,
- }[zLevel])};
+ })[zLevel]};
&.is-bottom,
&.is-bottom-left,
${tw`sw-ml-2`};
}
`;
-
-class PortalWrapper extends React.Component {
- el: HTMLElement;
-
- constructor(props: object) {
- super(props);
- this.el = document.createElement('div');
- }
-
- componentDidMount() {
- document.body.appendChild(this.el);
- }
-
- componentWillUnmount() {
- document.body.removeChild(this.el);
- }
-
- render() {
- return createPortal(this.props.children, this.el);
- }
-}
ItemDownload,
ItemLink,
PopupPlacement,
+ PopupZLevel,
Tooltip,
} from 'design-system';
import { some } from 'lodash';
profile.name,
profile.languageName,
)}
- isPortal
+ zLevel={PopupZLevel.Global}
>
{actions.edit && (
<ItemLink className="it__quality-profiles__activate-more-rules" to={activateMoreUrl}>
DropdownToggler,
ItemButton,
PopupPlacement,
+ PopupZLevel,
} from 'design-system';
import * as React from 'react';
import Spinner from '../../../components/ui/Spinner';
allowResizing
open={ides.length > 1}
placement={PopupPlacement.BottomLeft}
- isPortal
+ zLevel={PopupZLevel.Global}
overlay={
<DropdownMenu size="auto">
{ides.map((ide) => {
ItemDangerButton,
ItemDivider,
ItemHeader,
+ PopupZLevel,
} from 'design-system';
import * as React from 'react';
import withComponentContext from '../../../app/components/componentContext/withComponentContext';
allowResizing
closeOnClick={false}
id="filter-hotspots-menu"
- isPortal
+ zLevel={PopupZLevel.Global}
overlay={
<>
<ItemHeader>{translate('hotspot.filters.title')}</ItemHeader>