1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Remove shouldComponentUpdate, put style to state

instead of straight to DOM so they will be in sync

Signed-off-by: Juho Heikka <juho.heikka@gmail.com>
This commit is contained in:
Juho Heikka 2021-09-27 17:03:27 +03:00
parent 2e1b3ea70c
commit b70ec5ddbd

View File

@ -38,6 +38,10 @@ export interface MenuPosition {
bottom?: boolean;
}
export interface MenuStyle {
top: string;
left: string;
}
export interface MenuProps {
isOpen?: boolean;
open(): void;
@ -57,6 +61,7 @@ export interface MenuProps {
interface State {
position?: MenuPosition;
menuStyle?: MenuStyle
}
const defaultPropsMenu: Partial<MenuProps> = {
@ -76,7 +81,6 @@ export class Menu extends React.Component<MenuProps, State> {
super(props);
autoBind(this);
}
public opener: HTMLElement;
public elem: HTMLUListElement;
protected items: { [index: number]: MenuItem } = {};
@ -86,10 +90,6 @@ export class Menu extends React.Component<MenuProps, State> {
return !!this.props.isOpen;
}
shouldComponentUpdate(nextProps: MenuProps, nextState: State) {
return !isEqual(nextState, this.state) || !isEqual(nextProps, this.props);
}
componentDidMount() {
if (!this.props.usePortal) {
const parent = this.elem.parentElement;
@ -124,6 +124,12 @@ export class Menu extends React.Component<MenuProps, State> {
window.removeEventListener("scroll", this.onScrollOutside, true);
}
componentDidUpdate(prevProps: MenuProps) {
if (!isEqual(prevProps.children, this.props.children)) {
this.refreshPosition();
}
}
protected get focusableItems() {
return Object.values(this.items).filter(item => item.isFocusable);
}
@ -176,21 +182,23 @@ export class Menu extends React.Component<MenuProps, State> {
const menuOnLeftSidePosition = `${openerRight - this.elem.offsetWidth}px`;
const menuOnRightSidePosition = `${openerLeft}px`;
this.elem.style.left = renderMenuLeft ? menuOnLeftSidePosition : menuOnRightSidePosition;
const bottomOfMenu = openerBottom + extraMargin + menuHeight;
const renderMenuOnTop = bottomOfMenu > window.innerHeight;
const menuOnTopPosition = `${openerTop - this.elem.offsetHeight - extraMargin}px`;
const menuOnBottomPosition = `${openerBottom + extraMargin}px`;
this.elem.style.top = renderMenuOnTop ? menuOnTopPosition : menuOnBottomPosition;
this.setState({ position: {
top: renderMenuOnTop,
bottom: !renderMenuOnTop,
left: renderMenuLeft,
right: !renderMenuLeft
} });
this.setState({
position: {
top: renderMenuOnTop,
bottom: !renderMenuOnTop,
left: renderMenuLeft,
right: !renderMenuLeft
},
menuStyle: {
top: renderMenuOnTop ? menuOnTopPosition : menuOnBottomPosition,
left: renderMenuLeft ? menuOnLeftSidePosition : menuOnRightSidePosition,
}
});
};
open() {
@ -284,10 +292,6 @@ export class Menu extends React.Component<MenuProps, State> {
}
render() {
if (this.isOpen) {
setImmediate(() => this.refreshPosition());
}
const { position, id } = this.props;
let { className, usePortal } = this.props;
@ -313,7 +317,15 @@ 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}
ref={this.bindRef}
className={className}
style={{
left: this.state?.menuStyle?.left,
top: this.state?.menuStyle?.top
}}
>
{menuItems}
</ul>
</Animate>