diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx index b6cf176a24b..67201727a34 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx @@ -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 = (
); }; @@ -95,7 +95,7 @@ export const colorPickerFactory = (
@@ -110,5 +110,5 @@ export const colorPickerFactory = ( }; }; -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')); diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx index 28d66e7af86..444f0e658c8 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx @@ -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( {}} />); + const wrapper = mount( {}} 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( {}} />); + const wrapper = mount( {}} 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( - + ); 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); diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx index d2937a1caba..b4c77a5e373 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx @@ -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 extends ColorPickerProps, PopperContentProps { customPickers?: T; @@ -43,7 +43,7 @@ export class ColorPickerPopover 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 extends React case 'spectrum': return ; case 'palette': - return ; + return ( + + ); default: return this.renderCustomPicker(activePicker); } @@ -88,11 +90,7 @@ export class ColorPickerPopover extends React <> {Object.keys(customPickers).map(key => { return ( -
+
{customPickers[key].name}
); @@ -103,21 +101,14 @@ export class ColorPickerPopover extends React render() { const { theme } = this.props; - const colorPickerTheme = theme || GrafanaTheme.Dark; - + const colorPickerTheme = theme.type || GrafanaThemeType.Dark; return (
-
+
Colors
-
+
Custom
{this.renderCustomPickerTabs()} @@ -128,3 +119,4 @@ export class ColorPickerPopover extends React ); } } + diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx index 91c4f21642a..91407bc6cc6 100644 --- a/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx @@ -1,5 +1,5 @@ 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 = ({ }) => { 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 = ({ 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 = ({ onColorSelect(color)} theme={theme} /> diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx index 171d26f5c56..7a1ba95e81d 100644 --- a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx @@ -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( {}} />); + wrapper = mount( {}} />); selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name); expect(selectedSwatch.prop('color')).toBe(BasicGreen.variants.dark); wrapper.unmount(); - wrapper = mount( {}} />); + wrapper = mount( {}} />); 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( {}} />); + wrapper = mount( {}} theme={getTheme()}/>); selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name); expect(selectedSwatch.prop('color')).toBe(BasicGreen.variants.dark); }); diff --git a/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx index 3fa7a1f4a45..4cb8c15c002 100644 --- a/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx @@ -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 = props => { const { yaxis, onToggleAxis, color, ...colorPickerProps } = props; - return ( void; } -const renderPointer = (theme?: GrafanaTheme) => (props: SpectrumPalettePointerProps) => ( +const renderPointer = (theme: GrafanaTheme) => (props: SpectrumPalettePointerProps) => ( ); @@ -92,7 +92,7 @@ const SpectrumPalette: React.FunctionComponent = ({ color, }} theme={theme} /> - +
); }; diff --git a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalettePointer.tsx b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalettePointer.tsx index d0b2cbc4bff..18327e96769 100644 --- a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalettePointer.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalettePointer.tsx @@ -1,5 +1,5 @@ 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 ({ plot: jest.fn(), @@ -24,6 +25,7 @@ const setup = (propOverrides?: object) => { width: 300, value: 25, decimals: 0, + theme: getTheme() }; Object.assign(props, propOverrides); diff --git a/packages/grafana-ui/src/components/Gauge/Gauge.tsx b/packages/grafana-ui/src/components/Gauge/Gauge.tsx index 04d89bf3f57..a7435a56b3c 100644 --- a/packages/grafana-ui/src/components/Gauge/Gauge.tsx +++ b/packages/grafana-ui/src/components/Gauge/Gauge.tsx @@ -1,13 +1,14 @@ 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 { thresholds: [], unit: 'none', stat: 'avg', - theme: GrafanaTheme.Dark, + theme: GrafanaThemeType.Dark, }; componentDidMount() { @@ -77,19 +77,19 @@ export class Gauge extends PureComponent { 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 { 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 { 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; diff --git a/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx index c15f66cca54..b2a2e07c58d 100644 --- a/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx +++ b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx @@ -1,11 +1,11 @@ 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 {
{threshold.color && (
- this.onChangeThresholdColor(threshold, color)} /> + this.onChangeThresholdColor(threshold, color)} + />
)}
@@ -188,27 +191,35 @@ export class ThresholdsEditor extends PureComponent { render() { const { thresholds } = this.state; - const { theme } = this.props; return ( - -
- {thresholds.map((threshold, index) => { - return ( -
-
this.onAddThreshold(threshold.index + 1)}> - -
-
-
{this.renderInput(threshold)}
+ + {theme => { + return ( + +
+ {thresholds.map((threshold, index) => { + return ( +
+
this.onAddThreshold(threshold.index + 1)} + > + +
+
+
{this.renderInput(threshold)}
+
+ ); + })}
- ); - })} -
-
+ + ); + }} +
); } } diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index 5cd677761b0..dc435a8844d 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -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'; diff --git a/packages/grafana-ui/src/utils/namedColorsPalette.test.ts b/packages/grafana-ui/src/utils/namedColorsPalette.test.ts index c6a1aaf0dd0..f875b9966f1 100644 --- a/packages/grafana-ui/src/utils/namedColorsPalette.test.ts +++ b/packages/grafana-ui/src/utils/namedColorsPalette.test.ts @@ -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', () => { diff --git a/packages/grafana-ui/src/utils/namedColorsPalette.ts b/packages/grafana-ui/src/utils/namedColorsPalette.ts index 5312b27ad26..a99a93f4207 100644 --- a/packages/grafana-ui/src/utils/namedColorsPalette.ts +++ b/packages/grafana-ui/src/utils/namedColorsPalette.ts @@ -1,5 +1,5 @@ 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(); - 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']); diff --git a/public/app/core/angular_wrappers.ts b/public/app/core/angular_wrappers.ts index 4806275e87d..6db442e7470 100644 --- a/public/app/core/angular_wrappers.ts +++ b/public/app/core/angular_wrappers.ts @@ -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', diff --git a/public/app/core/utils/ConfigProvider.tsx b/public/app/core/utils/ConfigProvider.tsx index 6883401ad27..56b6fc3d8b9 100644 --- a/public/app/core/utils/ConfigProvider.tsx +++ b/public/app/core/utils/ConfigProvider.tsx @@ -1,6 +1,6 @@ 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(config); export const ConfigConsumer = ConfigContext.Consumer; @@ -13,16 +13,21 @@ export const provideConfig = (component: React.ComponentType) => { 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 ( - {({ bootData }) => { - return children(bootData.user.lightTheme ? GrafanaTheme.Light : GrafanaTheme.Dark); + {config => { + const currentTheme = getCurrentThemeName(); + return {children}; }} ); }; + +export const provideTheme = (component: React.ComponentType) => { + return provideConfig((props: any) => {React.createElement(component, { ...props })}); +}; diff --git a/public/app/core/utils/react2angular.ts b/public/app/core/utils/react2angular.ts index 1057f68fcda..eb4bccab267 100644 --- a/public/app/core/utils/react2angular.ts +++ b/public/app/core/utils/react2angular.ts @@ -1,11 +1,11 @@ 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); }, ]); } diff --git a/public/app/plugins/panel/gauge/GaugePanel.tsx b/public/app/plugins/panel/gauge/GaugePanel.tsx index b6f37dde94f..5cb256ee1aa 100644 --- a/public/app/plugins/panel/gauge/GaugePanel.tsx +++ b/public/app/plugins/panel/gauge/GaugePanel.tsx @@ -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 {} @@ -38,7 +37,7 @@ export class GaugePanel extends PureComponent { } return ( - + {theme => ( { theme={theme} /> )} - + ); } } diff --git a/public/app/plugins/panel/gauge/GaugePanelOptions.tsx b/public/app/plugins/panel/gauge/GaugePanelOptions.tsx index 655c596ce84..84726ac88bf 100644 --- a/public/app/plugins/panel/gauge/GaugePanelOptions.tsx +++ b/public/app/plugins/panel/gauge/GaugePanelOptions.tsx @@ -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 - {(theme) => ( - <> - - - - - - - - )} - + return ( + <> + + + + + + + + ); } } diff --git a/public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx b/public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx index d62613319b2..e3de5b067ba 100644 --- a/public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx +++ b/public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx @@ -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 - {theme => { - return ( - - - - - - ); - }} - + + + + + ); } } diff --git a/public/app/plugins/panel/graph/data_processor.ts b/public/app/plugins/panel/graph/data_processor.ts index 4141d36e273..0d4445e1981 100644 --- a/public/app/plugins/panel/graph/data_processor.ts +++ b/public/app/plugins/panel/graph/data_processor.ts @@ -1,5 +1,5 @@ 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, }); diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index aeb540551b8..3800e147d9d 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -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()); } diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index 68d982eab13..cb1c0d98269 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -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(); }; diff --git a/public/app/plugins/panel/graph/time_region_manager.ts b/public/app/plugins/panel/graph/time_region_manager.ts index 2917583ff36..ea39927bf57 100644 --- a/public/app/plugins/panel/graph/time_region_manager.ts +++ b/public/app/plugins/panel/graph/time_region_manager.ts @@ -1,7 +1,7 @@ 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; diff --git a/public/app/plugins/panel/heatmap/color_legend.ts b/public/app/plugins/panel/heatmap/color_legend.ts index 81329fe297b..dea250abf74 100644 --- a/public/app/plugins/panel/heatmap/color_legend.ts +++ b/public/app/plugins/panel/heatmap/color_legend.ts @@ -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)); } diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index 6489c9e9895..63604382432 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -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); diff --git a/public/app/plugins/panel/singlestat/module.ts b/public/app/plugins/panel/singlestat/module.ts index 2768951d2ba..4ea81ff8630 100644 --- a/public/app/plugins/panel/singlestat/module.ts +++ b/public/app/plugins/panel/singlestat/module.ts @@ -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(); diff --git a/public/app/plugins/panel/table/module.ts b/public/app/plugins/panel/table/module.ts index 82763e1839a..3d82dd4df68 100644 --- a/public/app/plugins/panel/table/module.ts +++ b/public/app/plugins/panel/table/module.ts @@ -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); diff --git a/public/app/plugins/panel/table/renderer.ts b/public/app/plugins/panel/table/renderer.ts index 90479a67602..e9bf89f45fe 100644 --- a/public/app/plugins/panel/table/renderer.ts +++ b/public/app/plugins/panel/table/renderer.ts @@ -1,7 +1,7 @@ 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(); } diff --git a/public/app/routes/ReactContainer.tsx b/public/app/routes/ReactContainer.tsx index 2cad3d828bf..985914eb067 100644 --- a/public/app/routes/ReactContainer.tsx +++ b/public/app/routes/ReactContainer.tsx @@ -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]);