diff options
Diffstat (limited to 'packages')
-rw-r--r-- | packages/website/ts/components/ui/drop_down.tsx | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 752c92e02..4d5caef08 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -25,7 +25,6 @@ export interface DropDownProps { interface DropDownState { isDropDownOpen: boolean; - isHovering: boolean; anchorEl?: HTMLInputElement; } @@ -36,21 +35,11 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> { activateEvent: DropdownMouseEvent.Hover, closeEvent: DropdownMouseEvent.Hover, }; + private _isHovering: boolean; private _popoverCloseCheckIntervalId: number; - public static getDerivedStateFromProps(props: DropDownProps, state: DropDownState): Partial<DropDownState> { - switch (props.activateEvent) { - case DropdownMouseEvent.Click: - return { isDropDownOpen: state.isDropDownOpen }; - case DropdownMouseEvent.Hover: - return { isDropDownOpen: state.isHovering }; - default: - return {}; - } - } constructor(props: DropDownProps) { super(props); this.state = { - isHovering: false, isDropDownOpen: false, }; } @@ -62,6 +51,15 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> { public componentWillUnmount(): void { window.clearInterval(this._popoverCloseCheckIntervalId); } + public componentWillReceiveProps(_nextProps: DropDownProps): void { + // HACK: If the popoverContent is updated to a different dimension and the users + // mouse is no longer above it, the dropdown can enter an inconsistent state where + // it believes the user is still hovering over it. In order to remedy this, we + // call hoverOff whenever the dropdown receives updated props. This is a hack + // because it will effectively close the dropdown on any prop update, barring + // dropdowns from having dynamic content. + this._onHoverOff(); + } public render(): React.ReactNode { return ( <div @@ -100,16 +98,28 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> { } } private _onHover(event: React.FormEvent<HTMLInputElement>): void { - this.setState({ isHovering: true }); + this._isHovering = true; + if (this.props.activateEvent === DropdownMouseEvent.Hover) { + this._checkIfShouldOpenPopover(event); + } } private _onHoverOff(): void { - this.setState({ isHovering: false }); + this._isHovering = false; + } + private _checkIfShouldOpenPopover(event: React.FormEvent<HTMLInputElement>): void { + if (this.state.isDropDownOpen) { + return; // noop + } + this.setState({ + isDropDownOpen: true, + anchorEl: event.currentTarget, + }); } private _checkIfShouldClosePopover(): void { if (!this.state.isDropDownOpen) { return; // noop } - if (this.props.closeEvent === DropdownMouseEvent.Hover && !this.state.isHovering) { + if (this.props.closeEvent === DropdownMouseEvent.Hover && !this._isHovering) { this._closePopover(); } } |