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