mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Menu: extended kinds of positions when rendered inside parent's element (usePortal=false)
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
33c405bdcf
commit
4e459fdff6
@ -32,7 +32,6 @@
|
||||
margin-bottom: $margin;
|
||||
|
||||
.Icon {
|
||||
margin-bottom: $margin * 1.5;
|
||||
border-radius: $radius;
|
||||
padding: $padding / 3;
|
||||
color: var(--textColorPrimary);
|
||||
|
||||
@ -118,13 +118,13 @@ export class ClustersMenu extends React.Component<Props> {
|
||||
<div className="WorkspaceMenu">
|
||||
<Icon big material="menu" id="workspace-menu-icon" data-test-id="workspace-menu" />
|
||||
<Menu
|
||||
usePortal
|
||||
htmlFor="workspace-menu-icon"
|
||||
className="WorkspaceMenu"
|
||||
isOpen={this.workspaceMenuVisible}
|
||||
open={() => this.workspaceMenuVisible = true}
|
||||
close={() => this.workspaceMenuVisible = false}
|
||||
toggleEvent="click"
|
||||
position={{right: "outside", top: "inside"}}
|
||||
>
|
||||
<MenuItem onClick={() => navigate(addClusterURL())} data-test-id="add-cluster-menu-item">
|
||||
<Icon small material="add" /> Add Cluster
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
border: 1px solid $borderColor;
|
||||
z-index: 101;
|
||||
|
||||
// TODO: support predefined positions setup when rendered in document.body
|
||||
// auto-positioning currently applied inside component on menu open
|
||||
&.portal {
|
||||
left: -1000px;
|
||||
top: -1000px;
|
||||
@ -22,23 +24,46 @@
|
||||
}
|
||||
}
|
||||
|
||||
// predefined positions without `usePortal` (default) where menu is rendered inside it's parent dom tree.
|
||||
&:not(.portal) {
|
||||
margin: $margin 0;
|
||||
|
||||
&.left {
|
||||
left: 0;
|
||||
&-inside {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&-outside {
|
||||
right: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.right {
|
||||
right: 0;
|
||||
&-inside {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&-outside {
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.top {
|
||||
bottom: 100%;
|
||||
&-inside {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&-outside {
|
||||
bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.bottom {
|
||||
top: 100%;
|
||||
&-inside {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&-outside {
|
||||
top: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,12 +9,13 @@ import debounce from "lodash/debounce";
|
||||
|
||||
export const MenuContext = React.createContext<MenuContextValue>(null);
|
||||
export type MenuContextValue = Menu;
|
||||
export type MenuPositionSide = "inside" | "outside";
|
||||
|
||||
export interface MenuPosition {
|
||||
left?: boolean;
|
||||
top?: boolean;
|
||||
right?: boolean;
|
||||
bottom?: boolean;
|
||||
left?: MenuPositionSide;
|
||||
top?: MenuPositionSide;
|
||||
right?: MenuPositionSide;
|
||||
bottom?: MenuPositionSide;
|
||||
}
|
||||
|
||||
export interface MenuProps {
|
||||
@ -35,11 +36,16 @@ export interface MenuProps {
|
||||
}
|
||||
|
||||
interface State {
|
||||
position?: MenuPosition;
|
||||
position?: {
|
||||
left?: boolean;
|
||||
top?: boolean;
|
||||
right?: boolean;
|
||||
bottom?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
const defaultPropsMenu: Partial<MenuProps> = {
|
||||
position: { right: true, bottom: true },
|
||||
position: { left: "inside", bottom: "outside" },
|
||||
autoFocus: false,
|
||||
usePortal: false,
|
||||
closeOnClickItem: true,
|
||||
@ -137,7 +143,12 @@ export class Menu extends React.Component<MenuProps, State> {
|
||||
}
|
||||
|
||||
// setup initial position
|
||||
const position: MenuPosition = { left: true, bottom: true };
|
||||
const position = {
|
||||
bottom: true,
|
||||
left: true,
|
||||
right: false,
|
||||
top: false,
|
||||
};
|
||||
|
||||
this.elem.style.left = `${left}px`;
|
||||
this.elem.style.top = `${bottom}px`;
|
||||
@ -248,12 +259,14 @@ export class Menu extends React.Component<MenuProps, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { position, id } = this.props;
|
||||
let { className, usePortal } = this.props;
|
||||
const { position = {}, id, className } = this.props;
|
||||
let { usePortal } = this.props;
|
||||
|
||||
className = cssNames("Menu", className, this.state.position || position, {
|
||||
portal: usePortal,
|
||||
});
|
||||
const positionClasses = usePortal
|
||||
? this.state.position // auto-corrected position to be visible in viewport
|
||||
: Object.entries(position).map(entry => entry.join("-")); // positioning relative to parent
|
||||
|
||||
const classNames = cssNames("Menu", className, { portal: usePortal }, positionClasses);
|
||||
|
||||
let children = this.props.children as ReactElement<any>;
|
||||
|
||||
@ -273,7 +286,7 @@ export class Menu extends React.Component<MenuProps, State> {
|
||||
const menu = (
|
||||
<MenuContext.Provider value={this}>
|
||||
<Animate enter={this.isOpen}>
|
||||
<ul id={id} className={className} ref={this.bindRef}>
|
||||
<ul id={id} className={classNames} ref={this.bindRef}>
|
||||
{menuItems}
|
||||
</ul>
|
||||
</Animate>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user