Merge pull request #5957 from influxdata/fix/dropdown_anchor_follow

fix(ui): optimize dropdown menu to avoid items re-rendering
pull/5965/head
Pavel Závora 2022-06-24 05:52:59 +02:00 committed by GitHub
commit 42e4b72025
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 8 deletions

View File

@ -78,7 +78,11 @@ export class Dropdown extends Component<Props, State> {
}
public handleHighlight = (itemIndex: number) => () => {
this.setState({highlightedItemIndex: itemIndex})
// setup highlighted element only in auto-complete mode,
// otherwise rely upon CSS :hover highlighting
if (this.props.useAutoComplete) {
this.setState({highlightedItemIndex: itemIndex})
}
}
public toggleMenu = (e?: MouseEvent<HTMLDivElement>) => {
@ -158,6 +162,10 @@ export class Dropdown extends Component<Props, State> {
})
}
private setDropdownRef = (ref: any) => {
this.dropdownRef = ref
}
public render() {
const {
items,
@ -188,7 +196,7 @@ export class Dropdown extends Component<Props, State> {
[className]: className,
})}
tabIndex={tabIndex}
ref={r => (this.dropdownRef = r)}
ref={this.setDropdownRef}
data-test="dropdown-toggle"
>
{useAutoComplete && isOpen ? (

View File

@ -108,7 +108,11 @@ const DropdownMenu: FunctionComponent<Props> = ({
autoHeight={true}
maxHeight={DROPDOWN_MENU_MAX_HEIGHT}
>
{menuLabel ? <li className="dropdown-header">{menuLabel}</li> : null}
{menuLabel ? (
<li className="dropdown-header" key="header">
{menuLabel}
</li>
) : null}
{items.map((item, i) => (
<DropdownMenuItem
item={item}

View File

@ -1,4 +1,4 @@
import React, {FunctionComponent, MouseEvent} from 'react'
import React, {MouseEvent, useCallback} from 'react'
import _ from 'lodash'
import classnames from 'classnames'
@ -28,7 +28,7 @@ interface ItemProps {
onAction?: OnActionHandler
}
const DropdownMenuItem: FunctionComponent<ItemProps> = ({
const DropdownMenuItem = ({
item,
highlightedItemIndex,
onSelection,
@ -37,7 +37,7 @@ const DropdownMenuItem: FunctionComponent<ItemProps> = ({
onAction,
selected,
index,
}) => {
}: ItemProps) => {
if (_.isString(item)) {
item = {text: item}
}
@ -46,6 +46,14 @@ const DropdownMenuItem: FunctionComponent<ItemProps> = ({
return <li className="dropdown-divider" />
}
const onClick = useCallback(
(e: MouseEvent<HTMLAnchorElement>) => {
e.preventDefault()
onSelection(item)(e)
},
[item]
)
return (
<li
className={classnames('dropdown-item', {
@ -54,7 +62,7 @@ const DropdownMenuItem: FunctionComponent<ItemProps> = ({
})}
data-test={`${item.text}-dropdown-item`}
>
<a href="#" onClick={onSelection(item)} onMouseOver={onHighlight(index)}>
<a href="#" onClick={onClick} onMouseOver={onHighlight(index)}>
{item.text}
</a>
{actions && !!actions.length && (

View File

@ -69,7 +69,6 @@ $dropdown-purple-header: $c-potassium;
&-340 .dropdown-toggle {width: 340px;}
}
.dropdown:focus,
.dropdown.open,
.dropdown.open:focus {
outline: none;