Commit a0da303f by Johannes Schill

Change KeyboardNavigation from hoc to render prop component

parent 07ce88f6
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import _ from 'lodash'; import _ from 'lodash';
import withKeyboardNavigation, { KeyboardNavigationProps } from './withKeyboardNavigation'; import KeyboardNavigation, { KeyboardNavigationProps } from './KeyboardNavigation';
import { DataSourceSelectItem } from 'app/types'; import { DataSourceSelectItem } from 'app/types';
export interface Props { export interface Props {
...@@ -13,8 +13,7 @@ interface State { ...@@ -13,8 +13,7 @@ interface State {
searchQuery: string; searchQuery: string;
} }
export const DataSourcePicker = withKeyboardNavigation( export class DataSourcePicker extends PureComponent<Props, State> {
class DataSourcePicker extends PureComponent<Props & KeyboardNavigationProps, State> {
searchInput: HTMLElement; searchInput: HTMLElement;
constructor(props) { constructor(props) {
...@@ -41,8 +40,9 @@ export const DataSourcePicker = withKeyboardNavigation( ...@@ -41,8 +40,9 @@ export const DataSourcePicker = withKeyboardNavigation(
return filtered.length - 1; return filtered.length - 1;
} }
renderDataSource = (ds: DataSourceSelectItem, index: number) => { renderDataSource = (ds: DataSourceSelectItem, index: number, keyNavProps: KeyboardNavigationProps) => {
const { onChangeDataSource, selected, onMouseEnter } = this.props; const { onChangeDataSource } = this.props;
const { selected, onMouseEnter } = keyNavProps;
const onClick = () => onChangeDataSource(ds); const onClick = () => onChangeDataSource(ds);
const isSelected = selected === index; const isSelected = selected === index;
const cssClass = classNames({ const cssClass = classNames({
...@@ -50,13 +50,7 @@ export const DataSourcePicker = withKeyboardNavigation( ...@@ -50,13 +50,7 @@ export const DataSourcePicker = withKeyboardNavigation(
'ds-picker-list__item--selected': isSelected, 'ds-picker-list__item--selected': isSelected,
}); });
return ( return (
<div <div key={index} className={cssClass} title={ds.name} onClick={onClick} onMouseEnter={() => onMouseEnter(index)}>
key={index}
className={cssClass}
title={ds.name}
onClick={onClick}
onMouseEnter={() => onMouseEnter(index)}
>
<img className="ds-picker-list__img" src={ds.meta.info.logos.small} /> <img className="ds-picker-list__img" src={ds.meta.info.logos.small} />
<div className="ds-picker-list__name">{ds.name}</div> <div className="ds-picker-list__name">{ds.name}</div>
</div> </div>
...@@ -77,11 +71,9 @@ export const DataSourcePicker = withKeyboardNavigation( ...@@ -77,11 +71,9 @@ export const DataSourcePicker = withKeyboardNavigation(
})); }));
}; };
renderFilters() { renderFilters({ onKeyDown, selected }: KeyboardNavigationProps) {
const { searchQuery } = this.state; const { searchQuery } = this.state;
const { onKeyDown } = this.props;
return ( return (
<>
<label className="gf-form--has-input-icon"> <label className="gf-form--has-input-icon">
<input <input
type="text" type="text"
...@@ -92,7 +84,7 @@ export const DataSourcePicker = withKeyboardNavigation( ...@@ -92,7 +84,7 @@ export const DataSourcePicker = withKeyboardNavigation(
value={searchQuery} value={searchQuery}
onKeyDown={evt => { onKeyDown={evt => {
onKeyDown(evt, this.maxSelectedIndex, () => { onKeyDown(evt, this.maxSelectedIndex, () => {
const { onChangeDataSource, selected } = this.props; const { onChangeDataSource } = this.props;
const ds = this.getDataSources()[selected]; const ds = this.getDataSources()[selected];
onChangeDataSource(ds); onChangeDataSource(ds);
}); });
...@@ -100,22 +92,26 @@ export const DataSourcePicker = withKeyboardNavigation( ...@@ -100,22 +92,26 @@ export const DataSourcePicker = withKeyboardNavigation(
/> />
<i className="gf-form-input-icon fa fa-search" /> <i className="gf-form-input-icon fa fa-search" />
</label> </label>
</>
); );
} }
render() { render() {
return ( return (
<KeyboardNavigation
render={(keyNavProps: KeyboardNavigationProps) => (
<> <>
<div className="cta-form__bar"> <div className="cta-form__bar">
{this.renderFilters()} {this.renderFilters(keyNavProps)}
<div className="gf-form--grow" /> <div className="gf-form--grow" />
</div> </div>
<div className="ds-picker-list">{this.getDataSources().map(this.renderDataSource)}</div> <div className="ds-picker-list">
{this.getDataSources().map((ds, index) => this.renderDataSource(ds, index, keyNavProps))}
</div>
</> </>
)}
/>
); );
} }
} }
);
export default DataSourcePicker; export default DataSourcePicker;
import React, { KeyboardEvent, ComponentType, Component } from 'react'; import React, { KeyboardEvent, Component } from 'react';
interface State { interface State {
selected: number; selected: number;
...@@ -10,8 +10,11 @@ export interface KeyboardNavigationProps { ...@@ -10,8 +10,11 @@ export interface KeyboardNavigationProps {
selected: number; selected: number;
} }
const withKeyboardNavigation = <P extends object>(WrappedComponent: ComponentType<P & KeyboardNavigationProps>) => { interface Props {
return class WithKeyboardNavigation extends Component<P, State> { render: (injectProps: any) => void;
}
class KeyboardNavigation extends Component<Props, State> {
constructor(props) { constructor(props) {
super(props); super(props);
...@@ -55,11 +58,14 @@ const withKeyboardNavigation = <P extends object>(WrappedComponent: ComponentTyp ...@@ -55,11 +58,14 @@ const withKeyboardNavigation = <P extends object>(WrappedComponent: ComponentTyp
}; };
render() { render() {
return ( const injectProps = {
<WrappedComponent {...this.state} {...this.props} onKeyDown={this.onKeyDown} onMouseEnter={this.onMouseEnter} /> onKeyDown: this.onKeyDown,
); onMouseEnter: this.onMouseEnter,
} selected: this.state.selected,
}; };
};
export default withKeyboardNavigation; return <>{this.props.render({ ...injectProps })}</>;
}
}
export default KeyboardNavigation;
...@@ -4,7 +4,7 @@ import _ from 'lodash'; ...@@ -4,7 +4,7 @@ import _ from 'lodash';
import config from 'app/core/config'; import config from 'app/core/config';
import { PanelPlugin } from 'app/types/plugins'; import { PanelPlugin } from 'app/types/plugins';
import VizTypePickerPlugin from './VizTypePickerPlugin'; import VizTypePickerPlugin from './VizTypePickerPlugin';
import withKeyboardNavigation, { KeyboardNavigationProps } from './withKeyboardNavigation'; import KeyboardNavigation, { KeyboardNavigationProps } from './KeyboardNavigation';
export interface Props { export interface Props {
current: PanelPlugin; current: PanelPlugin;
...@@ -15,8 +15,7 @@ interface State { ...@@ -15,8 +15,7 @@ interface State {
searchQuery: string; searchQuery: string;
} }
export const VizTypePicker = withKeyboardNavigation( export class VizTypePicker extends PureComponent<Props, State> {
class VizTypePicker extends PureComponent<Props & KeyboardNavigationProps, State> {
searchInput: HTMLElement; searchInput: HTMLElement;
pluginList = this.getPanelPlugins(''); pluginList = this.getPanelPlugins('');
...@@ -49,8 +48,9 @@ export const VizTypePicker = withKeyboardNavigation( ...@@ -49,8 +48,9 @@ export const VizTypePicker = withKeyboardNavigation(
return _.sortBy(panels, 'sort'); return _.sortBy(panels, 'sort');
} }
renderVizPlugin = (plugin: PanelPlugin, index: number) => { renderVizPlugin = (plugin: PanelPlugin, index: number, keyNavProps: KeyboardNavigationProps) => {
const { onTypeChanged, selected, onMouseEnter } = this.props; const { onTypeChanged } = this.props;
const { selected, onMouseEnter } = keyNavProps;
const isSelected = selected === index; const isSelected = selected === index;
const isCurrent = plugin.id === this.props.current.id; const isCurrent = plugin.id === this.props.current.id;
return ( return (
...@@ -87,9 +87,8 @@ export const VizTypePicker = withKeyboardNavigation( ...@@ -87,9 +87,8 @@ export const VizTypePicker = withKeyboardNavigation(
})); }));
}; };
renderFilters = () => { renderFilters = ({ onKeyDown, selected }: KeyboardNavigationProps) => {
const { searchQuery } = this.state; const { searchQuery } = this.state;
const { onKeyDown } = this.props;
return ( return (
<> <>
<label className="gf-form--has-input-icon"> <label className="gf-form--has-input-icon">
...@@ -100,10 +99,9 @@ export const VizTypePicker = withKeyboardNavigation( ...@@ -100,10 +99,9 @@ export const VizTypePicker = withKeyboardNavigation(
ref={elem => (this.searchInput = elem)} ref={elem => (this.searchInput = elem)}
onChange={this.onSearchQueryChange} onChange={this.onSearchQueryChange}
value={searchQuery} value={searchQuery}
// onKeyDown={this.props.onKeyDown}
onKeyDown={evt => { onKeyDown={evt => {
onKeyDown(evt, this.maxSelectedIndex, () => { onKeyDown(evt, this.maxSelectedIndex, () => {
const { onTypeChanged, selected } = this.props; const { onTypeChanged } = this.props;
const vizType = this.getFilteredPluginList()[selected]; const vizType = this.getFilteredPluginList()[selected];
onTypeChanged(vizType); onTypeChanged(vizType);
}); });
...@@ -119,14 +117,19 @@ export const VizTypePicker = withKeyboardNavigation( ...@@ -119,14 +117,19 @@ export const VizTypePicker = withKeyboardNavigation(
const filteredPluginList = this.getFilteredPluginList(); const filteredPluginList = this.getFilteredPluginList();
return ( return (
<KeyboardNavigation
render={(keyNavProps: KeyboardNavigationProps) => (
<> <>
<div className="cta-form__bar"> <div className="cta-form__bar">
{this.renderFilters()} {this.renderFilters(keyNavProps)}
<div className="gf-form--grow" /> <div className="gf-form--grow" />
</div> </div>
<div className="viz-picker">{filteredPluginList.map(this.renderVizPlugin)}</div> <div className="viz-picker">
{filteredPluginList.map((plugin, index) => this.renderVizPlugin(plugin, index, keyNavProps))}
</div>
</> </>
)}
/>
); );
} }
} }
);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment