Merge pull request #4341 from appsmithorg/fix/dropdown-overlap-modal
fix: Dropdown option gets overlapped on the ModalComponent
This commit is contained in:
commit
3c8944cc1c
|
|
@ -4,6 +4,7 @@ import Select from "react-select";
|
|||
import { WrappedFieldInputProps } from "redux-form";
|
||||
import { theme } from "constants/DefaultTheme";
|
||||
import { SelectComponentsConfig } from "react-select/src/components";
|
||||
import { LayersContext } from "../../../constants/Layers";
|
||||
|
||||
export type DropdownProps = {
|
||||
options: Array<{
|
||||
|
|
@ -55,11 +56,16 @@ const selectStyles = {
|
|||
};
|
||||
|
||||
export function BaseDropdown(props: DropdownProps) {
|
||||
const layer = React.useContext(LayersContext);
|
||||
const { customSelectStyles, input } = props;
|
||||
const menuPortalStyle = {
|
||||
menuPortal: (styles: any) => ({ ...styles, zIndex: layer.max }),
|
||||
};
|
||||
|
||||
return (
|
||||
<Select
|
||||
menuPortalTarget={document.body}
|
||||
styles={{ ...selectStyles, ...customSelectStyles }}
|
||||
styles={{ ...selectStyles, ...customSelectStyles, ...menuPortalStyle }}
|
||||
{...input}
|
||||
isDisabled={props.isDisabled}
|
||||
isSearchable={props.isSearchable}
|
||||
|
|
|
|||
|
|
@ -229,17 +229,35 @@ const StyledMultiDropDown = styled(MultiDropDown)<{
|
|||
}
|
||||
}
|
||||
`;
|
||||
interface DropDownComponentState {
|
||||
portalContainer: HTMLElement;
|
||||
}
|
||||
|
||||
class DropDownComponent extends React.Component<
|
||||
DropDownComponentProps,
|
||||
DropDownComponentState
|
||||
> {
|
||||
private _menu = React.createRef<HTMLDivElement>();
|
||||
constructor(props: DropDownComponentProps) {
|
||||
super(props);
|
||||
this.state = { portalContainer: this._menu.current as HTMLElement };
|
||||
}
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
portalContainer: this.props.getDropdownPosition(this._menu.current),
|
||||
});
|
||||
}
|
||||
|
||||
class DropDownComponent extends React.Component<DropDownComponentProps> {
|
||||
render() {
|
||||
const { options, selectedIndexArr } = this.props;
|
||||
const { portalContainer } = this.state;
|
||||
const selectedItems = selectedIndexArr
|
||||
? _.map(selectedIndexArr, (index) => options[index])
|
||||
: [];
|
||||
const hideCloseButtonIndex = -1;
|
||||
|
||||
return (
|
||||
<DropdownContainer>
|
||||
<DropdownContainer ref={this._menu as React.RefObject<HTMLDivElement>}>
|
||||
<DropdownStyles />
|
||||
<StyledControlGroup
|
||||
fill
|
||||
|
|
@ -300,6 +318,7 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
|
|||
popoverProps={{
|
||||
minimal: true,
|
||||
usePortal: true,
|
||||
portalContainer,
|
||||
modifiers: {
|
||||
preventOverflow: {
|
||||
enabled: false,
|
||||
|
|
@ -426,6 +445,7 @@ export interface DropDownComponentProps extends ComponentProps {
|
|||
isFilterable: boolean;
|
||||
width: number;
|
||||
height: number;
|
||||
getDropdownPosition: (node: HTMLDivElement | null) => HTMLElement;
|
||||
}
|
||||
|
||||
export default DropDownComponent;
|
||||
|
|
|
|||
|
|
@ -92,39 +92,50 @@ export function ModalComponent(props: ModalComponentProps) {
|
|||
}
|
||||
}, [props.scrollContents]);
|
||||
return (
|
||||
<Container
|
||||
bottom={props.bottom}
|
||||
height={props.height}
|
||||
left={props.left}
|
||||
right={props.bottom}
|
||||
top={props.top}
|
||||
width={props.width}
|
||||
zIndex={props.zIndex !== undefined ? props.zIndex : Layers.modalWidget}
|
||||
<Overlay
|
||||
canEscapeKeyClose={false}
|
||||
canOutsideClickClose={false}
|
||||
enforceFocus={false}
|
||||
hasBackdrop={false}
|
||||
isOpen={props.isOpen}
|
||||
onClose={props.onClose}
|
||||
portalClassName="bp3-modal-widget"
|
||||
usePortal
|
||||
>
|
||||
<Overlay
|
||||
canEscapeKeyClose={props.canEscapeKeyClose}
|
||||
canOutsideClickClose={props.canOutsideClickClose}
|
||||
className={props.overlayClassName}
|
||||
enforceFocus={false}
|
||||
hasBackdrop={
|
||||
props.hasBackDrop !== undefined ? !!props.hasBackDrop : true
|
||||
}
|
||||
isOpen={props.isOpen}
|
||||
onClose={props.onClose}
|
||||
usePortal={false}
|
||||
<Container
|
||||
bottom={props.bottom}
|
||||
height={props.height}
|
||||
left={props.left}
|
||||
right={props.bottom}
|
||||
top={props.top}
|
||||
width={props.width}
|
||||
zIndex={props.zIndex !== undefined ? props.zIndex : Layers.modalWidget}
|
||||
>
|
||||
<div>
|
||||
<Content
|
||||
className={`${getCanvasClassName()} ${props.className}`}
|
||||
height={props.height}
|
||||
ref={modalContentRef}
|
||||
scroll={props.scrollContents}
|
||||
>
|
||||
{props.children}
|
||||
</Content>
|
||||
</div>
|
||||
</Overlay>
|
||||
</Container>
|
||||
<Overlay
|
||||
canEscapeKeyClose={props.canEscapeKeyClose}
|
||||
canOutsideClickClose={props.canOutsideClickClose}
|
||||
className={props.overlayClassName}
|
||||
enforceFocus={false}
|
||||
hasBackdrop={
|
||||
props.hasBackDrop !== undefined ? !!props.hasBackDrop : true
|
||||
}
|
||||
isOpen={props.isOpen}
|
||||
onClose={props.onClose}
|
||||
usePortal={false}
|
||||
>
|
||||
<div>
|
||||
<Content
|
||||
className={`${getCanvasClassName()} ${props.className}`}
|
||||
height={props.height}
|
||||
ref={modalContentRef}
|
||||
scroll={props.scrollContents}
|
||||
>
|
||||
{props.children}
|
||||
</Content>
|
||||
</div>
|
||||
</Overlay>
|
||||
</Container>
|
||||
</Overlay>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export enum Indices {
|
|||
Layer7,
|
||||
Layer8,
|
||||
Layer9,
|
||||
Layer21 = 21,
|
||||
LayerMax = 99999,
|
||||
}
|
||||
|
||||
|
|
@ -22,6 +23,10 @@ export const Layers = {
|
|||
positionedWidget: Indices.Layer1,
|
||||
// Modal needs to higher than other widgets.
|
||||
modalWidget: Indices.Layer2,
|
||||
// Dropdown portaled to the canvas
|
||||
dropdownWidget: Indices.Layer2,
|
||||
// dropdown portaled to Modal Container with higher index than Overlay
|
||||
dropdownModalWidget: Indices.Layer21,
|
||||
selectedWidget: Indices.Layer2,
|
||||
// Layers when dragging
|
||||
animatedSnappingDropZone: Indices.Layer2,
|
||||
|
|
|
|||
|
|
@ -93,3 +93,12 @@ div.bp3-popover-arrow {
|
|||
background: white !important;
|
||||
border-bottom: 1px solid #E7E7E7 !important;
|
||||
}
|
||||
/* making both the Modal layer and the Dropdown layer */
|
||||
.bp3-modal-widget, .appsmith_widget_0 > .bp3-portal {
|
||||
z-index: 2 !important;
|
||||
}
|
||||
|
||||
/* Portals on the Modal widget */
|
||||
.bp3-modal-widget .bp3-portal {
|
||||
z-index: 21 !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,12 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
|
|||
? this.props.selectedOptionValueArr
|
||||
: [];
|
||||
}
|
||||
getDropdownPosition = (node: HTMLDivElement | null) => {
|
||||
if (Boolean(node?.closest(".bp3-modal-widget"))) {
|
||||
return document.querySelector(".bp3-modal-widget") as HTMLElement;
|
||||
}
|
||||
return document.querySelector(".appsmith_widget_0") as HTMLElement;
|
||||
};
|
||||
|
||||
getPageView() {
|
||||
const options = _.isArray(this.props.options) ? this.props.options : [];
|
||||
|
|
@ -161,6 +167,7 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
|
|||
return (
|
||||
<DropDownComponent
|
||||
disabled={this.props.isDisabled}
|
||||
getDropdownPosition={this.getDropdownPosition}
|
||||
height={componentHeight}
|
||||
isFilterable={this.props.isFilterable}
|
||||
isLoading={this.props.isLoading}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user