Enable custom picers on color color picker popovers (for y-axis support in legend picker)

This commit is contained in:
Dominik Prokop 2019-01-24 13:18:21 +01:00
parent 40dc29d135
commit 8d8f944a1f
3 changed files with 98 additions and 42 deletions

View File

@ -9,15 +9,10 @@ import propDeprecationWarning from '../../utils/propDeprecationWarning';
type ColorPickerChangeHandler = (color: string) => void;
export const handleColorPickerPropsDeprecation = (componentName: string, props: ColorPickerProps) => {
const { onColorChange } = props;
if (onColorChange) {
propDeprecationWarning(componentName, 'onColorChange', 'onChange');
}
};
export interface ColorPickerProps extends Themeable {
color: string;
onChange: ColorPickerChangeHandler;
/**
* @deprecated Use onChange instead
*/
@ -27,6 +22,13 @@ export interface ColorPickerProps extends Themeable {
children?: JSX.Element;
}
export const handleColorPickerPropsDeprecation = (componentName: string, props: ColorPickerProps) => {
const { onColorChange } = props;
if (onColorChange) {
propDeprecationWarning(componentName, 'onColorChange', 'onChange');
}
};
export const colorPickerFactory = <T extends ColorPickerProps>(
popover: React.ComponentType<T>,
displayName = 'ColorPicker',

View File

@ -2,20 +2,28 @@ import React from 'react';
import { NamedColorsPalette } from './NamedColorsPalette';
import { getColorName, getColorFromHexRgbOrName } from '../../utils/namedColorsPalette';
import { ColorPickerProps, handleColorPickerPropsDeprecation } from './ColorPicker';
import { GrafanaTheme, Themeable } from '../../types';
import { GrafanaTheme } from '../../types';
import { PopperContentProps } from '../Tooltip/PopperController';
import SpectrumPalette from './SpectrumPalette';
export interface Props extends ColorPickerProps, Themeable, PopperContentProps {}
export interface Props<T> extends ColorPickerProps, PopperContentProps {
customPickers?: T;
}
type PickerType = 'palette' | 'spectrum';
interface State {
activePicker: PickerType;
interface CustomPickersDescriptor {
[key: string]: {
tabComponent: React.ComponentType<ColorPickerProps>;
name: string;
};
}
interface State<T> {
activePicker: PickerType | keyof T;
}
export class ColorPickerPopover extends React.Component<Props, State> {
constructor(props: Props) {
export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React.Component<Props<T>, State<T>> {
constructor(props: Props<T>) {
super(props);
this.state = {
activePicker: 'palette',
@ -23,6 +31,11 @@ export class ColorPickerPopover extends React.Component<Props, State> {
handleColorPickerPropsDeprecation('ColorPickerPopover', props);
}
getTabClassName = (tabName: PickerType | keyof T) => {
const { activePicker } = this.state;
return `ColorPickerPopover__tab ${activePicker === tabName && 'ColorPickerPopover__tab--active'}`;
};
handleChange = (color: any) => {
const { onColorChange, onChange, enableNamedColors } = this.props;
const changeHandler = onColorChange || onChange;
@ -33,55 +46,89 @@ export class ColorPickerPopover extends React.Component<Props, State> {
changeHandler(getColorFromHexRgbOrName(color));
};
handleTabChange = (tab: PickerType | keyof T, updatePopperPosition?: () => void) => {
return () =>
this.setState({ activePicker: tab }, () => {
if (updatePopperPosition) {
updatePopperPosition();
}
});
};
renderPicker = () => {
const { activePicker } = this.state;
const { color, theme } = this.props;
return activePicker === 'spectrum' ? (
<SpectrumPalette color={color} onChange={this.handleChange} theme={theme} />
) : (
<NamedColorsPalette color={getColorName(color, theme)} onChange={this.handleChange} theme={theme} />
switch (activePicker) {
case 'spectrum':
return <SpectrumPalette color={color} onChange={this.handleChange} theme={theme} />;
case 'palette':
return <NamedColorsPalette color={getColorName(color, theme)} onChange={this.handleChange} theme={theme} />;
default:
return this.renderCustomPicker(activePicker);
}
};
renderCustomPicker = (tabKey: keyof T) => {
const { customPickers, color, theme } = this.props;
if (!customPickers) {
return null;
}
return React.createElement(customPickers[tabKey].tabComponent, {
color,
theme,
onChange: this.handleChange,
});
};
renderCustomPickerTabs = (updatePopperPosition?: () => void) => {
const { customPickers } = this.props;
if (!customPickers) {
return null;
}
return (
<>
{Object.keys(customPickers).map(key => {
return (
<div
className={this.getTabClassName(key)}
onClick={this.handleTabChange(key, updatePopperPosition)}
key={key}
>
{customPickers[key].name}
</div>
);
})}
</>
);
};
render() {
const { activePicker } = this.state;
const { theme, children, updatePopperPosition } = this.props;
const { theme, updatePopperPosition } = this.props;
const colorPickerTheme = theme || GrafanaTheme.Dark;
return (
<div className={`ColorPickerPopover ColorPickerPopover--${colorPickerTheme}`}>
<div className="ColorPickerPopover__tabs">
<div
className={`ColorPickerPopover__tab ${activePicker === 'palette' && 'ColorPickerPopover__tab--active'}`}
onClick={() => {
this.setState({ activePicker: 'palette' }, () => {
if (updatePopperPosition) {
updatePopperPosition();
}
});
}}
className={this.getTabClassName('palette')}
onClick={this.handleTabChange('palette', updatePopperPosition)}
>
Default
Colors
</div>
<div
className={`ColorPickerPopover__tab ${activePicker === 'spectrum' && 'ColorPickerPopover__tab--active'}`}
onClick={() => {
this.setState({ activePicker: 'spectrum' }, () => {
if (updatePopperPosition) {
updatePopperPosition();
}
});
}}
className={this.getTabClassName('spectrum')}
onClick={this.handleTabChange('spectrum', updatePopperPosition)}
>
Custom
</div>
{this.renderCustomPickerTabs(updatePopperPosition)}
</div>
<div className="ColorPickerPopover__content">
{this.renderPicker()}
{children}
</div>
<div className="ColorPickerPopover__content">{this.renderPicker()}</div>
</div>
);
}

View File

@ -13,9 +13,16 @@ export const SeriesColorPickerPopover: FunctionComponent<SeriesColorPickerPopove
const { yaxis, onToggleAxis, color, ...colorPickerProps } = props;
return (
<ColorPickerPopover color={color || '#000000'} {...colorPickerProps}>
<div style={{ marginTop: '32px' }}>{yaxis && <AxisSelector yaxis={yaxis} onToggleAxis={onToggleAxis} />}</div>
</ColorPickerPopover>
<ColorPickerPopover
{...colorPickerProps}
color={color || '#000000'}
customPickers={{
yaxis: {
name: 'Y-Axis',
tabComponent: () => <div style={{ marginTop: '24px' }}>{yaxis && <AxisSelector yaxis={yaxis} onToggleAxis={onToggleAxis} />}</div>
},
}}
/>
);
};