diff --git a/packages/grafana-ui/src/index.ts b/packages/grafana-ui/src/index.ts index 4ddc7c8485a..216f2f13bad 100644 --- a/packages/grafana-ui/src/index.ts +++ b/packages/grafana-ui/src/index.ts @@ -1,4 +1,5 @@ export * from './components'; export * from './types'; export * from './utils'; -export * from './theme'; +export * from './themes'; +export * from './themes/ThemeContext'; diff --git a/packages/grafana-ui/src/themes/ThemeContext.tsx b/packages/grafana-ui/src/themes/ThemeContext.tsx new file mode 100644 index 00000000000..a61a71d8af6 --- /dev/null +++ b/packages/grafana-ui/src/themes/ThemeContext.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { GrafanaThemeType, Themeable } from '../types'; +import { getTheme } from './index'; + +type Omit = Pick>; +type Subtract = Omit; + +// Use Grafana Dark theme by default +export const ThemeContext = React.createContext(getTheme(GrafanaThemeType.Dark)); + +export const withTheme =

(Component: React.ComponentType

) => { + const WithTheme: React.FunctionComponent> = props => { + // @ts-ignore + return {theme => }; + }; + + WithTheme.displayName = `WithTheme(${Component.displayName})`; + + return WithTheme; +}; diff --git a/packages/grafana-ui/src/themes/dark.js b/packages/grafana-ui/src/themes/dark.js index c80a4593f53..3031018bd56 100644 --- a/packages/grafana-ui/src/themes/dark.js +++ b/packages/grafana-ui/src/themes/dark.js @@ -4,7 +4,7 @@ const defaultTheme = require('./default'); const tinycolor = require('tinycolor2'); const basicColors = { - black: '#00ff00', + black: '#000000', white: '#ffffff', dark1: '#141414', dark2: '#1f1f20', @@ -33,6 +33,7 @@ const basicColors = { const darkTheme = { ...defaultTheme, + type: 'dark', name: 'Grafana Dark', colors: { ...basicColors, diff --git a/packages/grafana-ui/src/themes/index.d.ts b/packages/grafana-ui/src/themes/index.d.ts new file mode 100644 index 00000000000..304c478b46e --- /dev/null +++ b/packages/grafana-ui/src/themes/index.d.ts @@ -0,0 +1,4 @@ +import { GrafanaTheme } from "../types"; + +export function getTheme(themeName?: string): GrafanaTheme +export function mockTheme(themeMock: Partial): () => void diff --git a/packages/grafana-ui/src/theme.js b/packages/grafana-ui/src/themes/index.js similarity index 70% rename from packages/grafana-ui/src/theme.js rename to packages/grafana-ui/src/themes/index.js index 3d0695e2490..c88cf137574 100644 --- a/packages/grafana-ui/src/theme.js +++ b/packages/grafana-ui/src/themes/index.js @@ -1,5 +1,5 @@ -const darkTheme = require('./themes/dark'); -const lightTheme = require('./themes/light'); +const darkTheme = require('./dark'); +const lightTheme = require('./light'); const getTheme = name => (name === 'light' ? lightTheme : darkTheme); @@ -11,5 +11,5 @@ const mockTheme = mock => { module.exports = { getTheme, - mockTheme, + mockTheme }; diff --git a/packages/grafana-ui/src/themes/light.js b/packages/grafana-ui/src/themes/light.js index 84d1e656baa..de5c79e8319 100644 --- a/packages/grafana-ui/src/themes/light.js +++ b/packages/grafana-ui/src/themes/light.js @@ -33,6 +33,7 @@ const basicColors = { const lightTheme/*: GrafanaThemeType*/ = { ...defaultTheme, + type: 'light', name: 'Grafana Light', colors: { ...basicColors, diff --git a/packages/grafana-ui/src/types/index.ts b/packages/grafana-ui/src/types/index.ts index e23b5e63af8..81bdf741f30 100644 --- a/packages/grafana-ui/src/types/index.ts +++ b/packages/grafana-ui/src/types/index.ts @@ -1,14 +1,7 @@ + export * from './data'; export * from './time'; export * from './panel'; export * from './plugin'; export * from './datasource'; - -export enum GrafanaTheme { - Light = 'light', - Dark = 'dark', -} - -export interface Themeable { - theme?: GrafanaTheme; -} +export * from './theme'; diff --git a/packages/grafana-ui/src/theme.d.ts b/packages/grafana-ui/src/types/theme.ts similarity index 92% rename from packages/grafana-ui/src/theme.d.ts rename to packages/grafana-ui/src/types/theme.ts index 015bcd16136..0fc81fa24e1 100644 --- a/packages/grafana-ui/src/theme.d.ts +++ b/packages/grafana-ui/src/types/theme.ts @@ -1,4 +1,10 @@ -export interface GrafanaThemeType { +export enum GrafanaThemeType { + Light = 'light', + Dark = 'dark', +} + +export interface GrafanaTheme { + type: GrafanaThemeType; name: string; // TODO: not sure if should be a part of theme brakpoints: { @@ -112,5 +118,7 @@ export interface GrafanaThemeType { headingColor: string; }; } -export function getTheme(): GrafanaThemeType -export function mockTheme(themeMock: Partial): () => void + +export interface Themeable { + theme: GrafanaTheme; +} diff --git a/packages/grafana-ui/src/utils/storybook/withTheme.tsx b/packages/grafana-ui/src/utils/storybook/withTheme.tsx new file mode 100644 index 00000000000..b1a9bca013a --- /dev/null +++ b/packages/grafana-ui/src/utils/storybook/withTheme.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { RenderFunction } from '@storybook/react'; +import { ThemeContext } from '../../themes/ThemeContext'; +import { select } from '@storybook/addon-knobs'; +import { getTheme } from '../../themes'; +import { GrafanaThemeType } from '../../types'; + +const ThemableStory: React.FunctionComponent<{}> = ({ children }) => { + const themeKnob = select( + 'Theme', + { + Default: GrafanaThemeType.Dark, + Light: GrafanaThemeType.Light, + Dark: GrafanaThemeType.Dark, + }, + GrafanaThemeType.Dark + ); + + return ( + + {children} + + + ); +}; + +export const renderComponentWithTheme = (component: React.ComponentType, props: any) => { + return ( + + {theme => { + return React.createElement(component, { + ...props, + theme, + }); + }} + + ); +}; + +export const withTheme = (story: RenderFunction) => {story()}; diff --git a/scripts/webpack/getThemeVariable.js b/scripts/webpack/getThemeVariable.js index c0b6bc4ed79..0db0a9842a8 100644 --- a/scripts/webpack/getThemeVariable.js +++ b/scripts/webpack/getThemeVariable.js @@ -1,8 +1,8 @@ const sass = require('node-sass'); const sassUtils = require('node-sass-utils')(sass); -const { getTheme } = require('../../packages/grafana-ui/src/theme'); const { get } = require('lodash'); const tinycolor = require('tinycolor2'); +const { getTheme } = require('@grafana/ui/src/themes'); const units = ['rem', 'em', 'vh', 'vw', 'vmin', 'vmax', 'ex', '%', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ch']; const matchDimension = value => value.match(/[a-zA-Z]+|[0-9]+/g); @@ -13,12 +13,11 @@ const isHex = value => { }; const isDimension = value => { - if( typeof value !== "string") { + if (typeof value !== 'string') { return false; } - const [val, unit] = matchDimension(value); - return units.indexOf(unit) > -1 + return units.indexOf(unit) > -1; }; /** @@ -40,11 +39,9 @@ function getThemeVariable(variablePath, themeName) { } if (isDimension(variable)) { - const [value, unit] = matchDimension(variable) - - const tmp = new sassUtils.SassDimension(parseInt(value,10), unit); - // debugger - return sassUtils.castToSass(tmp) + const [value, unit] = matchDimension(variable); + const dimension = new sassUtils.SassDimension(parseInt(value, 10), unit); + return sassUtils.castToSass(dimension); } return sassUtils.castToSass(variable);