Commit 6b1390b9 by Dominik Prokop

Update types and themes usage in components

parent 1bc007e2
......@@ -2,11 +2,11 @@ import React, { Component, createRef } from 'react';
import PopperController from '../Tooltip/PopperController';
import Popper, { RenderPopperArrowFn } from '../Tooltip/Popper';
import { ColorPickerPopover } from './ColorPickerPopover';
import { Themeable, GrafanaTheme } from '../../types';
import { GrafanaThemeType, Themeable } from '../../types';
import { getColorFromHexRgbOrName } from '../../utils/namedColorsPalette';
import { SeriesColorPickerPopover } from './SeriesColorPickerPopover';
import propDeprecationWarning from '../../utils/propDeprecationWarning';
import { withTheme } from '../../themes/ThemeContext';
type ColorPickerChangeHandler = (color: string) => void;
export interface ColorPickerProps extends Themeable {
......@@ -57,7 +57,7 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
<div
{...arrowProps}
data-placement={placement}
className={`ColorPicker__arrow ColorPicker__arrow--${theme === GrafanaTheme.Light ? 'light' : 'dark'}`}
className={`ColorPicker__arrow ColorPicker__arrow--${theme.type === GrafanaThemeType.Light ? 'light' : 'dark'}`}
/>
);
};
......@@ -95,7 +95,7 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
<div
className="sp-preview-inner"
style={{
backgroundColor: getColorFromHexRgbOrName(this.props.color || '#000000', theme),
backgroundColor: getColorFromHexRgbOrName(this.props.color || '#000000', theme.type),
}}
/>
</div>
......@@ -110,5 +110,5 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
};
};
export const ColorPicker = colorPickerFactory(ColorPickerPopover, 'ColorPicker');
export const SeriesColorPicker = colorPickerFactory(SeriesColorPickerPopover, 'SeriesColorPicker');
export const ColorPicker = withTheme(colorPickerFactory(ColorPickerPopover, 'ColorPicker'));
export const SeriesColorPicker = withTheme(colorPickerFactory(SeriesColorPickerPopover, 'SeriesColorPicker'));
......@@ -4,7 +4,8 @@ import { ColorPickerPopover } from './ColorPickerPopover';
import { getColorDefinitionByName, getNamedColorPalette } from '../../utils/namedColorsPalette';
import { ColorSwatch } from './NamedColorsGroup';
import { flatten } from 'lodash';
import { GrafanaTheme } from '../../types';
import { GrafanaThemeType } from '../../types';
import { getTheme } from '../../themes';
const allColors = flatten(Array.from(getNamedColorPalette().values()));
......@@ -14,7 +15,7 @@ describe('ColorPickerPopover', () => {
describe('rendering', () => {
it('should render provided color as selected if color provided by name', () => {
const wrapper = mount(<ColorPickerPopover color={BasicGreen.name} onChange={() => {}} />);
const wrapper = mount(<ColorPickerPopover color={BasicGreen.name} onChange={() => {}} theme={getTheme()}/>);
const selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name);
const notSelectedSwatches = wrapper.find(ColorSwatch).filterWhere(node => node.prop('isSelected') === false);
......@@ -24,7 +25,7 @@ describe('ColorPickerPopover', () => {
});
it('should render provided color as selected if color provided by hex', () => {
const wrapper = mount(<ColorPickerPopover color={BasicGreen.variants.dark} onChange={() => {}} />);
const wrapper = mount(<ColorPickerPopover color={BasicGreen.variants.dark} onChange={() => {}} theme={getTheme()} />);
const selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name);
const notSelectedSwatches = wrapper.find(ColorSwatch).filterWhere(node => node.prop('isSelected') === false);
......@@ -45,7 +46,7 @@ describe('ColorPickerPopover', () => {
it('should pass hex color value to onChange prop by default', () => {
wrapper = mount(
<ColorPickerPopover color={BasicGreen.variants.dark} onChange={onChangeSpy} theme={GrafanaTheme.Light} />
<ColorPickerPopover color={BasicGreen.variants.dark} onChange={onChangeSpy} theme={getTheme(GrafanaThemeType.Light)} />
);
const basicBlueSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicBlue.name);
......@@ -61,7 +62,7 @@ describe('ColorPickerPopover', () => {
enableNamedColors
color={BasicGreen.variants.dark}
onChange={onChangeSpy}
theme={GrafanaTheme.Light}
theme={getTheme(GrafanaThemeType.Light)}
/>
);
const basicBlueSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicBlue.name);
......
......@@ -2,9 +2,9 @@ import React from 'react';
import { NamedColorsPalette } from './NamedColorsPalette';
import { getColorName, getColorFromHexRgbOrName } from '../../utils/namedColorsPalette';
import { ColorPickerProps, warnAboutColorPickerPropsDeprecation } from './ColorPicker';
import { GrafanaTheme } from '../../types';
import { PopperContentProps } from '../Tooltip/PopperController';
import SpectrumPalette from './SpectrumPalette';
import { GrafanaThemeType } from '@grafana/ui';
export interface Props<T> extends ColorPickerProps, PopperContentProps {
customPickers?: T;
......@@ -43,7 +43,7 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
if (enableNamedColors) {
return changeHandler(color);
}
changeHandler(getColorFromHexRgbOrName(color, theme));
changeHandler(getColorFromHexRgbOrName(color, theme.type));
};
handleTabChange = (tab: PickerType | keyof T) => {
......@@ -58,7 +58,9 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
case 'spectrum':
return <SpectrumPalette color={color} onChange={this.handleChange} theme={theme} />;
case 'palette':
return <NamedColorsPalette color={getColorName(color, theme)} onChange={this.handleChange} theme={theme} />;
return (
<NamedColorsPalette color={getColorName(color, theme.type)} onChange={this.handleChange} theme={theme} />
);
default:
return this.renderCustomPicker(activePicker);
}
......@@ -88,11 +90,7 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
<>
{Object.keys(customPickers).map(key => {
return (
<div
className={this.getTabClassName(key)}
onClick={this.handleTabChange(key)}
key={key}
>
<div className={this.getTabClassName(key)} onClick={this.handleTabChange(key)} key={key}>
{customPickers[key].name}
</div>
);
......@@ -103,21 +101,14 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
render() {
const { theme } = this.props;
const colorPickerTheme = theme || GrafanaTheme.Dark;
const colorPickerTheme = theme.type || GrafanaThemeType.Dark;
return (
<div className={`ColorPickerPopover ColorPickerPopover--${colorPickerTheme}`}>
<div className="ColorPickerPopover__tabs">
<div
className={this.getTabClassName('palette')}
onClick={this.handleTabChange('palette')}
>
<div className={this.getTabClassName('palette')} onClick={this.handleTabChange('palette')}>
Colors
</div>
<div
className={this.getTabClassName('spectrum')}
onClick={this.handleTabChange('spectrum')}
>
<div className={this.getTabClassName('spectrum')} onClick={this.handleTabChange('spectrum')}>
Custom
</div>
{this.renderCustomPickerTabs()}
......@@ -128,3 +119,4 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
);
}
}
import React, { FunctionComponent } from 'react';
import { Themeable, GrafanaTheme } from '../../types';
import { Themeable, GrafanaThemeType } from '../../types';
import { ColorDefinition, getColorForTheme } from '../../utils/namedColorsPalette';
import { Color } from 'csstype';
import { find, upperFirst } from 'lodash';
......@@ -28,7 +28,8 @@ export const ColorSwatch: FunctionComponent<ColorSwatchProps> = ({
}) => {
const isSmall = variant === ColorSwatchVariant.Small;
const swatchSize = isSmall ? '16px' : '32px';
const selectedSwatchBorder = theme === GrafanaTheme.Light ? '#ffffff' : '#1A1B1F';
const selectedSwatchBorder = theme.type === GrafanaThemeType.Light ? '#ffffff' : '#1A1B1F';
const swatchStyles = {
width: swatchSize,
height: swatchSize,
......@@ -76,7 +77,7 @@ const NamedColorsGroup: FunctionComponent<NamedColorsGroupProps> = ({
key={primaryColor.name}
isSelected={primaryColor.name === selectedColor}
variant={ColorSwatchVariant.Large}
color={getColorForTheme(primaryColor, theme)}
color={getColorForTheme(primaryColor, theme.type)}
label={upperFirst(primaryColor.hue)}
onClick={() => onColorSelect(primaryColor)}
theme={theme}
......@@ -95,7 +96,7 @@ const NamedColorsGroup: FunctionComponent<NamedColorsGroupProps> = ({
<ColorSwatch
key={color.name}
isSelected={color.name === selectedColor}
color={getColorForTheme(color, theme)}
color={getColorForTheme(color, theme.type)}
onClick={() => onColorSelect(color)}
theme={theme}
/>
......
......@@ -3,7 +3,8 @@ import { mount, ReactWrapper } from 'enzyme';
import { NamedColorsPalette } from './NamedColorsPalette';
import { ColorSwatch } from './NamedColorsGroup';
import { getColorDefinitionByName } from '../../utils';
import { GrafanaTheme } from '../../types';
import { getTheme } from '../../themes';
import { GrafanaThemeType } from '../../types';
describe('NamedColorsPalette', () => {
......@@ -17,18 +18,18 @@ describe('NamedColorsPalette', () => {
});
it('should render provided color variant specific for theme', () => {
wrapper = mount(<NamedColorsPalette color={BasicGreen.name} theme={GrafanaTheme.Dark} onChange={() => {}} />);
wrapper = mount(<NamedColorsPalette color={BasicGreen.name} theme={getTheme()} onChange={() => {}} />);
selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name);
expect(selectedSwatch.prop('color')).toBe(BasicGreen.variants.dark);
wrapper.unmount();
wrapper = mount(<NamedColorsPalette color={BasicGreen.name} theme={GrafanaTheme.Light} onChange={() => {}} />);
wrapper = mount(<NamedColorsPalette color={BasicGreen.name} theme={getTheme(GrafanaThemeType.Light)} onChange={() => {}} />);
selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name);
expect(selectedSwatch.prop('color')).toBe(BasicGreen.variants.light);
});
it('should render dar variant of provided color when theme not provided', () => {
wrapper = mount(<NamedColorsPalette color={BasicGreen.name} onChange={() => {}} />);
wrapper = mount(<NamedColorsPalette color={BasicGreen.name} onChange={() => {}} theme={getTheme()}/>);
selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name);
expect(selectedSwatch.prop('color')).toBe(BasicGreen.variants.dark);
});
......
......@@ -4,6 +4,7 @@ import { ColorPickerPopover } from './ColorPickerPopover';
import { ColorPickerProps } from './ColorPicker';
import { PopperContentProps } from '../Tooltip/PopperController';
import { Switch } from '../Switch/Switch';
import { withTheme } from '../../themes/ThemeContext';
export interface SeriesColorPickerPopoverProps extends ColorPickerProps, PopperContentProps {
yaxis?: number;
......@@ -12,7 +13,6 @@ export interface SeriesColorPickerPopoverProps extends ColorPickerProps, PopperC
export const SeriesColorPickerPopover: FunctionComponent<SeriesColorPickerPopoverProps> = props => {
const { yaxis, onToggleAxis, color, ...colorPickerProps } = props;
return (
<ColorPickerPopover
{...colorPickerProps}
......@@ -85,3 +85,6 @@ export class AxisSelector extends React.PureComponent<AxisSelectorProps, AxisSel
);
}
}
// This component is to enable SeriecColorPickerPopover usage via series-color-picker-popover directive
export const SeriesColorPickerPopoverWithTheme = withTheme(SeriesColorPickerPopover);
......@@ -13,7 +13,7 @@ export interface SpectrumPaletteProps extends Themeable {
onChange: (color: string) => void;
}
const renderPointer = (theme?: GrafanaTheme) => (props: SpectrumPalettePointerProps) => (
const renderPointer = (theme: GrafanaTheme) => (props: SpectrumPalettePointerProps) => (
<SpectrumPalettePointer {...props} theme={theme} />
);
......@@ -92,7 +92,7 @@ const SpectrumPalette: React.FunctionComponent<SpectrumPaletteProps> = ({ color,
}}
theme={theme}
/>
<ColorInput color={color} onChange={onChange} style={{ marginTop: '16px' }} />
<ColorInput theme={theme} color={color} onChange={onChange} style={{ marginTop: '16px' }} />
</div>
);
};
......
import React from 'react';
import { GrafanaTheme, Themeable } from '../../types';
import { GrafanaThemeType, Themeable } from '../../types';
export interface SpectrumPalettePointerProps extends Themeable {
direction?: string;
......@@ -17,7 +17,7 @@ const SpectrumPalettePointer: React.FunctionComponent<SpectrumPalettePointerProp
},
};
const pointerColor = theme === GrafanaTheme.Light ? '#3F444D' : '#8E8E8E';
const pointerColor = theme.type === GrafanaThemeType.Light ? '#3F444D' : '#8E8E8E';
let pointerStyles: React.CSSProperties = {
position: 'absolute',
......
......@@ -3,6 +3,7 @@ import { shallow } from 'enzyme';
import { Gauge, Props } from './Gauge';
import { ValueMapping, MappingType } from '../../types';
import { getTheme } from '../../themes';
jest.mock('jquery', () => ({
plot: jest.fn(),
......@@ -24,6 +25,7 @@ const setup = (propOverrides?: object) => {
width: 300,
value: 25,
decimals: 0,
theme: getTheme()
};
Object.assign(props, propOverrides);
......
import React, { PureComponent } from 'react';
import $ from 'jquery';
import { ValueMapping, Threshold, BasicGaugeColor, GrafanaTheme } from '../../types';
import { ValueMapping, Threshold, BasicGaugeColor, GrafanaThemeType } from '../../types';
import { getMappedValue } from '../../utils/valueMappings';
import { getColorFromHexRgbOrName, getValueFormat } from '../../utils';
import { Themeable } from '../../index';
type TimeSeriesValue = string | number | null;
export interface Props {
export interface Props extends Themeable {
decimals: number;
height: number;
valueMappings: ValueMapping[];
......@@ -22,7 +23,6 @@ export interface Props {
unit: string;
width: number;
value: number;
theme?: GrafanaTheme;
}
const FONT_SCALE = 1;
......@@ -41,7 +41,7 @@ export class Gauge extends PureComponent<Props> {
thresholds: [],
unit: 'none',
stat: 'avg',
theme: GrafanaTheme.Dark,
theme: GrafanaThemeType.Dark,
};
componentDidMount() {
......@@ -77,19 +77,19 @@ export class Gauge extends PureComponent<Props> {
const { thresholds, theme } = this.props;
if (thresholds.length === 1) {
return getColorFromHexRgbOrName(thresholds[0].color, theme);
return getColorFromHexRgbOrName(thresholds[0].color, theme.type);
}
const atThreshold = thresholds.filter(threshold => (value as number) === threshold.value)[0];
if (atThreshold) {
return getColorFromHexRgbOrName(atThreshold.color, theme);
return getColorFromHexRgbOrName(atThreshold.color, theme.type);
}
const belowThreshold = thresholds.filter(threshold => (value as number) > threshold.value);
if (belowThreshold.length > 0) {
const nearestThreshold = belowThreshold.sort((t1, t2) => t2.value - t1.value)[0];
return getColorFromHexRgbOrName(nearestThreshold.color, theme);
return getColorFromHexRgbOrName(nearestThreshold.color, theme.type);
}
return BasicGaugeColor.Red;
......@@ -104,13 +104,13 @@ export class Gauge extends PureComponent<Props> {
return [
...thresholdsSortedByIndex.map(threshold => {
if (threshold.index === 0) {
return { value: minValue, color: getColorFromHexRgbOrName(threshold.color, theme) };
return { value: minValue, color: getColorFromHexRgbOrName(threshold.color, theme.type) };
}
const previousThreshold = thresholdsSortedByIndex[threshold.index - 1];
return { value: threshold.value, color: getColorFromHexRgbOrName(previousThreshold.color, theme) };
return { value: threshold.value, color: getColorFromHexRgbOrName(previousThreshold.color, theme.type) };
}),
{ value: maxValue, color: getColorFromHexRgbOrName(lastThreshold.color, theme) },
{ value: maxValue, color: getColorFromHexRgbOrName(lastThreshold.color, theme.type) },
];
}
......@@ -126,7 +126,8 @@ export class Gauge extends PureComponent<Props> {
const formattedValue = this.formatValue(value) as string;
const dimension = Math.min(width, height * 1.3);
const backgroundColor = theme === GrafanaTheme.Light ? 'rgb(230,230,230)' : 'rgb(38,38,38)';
const backgroundColor = theme.type === GrafanaThemeType.Light ? 'rgb(230,230,230)' : theme.colors.dark3;
const gaugeWidthReduceRatio = showThresholdLabels ? 1.5 : 1;
const gaugeWidth = Math.min(dimension / 6, 60) / gaugeWidthReduceRatio;
const thresholdMarkersWidth = gaugeWidth / 5;
......
import React, { PureComponent } from 'react';
import { Threshold, Themeable } from '../../types';
import { Threshold } from '../../types';
import { ColorPicker } from '../ColorPicker/ColorPicker';
import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup';
import { colors } from '../../utils';
import { getColorFromHexRgbOrName } from '@grafana/ui';
import { getColorFromHexRgbOrName, ThemeContext } from '@grafana/ui';
export interface Props extends Themeable {
export interface Props {
thresholds: Threshold[];
onChange: (thresholds: Threshold[]) => void;
}
......@@ -164,7 +164,10 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
<div className="thresholds-row-input-inner-color">
{threshold.color && (
<div className="thresholds-row-input-inner-color-colorpicker">
<ColorPicker color={threshold.color} onChange={color => this.onChangeThresholdColor(threshold, color)} />
<ColorPicker
color={threshold.color}
onChange={color => this.onChangeThresholdColor(threshold, color)}
/>
</div>
)}
</div>
......@@ -188,27 +191,35 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
render() {
const { thresholds } = this.state;
const { theme } = this.props;
return (
<PanelOptionsGroup title="Thresholds">
<div className="thresholds">
{thresholds.map((threshold, index) => {
return (
<div className="thresholds-row" key={`${threshold.index}-${index}`}>
<div className="thresholds-row-add-button" onClick={() => this.onAddThreshold(threshold.index + 1)}>
<i className="fa fa-plus" />
</div>
<div
className="thresholds-row-color-indicator"
style={{ backgroundColor: getColorFromHexRgbOrName(threshold.color, theme) }}
/>
<div className="thresholds-row-input">{this.renderInput(threshold)}</div>
<ThemeContext.Consumer>
{theme => {
return (
<PanelOptionsGroup title="Thresholds">
<div className="thresholds">
{thresholds.map((threshold, index) => {
return (
<div className="thresholds-row" key={`${threshold.index}-${index}`}>
<div
className="thresholds-row-add-button"
onClick={() => this.onAddThreshold(threshold.index + 1)}
>
<i className="fa fa-plus" />
</div>
<div
className="thresholds-row-color-indicator"
style={{ backgroundColor: getColorFromHexRgbOrName(threshold.color, theme.type) }}
/>
<div className="thresholds-row-input">{this.renderInput(threshold)}</div>
</div>
);
})}
</div>
);
})}
</div>
</PanelOptionsGroup>
</PanelOptionsGroup>
);
}}
</ThemeContext.Consumer>
);
}
}
......@@ -14,8 +14,8 @@ export { FormLabel } from './FormLabel/FormLabel';
export { FormField } from './FormField/FormField';
export { LoadingPlaceholder } from './LoadingPlaceholder/LoadingPlaceholder';
export { ColorPicker, SeriesColorPicker } from './ColorPicker/ColorPicker';
export { SeriesColorPickerPopover } from './ColorPicker/SeriesColorPickerPopover';
export { ColorPicker, SeriesColorPicker } from './ColorPicker/ColorPicker';
export { SeriesColorPickerPopover, SeriesColorPickerPopoverWithTheme } from './ColorPicker/SeriesColorPickerPopover';
export { ThresholdsEditor } from './ThresholdsEditor/ThresholdsEditor';
export { Graph } from './Graph/Graph';
export { PanelOptionsGroup } from './PanelOptionsGroup/PanelOptionsGroup';
......
......@@ -5,20 +5,20 @@ import {
getColorFromHexRgbOrName,
getColorDefinitionByName,
} from './namedColorsPalette';
import { GrafanaTheme } from '../types/index';
import { GrafanaThemeType } from '../types/index';
describe('colors', () => {
const SemiDarkBlue = getColorDefinitionByName('semi-dark-blue');
describe('getColorDefinition', () => {
it('returns undefined for unknown hex', () => {
expect(getColorDefinition('#ff0000', GrafanaTheme.Light)).toBeUndefined();
expect(getColorDefinition('#ff0000', GrafanaTheme.Dark)).toBeUndefined();
expect(getColorDefinition('#ff0000', GrafanaThemeType.Light)).toBeUndefined();
expect(getColorDefinition('#ff0000', GrafanaThemeType.Dark)).toBeUndefined();
});
it('returns definition for known hex', () => {
expect(getColorDefinition(SemiDarkBlue.variants.light, GrafanaTheme.Light)).toEqual(SemiDarkBlue);
expect(getColorDefinition(SemiDarkBlue.variants.dark, GrafanaTheme.Dark)).toEqual(SemiDarkBlue);
expect(getColorDefinition(SemiDarkBlue.variants.light, GrafanaThemeType.Light)).toEqual(SemiDarkBlue);
expect(getColorDefinition(SemiDarkBlue.variants.dark, GrafanaThemeType.Dark)).toEqual(SemiDarkBlue);
});
});
......@@ -28,8 +28,8 @@ describe('colors', () => {
});
it('returns name for known hex', () => {
expect(getColorName(SemiDarkBlue.variants.light, GrafanaTheme.Light)).toEqual(SemiDarkBlue.name);
expect(getColorName(SemiDarkBlue.variants.dark, GrafanaTheme.Dark)).toEqual(SemiDarkBlue.name);
expect(getColorName(SemiDarkBlue.variants.light, GrafanaThemeType.Light)).toEqual(SemiDarkBlue.name);
expect(getColorName(SemiDarkBlue.variants.dark, GrafanaThemeType.Dark)).toEqual(SemiDarkBlue.name);
});
});
......@@ -53,7 +53,7 @@ describe('colors', () => {
});
it("returns correct variant's hex for known color if theme specified", () => {
expect(getColorFromHexRgbOrName(SemiDarkBlue.name, GrafanaTheme.Light)).toBe(SemiDarkBlue.variants.light);
expect(getColorFromHexRgbOrName(SemiDarkBlue.name, GrafanaThemeType.Light)).toBe(SemiDarkBlue.variants.light);
});
it('returns color if specified as hex or rgb/a', () => {
......
import { flatten } from 'lodash';
import { GrafanaTheme } from '../types';
import { GrafanaThemeType } from '../types';
type Hue = 'green' | 'yellow' | 'red' | 'blue' | 'orange' | 'purple';
......@@ -68,7 +68,7 @@ export const getColorDefinitionByName = (name: Color): ColorDefinition => {
return flatten(Array.from(getNamedColorPalette().values())).filter(definition => definition.name === name)[0];
};
export const getColorDefinition = (hex: string, theme: GrafanaTheme): ColorDefinition | undefined => {
export const getColorDefinition = (hex: string, theme: GrafanaThemeType): ColorDefinition | undefined => {
return flatten(Array.from(getNamedColorPalette().values())).filter(definition => definition.variants[theme] === hex)[0];
};
......@@ -77,7 +77,7 @@ const isHex = (color: string) => {
return hexRegex.test(color);
};
export const getColorName = (color?: string, theme?: GrafanaTheme): Color | undefined => {
export const getColorName = (color?: string, theme?: GrafanaThemeType): Color | undefined => {
if (!color) {
return undefined;
}
......@@ -86,7 +86,7 @@ export const getColorName = (color?: string, theme?: GrafanaTheme): Color | unde
return undefined;
}
if (isHex(color)) {
const definition = getColorDefinition(color, theme || GrafanaTheme.Dark);
const definition = getColorDefinition(color, theme || GrafanaThemeType.Dark);
return definition ? definition.name : undefined;
}
......@@ -98,7 +98,7 @@ export const getColorByName = (colorName: string) => {
return definition.length > 0 ? definition[0] : undefined;
};
export const getColorFromHexRgbOrName = (color: string, theme?: GrafanaTheme): string => {
export const getColorFromHexRgbOrName = (color: string, theme?: GrafanaThemeType): string => {
if (color.indexOf('rgb') > -1 || isHex(color)) {
return color;
}
......@@ -112,14 +112,14 @@ export const getColorFromHexRgbOrName = (color: string, theme?: GrafanaTheme): s
return theme ? colorDefinition.variants[theme] : colorDefinition.variants.dark;
};
export const getColorForTheme = (color: ColorDefinition, theme?: GrafanaTheme) => {
export const getColorForTheme = (color: ColorDefinition, theme?: GrafanaThemeType) => {
return theme ? color.variants[theme] : color.variants.dark;
};
const buildNamedColorsPalette = () => {
const palette = new Map<Hue, ColorDefinition[]>();
const BasicGreen = buildColorDefinition('green', 'green', ['#56A64B', '#73BF69'], true);
const BasicGreen = buildColorDefinition('green', 'green', ['#56A64B', '#73BF69'], true);
const DarkGreen = buildColorDefinition('green', 'dark-green', ['#19730E', '#37872D']);
const SemiDarkGreen = buildColorDefinition('green', 'semi-dark-green', ['#37872D', '#56A64B']);
const LightGreen = buildColorDefinition('green', 'light-green', ['#73BF69', '#96D98D']);
......
......@@ -9,7 +9,7 @@ import { TagFilter } from './components/TagFilter/TagFilter';
import { SideMenu } from './components/sidemenu/SideMenu';
import { MetricSelect } from './components/Select/MetricSelect';
import AppNotificationList from './components/AppNotifications/AppNotificationList';
import { ColorPicker, SeriesColorPickerPopover } from '@grafana/ui';
import { ColorPicker, SeriesColorPickerPopoverWithTheme } from '@grafana/ui';
export function registerAngularDirectives() {
react2AngularDirective('passwordStrength', PasswordStrength, ['password']);
......@@ -27,7 +27,7 @@ export function registerAngularDirectives() {
'color',
['onChange', { watchDepth: 'reference', wrapApply: true }],
]);
react2AngularDirective('seriesColorPickerPopover', SeriesColorPickerPopover, [
react2AngularDirective('seriesColorPickerPopover', SeriesColorPickerPopoverWithTheme, [
'color',
'series',
'onColorChange',
......
import React from 'react';
import config, { Settings } from 'app/core/config';
import { GrafanaTheme } from '@grafana/ui';
import { GrafanaThemeType, ThemeContext, getTheme } from '@grafana/ui';
export const ConfigContext = React.createContext<Settings>(config);
export const ConfigConsumer = ConfigContext.Consumer;
......@@ -13,16 +13,21 @@ export const provideConfig = (component: React.ComponentType<any>) => {
return ConfigProvider;
};
interface ThemeProviderProps {
children: (theme: GrafanaTheme) => JSX.Element;
}
export const getCurrentThemeName = () =>
config.bootData.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark;
export const getCurrentTheme = () => getTheme(getCurrentThemeName());
export const ThemeProvider = ({ children }: ThemeProviderProps) => {
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
return (
<ConfigConsumer>
{({ bootData }) => {
return children(bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark);
{config => {
const currentTheme = getCurrentThemeName();
return <ThemeContext.Provider value={getTheme(currentTheme)}>{children}</ThemeContext.Provider>;
}}
</ConfigConsumer>
);
};
export const provideTheme = (component: React.ComponentType<any>) => {
return provideConfig((props: any) => <ThemeProvider>{React.createElement(component, { ...props })}</ThemeProvider>);
};
import coreModule from 'app/core/core_module';
import { provideConfig } from 'app/core/utils/ConfigProvider';
import { provideTheme } from 'app/core/utils/ConfigProvider';
export function react2AngularDirective(name: string, component: any, options: any) {
coreModule.directive(name, [
'reactDirective',
reactDirective => {
return reactDirective(provideConfig(component), options);
return reactDirective(provideTheme(component), options);
},
]);
}
......@@ -2,7 +2,7 @@
import React, { PureComponent } from 'react';
// Services & Utils
import { processTimeSeries } from '@grafana/ui';
import { processTimeSeries, ThemeContext } from '@grafana/ui';
// Components
import { Gauge } from '@grafana/ui';
......@@ -10,7 +10,6 @@ import { Gauge } from '@grafana/ui';
// Types
import { GaugeOptions } from './types';
import { PanelProps, NullValueMode, TimeSeriesValue } from '@grafana/ui/src/types';
import { ThemeProvider } from 'app/core/utils/ConfigProvider';
interface Props extends PanelProps<GaugeOptions> {}
......@@ -38,7 +37,7 @@ export class GaugePanel extends PureComponent<Props> {
}
return (
<ThemeProvider>
<ThemeContext.Consumer>
{theme => (
<Gauge
value={value}
......@@ -50,7 +49,7 @@ export class GaugePanel extends PureComponent<Props> {
theme={theme}
/>
)}
</ThemeProvider>
</ThemeContext.Consumer>
);
}
}
......@@ -11,7 +11,6 @@ import {
import ValueOptions from 'app/plugins/panel/gauge/ValueOptions';
import GaugeOptionsEditor from './GaugeOptionsEditor';
import { GaugeOptions } from './types';
import { ThemeProvider } from 'app/core/utils/ConfigProvider';
export const defaultProps = {
options: {
......@@ -46,24 +45,17 @@ export default class GaugePanelOptions extends PureComponent<PanelOptionsProps<G
render() {
const { onChange, options } = this.props;
return (
<ThemeProvider>
{(theme) => (
<>
<PanelOptionsGrid>
<ValueOptions onChange={onChange} options={options} />
<GaugeOptionsEditor onChange={onChange} options={options} />
<ThresholdsEditor
onChange={this.onThresholdsChanged}
thresholds={options.thresholds}
theme={theme}
/>
</PanelOptionsGrid>
<>
<PanelOptionsGrid>
<ValueOptions onChange={onChange} options={options} />
<GaugeOptionsEditor onChange={onChange} options={options} />
<ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={options.thresholds} />
</PanelOptionsGrid>
<ValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={options.valueMappings} />
</>
)}
</ThemeProvider>
<ValueMappingsEditor onChange={this.onValueMappingsChanged} valueMappings={options.valueMappings} />
</>
);
}
}
......@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
import classNames from 'classnames';
import { TimeSeries } from 'app/core/core';
import { SeriesColorPicker } from '@grafana/ui';
import { ThemeProvider } from 'app/core/utils/ConfigProvider';
// import { ThemeProvider } from 'app/core/utils/ConfigProvider';
export const LEGEND_STATS = ['min', 'max', 'avg', 'current', 'total'];
......@@ -168,24 +168,17 @@ class LegendSeriesIcon extends PureComponent<LegendSeriesIconProps, LegendSeries
render() {
return (
<ThemeProvider>
{theme => {
return (
<SeriesColorPicker
yaxis={this.props.yaxis}
color={this.props.color}
onChange={this.props.onColorChange}
onToggleAxis={this.props.onToggleAxis}
theme={theme}
enableNamedColors
>
<span className="graph-legend-icon">
<SeriesIcon color={this.props.color} />
</span>
</SeriesColorPicker>
);
}}
</ThemeProvider>
<SeriesColorPicker
yaxis={this.props.yaxis}
color={this.props.color}
onChange={this.props.onColorChange}
onToggleAxis={this.props.onToggleAxis}
enableNamedColors
>
<span className="graph-legend-icon">
<SeriesIcon color={this.props.color} />
</span>
</SeriesColorPicker>
);
}
}
......
import _ from 'lodash';
import { colors, GrafanaTheme, getColorFromHexRgbOrName } from '@grafana/ui';
import { colors, GrafanaThemeType, getColorFromHexRgbOrName } from '@grafana/ui';
import TimeSeries from 'app/core/time_series2';
import config from 'app/core/config';
......@@ -113,7 +113,7 @@ export class DataProcessor {
const series = new TimeSeries({
datapoints: datapoints,
alias: alias,
color: getColorFromHexRgbOrName(color, config.bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark),
color: getColorFromHexRgbOrName(color, config.bootData.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark),
unit: seriesData.unit,
});
......
......@@ -25,7 +25,8 @@ import ReactDOM from 'react-dom';
import { Legend, GraphLegendProps } from './Legend/Legend';
import { GraphCtrl } from './module';
import { GrafanaTheme, getValueFormat } from '@grafana/ui';
import { GrafanaThemeType, getValueFormat } from '@grafana/ui';
import { provideTheme } from 'app/core/utils/ConfigProvider';
class GraphElement {
ctrl: GraphCtrl;
......@@ -53,7 +54,7 @@ class GraphElement {
this.thresholdManager = new ThresholdManager(this.ctrl);
this.timeRegionManager = new TimeRegionManager(
this.ctrl,
config.bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark
config.bootData.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark
);
this.tooltip = new GraphTooltip(this.elem, this.ctrl.dashboard, this.scope, () => {
return this.sortedSeries;
......@@ -109,7 +110,7 @@ class GraphElement {
onToggleAxis: this.ctrl.onToggleAxis,
};
const legendReactElem = React.createElement(Legend, legendProps);
const legendReactElem = React.createElement(provideTheme(Legend), legendProps);
ReactDOM.render(legendReactElem, this.legendElem, () => this.renderPanel());
}
......
......@@ -10,7 +10,7 @@ import { MetricsPanelCtrl } from 'app/plugins/sdk';
import { DataProcessor } from './data_processor';
import { axesEditorComponent } from './axes_editor';
import config from 'app/core/config';
import { GrafanaTheme, getColorFromHexRgbOrName } from '@grafana/ui';
import { GrafanaThemeType, getColorFromHexRgbOrName } from '@grafana/ui';
class GraphCtrl extends MetricsPanelCtrl {
static template = template;
......@@ -244,7 +244,7 @@ class GraphCtrl extends MetricsPanelCtrl {
}
onColorChange = (series, color) => {
series.setColor(getColorFromHexRgbOrName(color, config.bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark));
series.setColor(getColorFromHexRgbOrName(color, config.bootData.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark));
this.panel.aliasColors[series.alias] = color;
this.render();
};
......
import 'vendor/flot/jquery.flot';
import _ from 'lodash';
import moment from 'moment';
import { GrafanaTheme, getColorFromHexRgbOrName } from '@grafana/ui';
import { GrafanaThemeType, getColorFromHexRgbOrName } from '@grafana/ui';
type TimeRegionColorDefinition = {
fill: string;
......@@ -43,7 +43,7 @@ export function getColorModes() {
});
}
function getColor(timeRegion, theme: GrafanaTheme): TimeRegionColorDefinition {
function getColor(timeRegion, theme: GrafanaThemeType): TimeRegionColorDefinition {
if (Object.keys(colorModes).indexOf(timeRegion.colorMode) === -1) {
timeRegion.colorMode = 'red';
}
......@@ -58,7 +58,7 @@ function getColor(timeRegion, theme: GrafanaTheme): TimeRegionColorDefinition {
const colorMode = colorModes[timeRegion.colorMode];
if (colorMode.themeDependent === true) {
return theme === GrafanaTheme.Light ? colorMode.lightColor : colorMode.darkColor;
return theme === GrafanaThemeType.Light ? colorMode.lightColor : colorMode.darkColor;
}
return {
......@@ -71,7 +71,7 @@ export class TimeRegionManager {
plot: any;
timeRegions: any;
constructor(private panelCtrl, private theme: GrafanaTheme = GrafanaTheme.Dark) {}
constructor(private panelCtrl, private theme: GrafanaThemeType = GrafanaThemeType.Dark) {}
draw(plot) {
this.timeRegions = this.panelCtrl.panel.timeRegions;
......
......@@ -5,7 +5,7 @@ import { contextSrv } from 'app/core/core';
import { tickStep } from 'app/core/utils/ticks';
import { getColorScale, getOpacityScale } from './color_scale';
import coreModule from 'app/core/core_module';
import { GrafanaTheme, getColorFromHexRgbOrName } from '@grafana/ui';
import { GrafanaThemeType, getColorFromHexRgbOrName } from '@grafana/ui';
const LEGEND_HEIGHT_PX = 6;
const LEGEND_WIDTH_PX = 100;
......@@ -250,7 +250,7 @@ function drawSimpleOpacityLegend(elem, options) {
.attr('stroke-width', 0)
.attr(
'fill',
getColorFromHexRgbOrName(options.cardColor, contextSrv.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark)
getColorFromHexRgbOrName(options.cardColor, contextSrv.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark)
)
.style('opacity', d => legendOpacityScale(d));
}
......
......@@ -7,7 +7,7 @@ import * as ticksUtils from 'app/core/utils/ticks';
import { HeatmapTooltip } from './heatmap_tooltip';
import { mergeZeroBuckets } from './heatmap_data_converter';
import { getColorScale, getOpacityScale } from './color_scale';
import { GrafanaTheme, getColorFromHexRgbOrName, getValueFormat } from '@grafana/ui';
import { GrafanaThemeType, getColorFromHexRgbOrName, getValueFormat } from '@grafana/ui';
const MIN_CARD_SIZE = 1,
CARD_PADDING = 1,
......@@ -663,7 +663,7 @@ export class HeatmapRenderer {
if (this.panel.color.mode === 'opacity') {
return getColorFromHexRgbOrName(
this.panel.color.cardColor,
contextSrv.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark
contextSrv.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark
);
} else {
return this.colorScale(d.count);
......
......@@ -8,7 +8,7 @@ import kbn from 'app/core/utils/kbn';
import config from 'app/core/config';
import TimeSeries from 'app/core/time_series2';
import { MetricsPanelCtrl } from 'app/plugins/sdk';
import { GrafanaTheme, getValueFormat, getColorFromHexRgbOrName } from '@grafana/ui';
import { GrafanaThemeType, getValueFormat, getColorFromHexRgbOrName } from '@grafana/ui';
class SingleStatCtrl extends MetricsPanelCtrl {
static templateUrl = 'module.html';
......@@ -590,7 +590,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
lineWidth: 1,
fillColor: getColorFromHexRgbOrName(
panel.sparkline.fillColor,
config.bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark
config.bootData.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark
),
},
},
......@@ -610,7 +610,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
data: data.flotpairs,
color: getColorFromHexRgbOrName(
panel.sparkline.lineColor,
config.bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark
config.bootData.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark
),
};
......@@ -630,7 +630,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
// Map panel colors to hex or rgb/a values
data.colorMap = panel.colors.map(color =>
getColorFromHexRgbOrName(color, config.bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark)
getColorFromHexRgbOrName(color, config.bootData.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark)
);
const body = panel.gauge.show ? '' : getBigValueHtml();
......
......@@ -6,7 +6,7 @@ import { transformDataToTable } from './transformers';
import { tablePanelEditor } from './editor';
import { columnOptionsTab } from './column_options';
import { TableRenderer } from './renderer';
import { GrafanaTheme } from '@grafana/ui';
import { GrafanaThemeType } from '@grafana/ui';
class TablePanelCtrl extends MetricsPanelCtrl {
static templateUrl = 'module.html';
......@@ -131,7 +131,7 @@ class TablePanelCtrl extends MetricsPanelCtrl {
this.dashboard.isTimezoneUtc(),
this.$sanitize,
this.templateSrv,
config.bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark,
config.bootData.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark,
);
return super.render(this.table);
......
import _ from 'lodash';
import moment from 'moment';
import kbn from 'app/core/utils/kbn';
import { GrafanaTheme, getValueFormat, getColorFromHexRgbOrName } from '@grafana/ui';
import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType } from '@grafana/ui';
export class TableRenderer {
formatters: any[];
......@@ -13,7 +13,7 @@ export class TableRenderer {
private isUtc,
private sanitize,
private templateSrv,
private theme?: GrafanaTheme
private theme?: GrafanaThemeType
) {
this.initColumns();
}
......
......@@ -5,6 +5,7 @@ import { Provider } from 'react-redux';
import coreModule from 'app/core/core_module';
import { store } from 'app/store/store';
import { ContextSrv } from 'app/core/services/context_srv';
import { provideTheme } from 'app/core/utils/ConfigProvider';
function WrapInProvider(store, Component, props) {
return (
......@@ -46,7 +47,7 @@ export function reactContainer(
$scope: scope,
};
ReactDOM.render(WrapInProvider(store, component, props), elem[0]);
ReactDOM.render(WrapInProvider(store, provideTheme(component), props), elem[0]);
scope.$on('$destroy', () => {
ReactDOM.unmountComponentAtNode(elem[0]);
......
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