mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Enable custom picers on color color picker popovers (for y-axis support in legend picker)
This commit is contained in:
parent
40dc29d135
commit
8d8f944a1f
@ -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',
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
@ -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>
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user