Browse Source

Implemented theme context and renamed/moved theme related types

Dominik Prokop 6 years ago
parent
commit
1bc007e29c

+ 2 - 1
packages/grafana-ui/src/index.ts

@@ -1,4 +1,5 @@
 export * from './components';
 export * from './components';
 export * from './types';
 export * from './types';
 export * from './utils';
 export * from './utils';
-export * from './theme';
+export * from './themes';
+export * from './themes/ThemeContext';

+ 20 - 0
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<T, K> = Pick<T, Exclude<keyof T, K>>;
+type Subtract<T, K> = Omit<T, keyof K>;
+
+// Use Grafana Dark theme by default
+export const ThemeContext = React.createContext(getTheme(GrafanaThemeType.Dark));
+
+export const withTheme = <P extends Themeable>(Component: React.ComponentType<P>) => {
+  const WithTheme: React.FunctionComponent<Subtract<P, Themeable>> = props => {
+    // @ts-ignore
+    return <ThemeContext.Consumer>{theme => <Component {...props} theme={theme} />}</ThemeContext.Consumer>;
+  };
+
+  WithTheme.displayName = `WithTheme(${Component.displayName})`;
+
+  return WithTheme;
+};

+ 2 - 1
packages/grafana-ui/src/themes/dark.js

@@ -4,7 +4,7 @@ const defaultTheme = require('./default');
 const tinycolor = require('tinycolor2');
 const tinycolor = require('tinycolor2');
 
 
 const basicColors = {
 const basicColors = {
-  black: '#00ff00',
+  black: '#000000',
   white: '#ffffff',
   white: '#ffffff',
   dark1: '#141414',
   dark1: '#141414',
   dark2: '#1f1f20',
   dark2: '#1f1f20',
@@ -33,6 +33,7 @@ const basicColors = {
 
 
 const darkTheme = {
 const darkTheme = {
   ...defaultTheme,
   ...defaultTheme,
+  type: 'dark',
   name: 'Grafana Dark',
   name: 'Grafana Dark',
   colors:  {
   colors:  {
     ...basicColors,
     ...basicColors,

+ 4 - 0
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<GrafanaTheme>): () => void

+ 3 - 3
packages/grafana-ui/src/theme.js → 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);
 const getTheme = name => (name === 'light' ? lightTheme : darkTheme);
 
 
@@ -11,5 +11,5 @@ const mockTheme = mock => {
 
 
 module.exports = {
 module.exports = {
   getTheme,
   getTheme,
-  mockTheme,
+  mockTheme
 };
 };

+ 1 - 0
packages/grafana-ui/src/themes/light.js

@@ -33,6 +33,7 @@ const basicColors = {
 
 
 const lightTheme/*: GrafanaThemeType*/ = {
 const lightTheme/*: GrafanaThemeType*/ = {
   ...defaultTheme,
   ...defaultTheme,
+  type: 'light',
   name: 'Grafana Light',
   name: 'Grafana Light',
   colors:  {
   colors:  {
     ...basicColors,
     ...basicColors,

+ 2 - 9
packages/grafana-ui/src/types/index.ts

@@ -1,14 +1,7 @@
+
 export * from './data';
 export * from './data';
 export * from './time';
 export * from './time';
 export * from './panel';
 export * from './panel';
 export * from './plugin';
 export * from './plugin';
 export * from './datasource';
 export * from './datasource';
-
-export enum GrafanaTheme {
-  Light = 'light',
-  Dark = 'dark',
-}
-
-export interface Themeable {
-  theme?: GrafanaTheme;
-}
+export * from './theme';

+ 11 - 3
packages/grafana-ui/src/theme.d.ts → 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;
   name: string;
   // TODO: not sure if should be a part of theme
   // TODO: not sure if should be a part of theme
   brakpoints: {
   brakpoints: {
@@ -112,5 +118,7 @@ export interface GrafanaThemeType {
     headingColor: string;
     headingColor: string;
   };
   };
 }
 }
-export function getTheme(): GrafanaThemeType
-export function mockTheme(themeMock: Partial<GrafanaThemeType>): () => void
+
+export interface Themeable {
+  theme: GrafanaTheme;
+}

+ 40 - 0
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 (
+    <ThemeContext.Provider value={getTheme(themeKnob)}>
+      {children}
+    </ThemeContext.Provider>
+
+  );
+};
+
+export const renderComponentWithTheme = (component: React.ComponentType<any>, props: any) => {
+  return (
+    <ThemeContext.Consumer>
+      {theme => {
+        return React.createElement(component, {
+          ...props,
+          theme,
+        });
+      }}
+    </ThemeContext.Consumer>
+  );
+};
+
+export const withTheme = (story: RenderFunction) => <ThemableStory>{story()}</ThemableStory>;

+ 6 - 9
scripts/webpack/getThemeVariable.js

@@ -1,8 +1,8 @@
 const sass = require('node-sass');
 const sass = require('node-sass');
 const sassUtils = require('node-sass-utils')(sass);
 const sassUtils = require('node-sass-utils')(sass);
-const { getTheme } = require('../../packages/grafana-ui/src/theme');
 const { get } = require('lodash');
 const { get } = require('lodash');
 const tinycolor = require('tinycolor2');
 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 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);
 const matchDimension = value => value.match(/[a-zA-Z]+|[0-9]+/g);
@@ -13,12 +13,11 @@ const isHex = value => {
 };
 };
 
 
 const isDimension = value => {
 const isDimension = value => {
-  if( typeof value !== "string") {
+  if (typeof value !== 'string') {
     return false;
     return false;
   }
   }
-
   const [val, unit] = matchDimension(value);
   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)) {
   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);
   return sassUtils.castToSass(variable);