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;
|
margin-bottom: $margin;
|
||||||
|
|
||||||
.Icon {
|
.Icon {
|
||||||
margin-bottom: $margin * 1.5;
|
|
||||||
border-radius: $radius;
|
border-radius: $radius;
|
||||||
padding: $padding / 3;
|
padding: $padding / 3;
|
||||||
color: var(--textColorPrimary);
|
color: var(--textColorPrimary);
|
||||||
|
|||||||
@ -118,13 +118,13 @@ export class ClustersMenu extends React.Component<Props> {
|
|||||||
<div className="WorkspaceMenu">
|
<div className="WorkspaceMenu">
|
||||||
<Icon big material="menu" id="workspace-menu-icon" data-test-id="workspace-menu" />
|
<Icon big material="menu" id="workspace-menu-icon" data-test-id="workspace-menu" />
|
||||||
<Menu
|
<Menu
|
||||||
usePortal
|
|
||||||
htmlFor="workspace-menu-icon"
|
htmlFor="workspace-menu-icon"
|
||||||
className="WorkspaceMenu"
|
className="WorkspaceMenu"
|
||||||
isOpen={this.workspaceMenuVisible}
|
isOpen={this.workspaceMenuVisible}
|
||||||
open={() => this.workspaceMenuVisible = true}
|
open={() => this.workspaceMenuVisible = true}
|
||||||
close={() => this.workspaceMenuVisible = false}
|
close={() => this.workspaceMenuVisible = false}
|
||||||
toggleEvent="click"
|
toggleEvent="click"
|
||||||
|
position={{right: "outside", top: "inside"}}
|
||||||
>
|
>
|
||||||
<MenuItem onClick={() => navigate(addClusterURL())} data-test-id="add-cluster-menu-item">
|
<MenuItem onClick={() => navigate(addClusterURL())} data-test-id="add-cluster-menu-item">
|
||||||
<Icon small material="add" /> Add Cluster
|
<Icon small material="add" /> Add Cluster
|
||||||
|
|||||||
@ -9,6 +9,8 @@
|
|||||||
border: 1px solid $borderColor;
|
border: 1px solid $borderColor;
|
||||||
z-index: 101;
|
z-index: 101;
|
||||||
|
|
||||||
|
// TODO: support predefined positions setup when rendered in document.body
|
||||||
|
// auto-positioning currently applied inside component on menu open
|
||||||
&.portal {
|
&.portal {
|
||||||
left: -1000px;
|
left: -1000px;
|
||||||
top: -1000px;
|
top: -1000px;
|
||||||
@ -22,23 +24,46 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// predefined positions without `usePortal` (default) where menu is rendered inside it's parent dom tree.
|
||||||
&:not(.portal) {
|
&:not(.portal) {
|
||||||
margin: $margin 0;
|
|
||||||
|
|
||||||
&.left {
|
&.left {
|
||||||
left: 0;
|
&-inside {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-outside {
|
||||||
|
right: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.right {
|
&.right {
|
||||||
right: 0;
|
&-inside {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-outside {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.top {
|
&.top {
|
||||||
bottom: 100%;
|
&-inside {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-outside {
|
||||||
|
bottom: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.bottom {
|
&.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 const MenuContext = React.createContext<MenuContextValue>(null);
|
||||||
export type MenuContextValue = Menu;
|
export type MenuContextValue = Menu;
|
||||||
|
export type MenuPositionSide = "inside" | "outside";
|
||||||
|
|
||||||
export interface MenuPosition {
|
export interface MenuPosition {
|
||||||
left?: boolean;
|
left?: MenuPositionSide;
|
||||||
top?: boolean;
|
top?: MenuPositionSide;
|
||||||
right?: boolean;
|
right?: MenuPositionSide;
|
||||||
bottom?: boolean;
|
bottom?: MenuPositionSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MenuProps {
|
export interface MenuProps {
|
||||||
@ -35,11 +36,16 @@ export interface MenuProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
position?: MenuPosition;
|
position?: {
|
||||||
|
left?: boolean;
|
||||||
|
top?: boolean;
|
||||||
|
right?: boolean;
|
||||||
|
bottom?: boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultPropsMenu: Partial<MenuProps> = {
|
const defaultPropsMenu: Partial<MenuProps> = {
|
||||||
position: { right: true, bottom: true },
|
position: { left: "inside", bottom: "outside" },
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
usePortal: false,
|
usePortal: false,
|
||||||
closeOnClickItem: true,
|
closeOnClickItem: true,
|
||||||
@ -137,7 +143,12 @@ export class Menu extends React.Component<MenuProps, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup initial position
|
// 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.left = `${left}px`;
|
||||||
this.elem.style.top = `${bottom}px`;
|
this.elem.style.top = `${bottom}px`;
|
||||||
@ -248,12 +259,14 @@ export class Menu extends React.Component<MenuProps, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { position, id } = this.props;
|
const { position = {}, id, className } = this.props;
|
||||||
let { className, usePortal } = this.props;
|
let { usePortal } = this.props;
|
||||||
|
|
||||||
className = cssNames("Menu", className, this.state.position || position, {
|
const positionClasses = usePortal
|
||||||
portal: 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>;
|
let children = this.props.children as ReactElement<any>;
|
||||||
|
|
||||||
@ -273,7 +286,7 @@ export class Menu extends React.Component<MenuProps, State> {
|
|||||||
const menu = (
|
const menu = (
|
||||||
<MenuContext.Provider value={this}>
|
<MenuContext.Provider value={this}>
|
||||||
<Animate enter={this.isOpen}>
|
<Animate enter={this.isOpen}>
|
||||||
<ul id={id} className={className} ref={this.bindRef}>
|
<ul id={id} className={classNames} ref={this.bindRef}>
|
||||||
{menuItems}
|
{menuItems}
|
||||||
</ul>
|
</ul>
|
||||||
</Animate>
|
</Animate>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user