Merge pull request #5957 from influxdata/fix/dropdown_anchor_follow
fix(ui): optimize dropdown menu to avoid items re-renderingpull/5965/head
commit
42e4b72025
|
@ -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 ? (
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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 && (
|
||||
|
|
|
@ -69,7 +69,6 @@ $dropdown-purple-header: $c-potassium;
|
|||
&-340 .dropdown-toggle {width: 340px;}
|
||||
}
|
||||
|
||||
.dropdown:focus,
|
||||
.dropdown.open,
|
||||
.dropdown.open:focus {
|
||||
outline: none;
|
||||
|
|
Loading…
Reference in New Issue