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,8 +78,12 @@ export class Dropdown extends Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleHighlight = (itemIndex: number) => () => {
|
public handleHighlight = (itemIndex: number) => () => {
|
||||||
|
// setup highlighted element only in auto-complete mode,
|
||||||
|
// otherwise rely upon CSS :hover highlighting
|
||||||
|
if (this.props.useAutoComplete) {
|
||||||
this.setState({highlightedItemIndex: itemIndex})
|
this.setState({highlightedItemIndex: itemIndex})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public toggleMenu = (e?: MouseEvent<HTMLDivElement>) => {
|
public toggleMenu = (e?: MouseEvent<HTMLDivElement>) => {
|
||||||
if (e) {
|
if (e) {
|
||||||
|
@ -158,6 +162,10 @@ export class Dropdown extends Component<Props, State> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setDropdownRef = (ref: any) => {
|
||||||
|
this.dropdownRef = ref
|
||||||
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {
|
const {
|
||||||
items,
|
items,
|
||||||
|
@ -188,7 +196,7 @@ export class Dropdown extends Component<Props, State> {
|
||||||
[className]: className,
|
[className]: className,
|
||||||
})}
|
})}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
ref={r => (this.dropdownRef = r)}
|
ref={this.setDropdownRef}
|
||||||
data-test="dropdown-toggle"
|
data-test="dropdown-toggle"
|
||||||
>
|
>
|
||||||
{useAutoComplete && isOpen ? (
|
{useAutoComplete && isOpen ? (
|
||||||
|
|
|
@ -108,7 +108,11 @@ const DropdownMenu: FunctionComponent<Props> = ({
|
||||||
autoHeight={true}
|
autoHeight={true}
|
||||||
maxHeight={DROPDOWN_MENU_MAX_HEIGHT}
|
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) => (
|
{items.map((item, i) => (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
item={item}
|
item={item}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, {FunctionComponent, MouseEvent} from 'react'
|
import React, {MouseEvent, useCallback} from 'react'
|
||||||
|
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
@ -28,7 +28,7 @@ interface ItemProps {
|
||||||
onAction?: OnActionHandler
|
onAction?: OnActionHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
const DropdownMenuItem: FunctionComponent<ItemProps> = ({
|
const DropdownMenuItem = ({
|
||||||
item,
|
item,
|
||||||
highlightedItemIndex,
|
highlightedItemIndex,
|
||||||
onSelection,
|
onSelection,
|
||||||
|
@ -37,7 +37,7 @@ const DropdownMenuItem: FunctionComponent<ItemProps> = ({
|
||||||
onAction,
|
onAction,
|
||||||
selected,
|
selected,
|
||||||
index,
|
index,
|
||||||
}) => {
|
}: ItemProps) => {
|
||||||
if (_.isString(item)) {
|
if (_.isString(item)) {
|
||||||
item = {text: item}
|
item = {text: item}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,14 @@ const DropdownMenuItem: FunctionComponent<ItemProps> = ({
|
||||||
return <li className="dropdown-divider" />
|
return <li className="dropdown-divider" />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onClick = useCallback(
|
||||||
|
(e: MouseEvent<HTMLAnchorElement>) => {
|
||||||
|
e.preventDefault()
|
||||||
|
onSelection(item)(e)
|
||||||
|
},
|
||||||
|
[item]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className={classnames('dropdown-item', {
|
className={classnames('dropdown-item', {
|
||||||
|
@ -54,7 +62,7 @@ const DropdownMenuItem: FunctionComponent<ItemProps> = ({
|
||||||
})}
|
})}
|
||||||
data-test={`${item.text}-dropdown-item`}
|
data-test={`${item.text}-dropdown-item`}
|
||||||
>
|
>
|
||||||
<a href="#" onClick={onSelection(item)} onMouseOver={onHighlight(index)}>
|
<a href="#" onClick={onClick} onMouseOver={onHighlight(index)}>
|
||||||
{item.text}
|
{item.text}
|
||||||
</a>
|
</a>
|
||||||
{actions && !!actions.length && (
|
{actions && !!actions.length && (
|
||||||
|
|
|
@ -69,7 +69,6 @@ $dropdown-purple-header: $c-potassium;
|
||||||
&-340 .dropdown-toggle {width: 340px;}
|
&-340 .dropdown-toggle {width: 340px;}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown:focus,
|
|
||||||
.dropdown.open,
|
.dropdown.open,
|
||||||
.dropdown.open:focus {
|
.dropdown.open:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
Loading…
Reference in New Issue