Revert "Select: scroll into view when navigate with up/down arrows (#22503)" (#22535)

This reverts commit 75fe3c839b.
This commit is contained in:
Tobias Skarhed 2020-03-03 11:51:17 +01:00 committed by GitHub
parent e6cec8dbdc
commit 87da6a293b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 54 additions and 202 deletions

View File

@ -1,4 +1,4 @@
import React, { Component, RefObject } from 'react';
import React, { Component } from 'react';
import isNil from 'lodash/isNil';
import classNames from 'classnames';
import Scrollbars from 'react-custom-scrollbars';
@ -17,7 +17,6 @@ interface Props {
setScrollTop: (event: any) => void;
autoHeightMin?: number | string;
updateAfterMountMs?: number;
scrollRef?: RefObject<Scrollbars>;
}
/**
@ -38,7 +37,7 @@ export class CustomScrollbar extends Component<Props> {
constructor(props: Props) {
super(props);
this.ref = props.scrollRef || React.createRef<Scrollbars>();
this.ref = React.createRef<Scrollbars>();
}
updateScroll() {
@ -52,6 +51,7 @@ export class CustomScrollbar extends Component<Props> {
componentDidMount() {
this.updateScroll();
// this logic is to make scrollbar visible when content is added body after mount
if (this.props.updateAfterMountMs) {
setTimeout(() => this.updateAfterMount(), this.props.updateAfterMountMs);

View File

@ -24,7 +24,6 @@ import { SingleValue } from './SingleValue';
import { MultiValueContainer, MultiValueRemove } from './MultiValue';
import { useTheme } from '../../../themes';
import { getSelectStyles } from './getSelectStyles';
import { withSelectArrowNavigation } from '../../Select/withSelectArrowNavigation';
type SelectValue<T> = T | SelectableValue<T> | T[] | Array<SelectableValue<T>>;
@ -272,10 +271,10 @@ export function SelectBase<T>({
defaultOptions,
};
}
const NavigatableSelect = withSelectArrowNavigation(ReactSelectComponent);
return (
<>
<NavigatableSelect
<ReactSelectComponent
components={{
MenuList: SelectMenu,
Group: SelectOptionGroup,

View File

@ -1,35 +1,29 @@
import React, { RefObject, PropsWithChildren, forwardRef } from 'react';
import React from 'react';
import { useTheme } from '../../../themes/ThemeContext';
import { getSelectStyles } from './getSelectStyles';
import { cx } from 'emotion';
import { SelectableValue } from '@grafana/data';
import { Icon } from '../../Icon/Icon';
import { CustomScrollbar } from '../../CustomScrollbar/CustomScrollbar';
import { ExtendedOptionProps } from '../../Select/SelectOption';
import Scrollbars from 'react-custom-scrollbars';
interface SelectMenuProps {
maxHeight: number;
innerRef: React.Ref<any>;
innerProps: {};
scrollRef: RefObject<Scrollbars>;
}
export const SelectMenu = forwardRef<HTMLDivElement, PropsWithChildren<SelectMenuProps & ExtendedOptionProps>>(
(props, ref = props.innerRef) => {
const theme = useTheme();
const styles = getSelectStyles(theme);
const { children, maxHeight, innerProps, scrollRef } = props;
export const SelectMenu = React.forwardRef<HTMLDivElement, React.PropsWithChildren<SelectMenuProps>>((props, ref) => {
const theme = useTheme();
const styles = getSelectStyles(theme);
const { children, maxHeight, innerRef, innerProps } = props;
return (
<div {...innerProps} className={styles.menu} ref={ref} style={{ maxHeight }} aria-label="Select options menu">
<CustomScrollbar scrollRef={scrollRef} autoHide={false} autoHeightMax="inherit" hideHorizontalTrack>
{children}
</CustomScrollbar>
</div>
);
}
);
return (
<div {...innerProps} className={styles.menu} ref={innerRef} style={{ maxHeight }} aria-label="Select options menu">
<CustomScrollbar autoHide={false} autoHeightMax="inherit" hideHorizontalTrack>
{children}
</CustomScrollbar>
</div>
);
});
SelectMenu.displayName = 'SelectMenu';

View File

@ -27,8 +27,6 @@ import { PopoverContent } from '../Tooltip/Tooltip';
import { Tooltip } from '../Tooltip/Tooltip';
import { SelectableValue } from '@grafana/data';
import { withSelectArrowNavigation } from './withSelectArrowNavigation';
/**
* Changes in new selects:
* - noOptionsMessage & loadingMessage is of string type
@ -44,7 +42,7 @@ interface AsyncProps<T> extends LegacyCommonProps<T>, Omit<SelectAsyncProps<T>,
value?: SelectableValue<T>;
}
export interface LegacySelectProps<T> extends LegacyCommonProps<T> {
interface LegacySelectProps<T> extends LegacyCommonProps<T> {
tooltipContent?: PopoverContent;
noOptionsMessage?: () => string;
isDisabled?: boolean;
@ -54,7 +52,7 @@ export interface LegacySelectProps<T> extends LegacyCommonProps<T> {
export const MenuList = (props: any) => {
return (
<components.MenuList {...props}>
<CustomScrollbar scrollRef={props.scrollRef} autoHide={false} autoHeightMax="inherit">
<CustomScrollbar autoHide={false} autoHeightMax="inherit">
{props.children}
</CustomScrollbar>
</components.MenuList>
@ -127,7 +125,6 @@ export class Select<T> extends PureComponent<LegacySelectProps<T>> {
SelectComponent = Creatable;
creatableOptions.formatCreateLabel = formatCreateLabel ?? ((input: string) => input);
}
const NavigatableSelect = withSelectArrowNavigation(SelectComponent);
const selectClassNames = classNames('gf-form-input', 'gf-form-input--form-dropdown', widthClass, className);
const selectComponents = { ...Select.defaultProps.components, ...components };
@ -135,7 +132,7 @@ export class Select<T> extends PureComponent<LegacySelectProps<T>> {
<WrapInTooltip onCloseMenu={onCloseMenu} onOpenMenu={onOpenMenu} tooltipContent={tooltipContent} isOpen={isOpen}>
{(onOpenMenuInternal, onCloseMenuInternal) => {
return (
<NavigatableSelect
<SelectComponent
captureMenuScroll={false}
classNamePrefix="gf-form-select-box"
className={selectClassNames}
@ -173,8 +170,6 @@ export class Select<T> extends PureComponent<LegacySelectProps<T>> {
}
}
const NavigatableAsyncSelect = withSelectArrowNavigation(ReactAsyncSelect);
export class AsyncSelect<T> extends PureComponent<AsyncProps<T>> {
static defaultProps: Partial<AsyncProps<any>> = {
className: '',
@ -231,7 +226,7 @@ export class AsyncSelect<T> extends PureComponent<AsyncProps<T>> {
<WrapInTooltip onCloseMenu={onCloseMenu} onOpenMenu={onOpenMenu} tooltipContent={tooltipContent} isOpen={isOpen}>
{(onOpenMenuInternal, onCloseMenuInternal) => {
return (
<NavigatableAsyncSelect
<ReactAsyncSelect
captureMenuScroll={false}
classNamePrefix="gf-form-select-box"
className={selectClassNames}

View File

@ -1,4 +1,4 @@
import React, { forwardRef } from 'react';
import React from 'react';
// Ignoring because I couldn't get @types/react-select work wih Torkel's fork
// @ts-ignore
@ -13,10 +13,11 @@ export interface ExtendedOptionProps extends OptionProps<any> {
};
}
export const SelectOption = forwardRef((props: ExtendedOptionProps, ref) => {
export const SelectOption = (props: ExtendedOptionProps) => {
const { children, isSelected, data } = props;
return (
<components.Option {...props} innerRef={ref}>
<components.Option {...props}>
<div className="gf-form-select-box__desc-option">
{data.imgUrl && <img className="gf-form-select-box__desc-option__img" src={data.imgUrl} />}
<div className="gf-form-select-box__desc-option__body">
@ -27,6 +28,6 @@ export const SelectOption = forwardRef((props: ExtendedOptionProps, ref) => {
</div>
</components.Option>
);
});
};
export default SelectOption;

View File

@ -1,56 +0,0 @@
import React, { useRef, Component, createRef, RefObject, ComponentType, KeyboardEvent } from 'react';
import { ExtendedOptionProps } from './SelectOption';
const scrollIntoView = (optionRef: RefObject<HTMLElement> | null, scrollRef: RefObject<any>) => {
if (!optionRef || !optionRef.current || !scrollRef || !scrollRef.current || !scrollRef.current.container) {
return;
}
const { container, scrollTop } = scrollRef.current;
const option = optionRef.current;
const containerRect = container.getBoundingClientRect();
const optionRect = option.getBoundingClientRect();
if (optionRect.bottom > containerRect.bottom) {
scrollTop(option.offsetTop + option.clientHeight - container.offsetHeight);
} else if (optionRect.top < containerRect.top) {
scrollTop(option.offsetTop);
}
};
export const withSelectArrowNavigation = <P extends any>(WrappedComponent: ComponentType<P>) => {
return class Select extends Component<P> {
focusedOptionRef: RefObject<HTMLElement> | null = null;
scrollRef = createRef();
render() {
const { components } = this.props;
return (
<WrappedComponent
{...this.props}
components={{
...components,
MenuList: (props: ExtendedOptionProps) => {
return <components.MenuList {...props} scrollRef={this.scrollRef} />;
},
Option: (props: ExtendedOptionProps) => {
const innerRef = useRef<HTMLElement>(null);
if (props.isFocused) {
this.focusedOptionRef = innerRef;
}
return <components.Option {...props} ref={innerRef} />;
},
}}
onKeyDown={(e: KeyboardEvent) => {
const { onKeyDown } = this.props;
onKeyDown && onKeyDown(e);
if (e.keyCode === 38 || e.keyCode === 40) {
setTimeout(() => {
scrollIntoView(this.focusedOptionRef, this.scrollRef);
});
}
}}
/>
);
}
};
};

View File

@ -97,10 +97,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned off should not ren
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -190,10 +187,7 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}

View File

@ -31,10 +31,7 @@ exports[`Render should disable access key id field 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -141,10 +138,7 @@ exports[`Render should disable access key id field 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -217,10 +211,7 @@ exports[`Render should render component 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -327,10 +318,7 @@ exports[`Render should render component 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -403,10 +391,7 @@ exports[`Render should should show access key and secret access key fields 1`] =
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -513,10 +498,7 @@ exports[`Render should should show access key and secret access key fields 1`] =
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -589,10 +571,7 @@ exports[`Render should should show arn role field 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -699,10 +678,7 @@ exports[`Render should should show arn role field 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -775,10 +751,7 @@ exports[`Render should should show credentials profile name field 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -885,10 +858,7 @@ exports[`Render should should show credentials profile name field 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}

View File

@ -52,10 +52,7 @@ exports[`Render should disable log analytics credentials form 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -151,10 +148,7 @@ exports[`Render should enable azure log analytics load workspaces button 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -250,10 +244,7 @@ exports[`Render should render component 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}

View File

@ -27,10 +27,7 @@ exports[`Render should disable azure monitor secret input 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -176,10 +173,7 @@ exports[`Render should disable azure monitor secret input 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -250,10 +244,7 @@ exports[`Render should enable azure monitor load subscriptions button 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -389,10 +380,7 @@ exports[`Render should enable azure monitor load subscriptions button 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -463,10 +451,7 @@ exports[`Render should render component 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -602,10 +587,7 @@ exports[`Render should render component 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}

View File

@ -125,10 +125,7 @@ exports[`Render should disable basic auth password input 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -345,10 +342,7 @@ exports[`Render should hide basic auth fields when switch off 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -565,10 +559,7 @@ exports[`Render should hide white listed cookies input when browser access chose
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -785,10 +776,7 @@ exports[`Render should render component 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}

View File

@ -86,10 +86,7 @@ exports[`Render PromQueryEditor with basic options should render 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}
@ -156,10 +153,7 @@ exports[`Render PromQueryEditor with basic options should render 1`] = `
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": Object {
"$$typeof": Symbol(react.forward_ref),
"render": [Function],
},
"Option": [Function],
"SingleValue": [Function],
}
}