Theme: V8 Theme updates (#33050)

* GraphNG: Use new theme props

* Minor fix to letterspacing in button

* Minor tweaks

* Updated

* Revert to roboto

* Added concept of a dark or white base

* Style updates

* Sass

* Updated light text blue

* updates

* reverting button group design

* Fixed tests

* updates

* Updated tests
This commit is contained in:
Torkel Ödegaard
2021-04-16 09:48:52 +02:00
committed by GitHub
parent da03175d0b
commit 66485b3e70
51 changed files with 318 additions and 182 deletions

View File

@@ -34,7 +34,7 @@ export const colors = {
lightBorder1: '#E4E7E7',
blueDarkMain: '#4165F5',
blueDarkText: '#33a2e5', // '#5790FF',
blueDarkText: '#58a6ff', //'#33a2e5', // '#5790FF',
redDarkMain: '#D10E5C',
redDarkText: '#FF5286',
greenDarkMain: '#1A7F4B',
@@ -43,7 +43,7 @@ export const colors = {
orangeDarkText: '#F8D06B',
blueLightMain: '#3871DC',
blueLightText: '#1F62E0',
blueLightText: '#0465d7', // '#1F62E0',
redLightMain: '#E0226E',
redLightText: '#CF0E5B',
greenLightMain: '#1A7F4B',

View File

@@ -79,10 +79,12 @@ export type ThemePaletteInput = DeepPartial<ThemePaletteBase<ThemePaletteColor>>
class DarkPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
mode: ThemePaletteMode = 'dark';
whiteBase = '201, 209, 217';
text = {
primary: 'rgba(255, 255, 255, 0.77)',
secondary: 'rgba(255, 255, 255, 0.50)',
disabled: 'rgba(255, 255, 255, 0.35)',
primary: `rgb(${this.whiteBase})`,
secondary: `rgba(${this.whiteBase}, 0.65)`,
disabled: `rgba(${this.whiteBase}, 0.40)`,
link: colors.blueDarkText,
maxContrast: colors.white,
};
@@ -94,10 +96,10 @@ class DarkPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
};
secondary = {
main: 'rgba(255,255,255,0.1)',
shade: 'rgba(255,255,255,0.15)',
text: 'rgba(255,255,255,0.13)',
contrastText: 'rgba(255, 255, 255, 0.8)',
main: `rgba(${this.whiteBase}, 0.1)`,
shade: `rgba(${this.whiteBase}, 0.15)`,
text: `rgba(${this.whiteBase}, 0.13)`,
contrastText: `rgb(${this.whiteBase})`,
};
info = this.primary;
@@ -121,19 +123,19 @@ class DarkPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
layer1 = colors.gray10;
layer2 = colors.gray15;
divider = 'rgba(218,224,254,0.06)';
divider = `rgba(${this.whiteBase}, 0.10)`;
border0 = this.layer1;
border1 = 'rgba(218,224,254,0.15)';
border2 = 'rgba(218,224,254,0.20)';
border1 = `rgba(${this.whiteBase}, 0.15)`;
border2 = `rgba(${this.whiteBase}, 0.20)`;
action = {
hover: 'rgba(255, 255, 255, 0.08)',
selected: 'rgba(255, 255, 255, 0.12)',
focus: 'rgba(255, 255, 255, 0.16)',
hover: `rgba(${this.whiteBase}, 0.08)`,
selected: `rgba(${this.whiteBase}, 0.12)`,
focus: `rgba(${this.whiteBase}, 0.16)`,
hoverOpacity: 0.08,
disabledText: this.text.disabled,
disabledBackground: 'rgba(255,255,255,0.07)',
disabledBackground: `rgba(${this.whiteBase}, 0.07)`,
disabledOpacity: 0.38,
};
@@ -143,13 +145,15 @@ class DarkPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
};
contrastThreshold = 3;
hoverFactor = 0.15;
hoverFactor = 0.03;
tonalOffset = 0.15;
}
class LightPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
mode: ThemePaletteMode = 'light';
blackBase = '36, 41, 46';
primary = {
main: colors.blueLightMain,
border: colors.blueLightText,
@@ -157,9 +161,9 @@ class LightPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
};
secondary = {
main: 'rgba(0,0,0,0.11)',
shade: 'rgba(0,0,0,0.16)',
contrastText: 'rgba(0, 0, 0, 0.75)',
main: `rgba(${this.blackBase}, 0.11)`,
shade: `rgba(${this.blackBase}, 0.16)`,
contrastText: `rgba(${this.blackBase}, 1)`,
};
info = {
@@ -184,9 +188,9 @@ class LightPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
};
text = {
primary: 'rgba(0, 0, 0, 0.75)',
secondary: 'rgba(0, 0, 0, 0.60)',
disabled: 'rgba(0, 0, 0, 0.45)',
primary: `rgba(${this.blackBase}, 1)`,
secondary: `rgba(${this.blackBase}, 0.75)`,
disabled: `rgba(${this.blackBase}, 0.50)`,
link: this.primary.text,
maxContrast: colors.black,
};
@@ -195,18 +199,18 @@ class LightPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
layer1 = colors.white;
layer2 = colors.gray100;
divider = 'rgba(0, 2, 78, 0.07)';
divider = `rgba(${this.blackBase}, 0.12)`;
border0 = this.layer1;
border1 = 'rgba(0, 2, 78, 0.20)';
border2 = 'rgba(0, 2, 78, 0.30)';
border1 = `rgba(${this.blackBase}, 0.30)`;
border2 = `rgba(${this.blackBase}, 0.40)`;
action = {
hover: 'rgba(0, 0, 0, 0.04)',
selected: 'rgba(0, 0, 0, 0.08)',
hover: `rgba(${this.blackBase}, 0.04)`,
selected: `rgba(${this.blackBase}, 0.08)`,
hoverOpacity: 0.08,
focus: 'rgba(0, 0, 0, 0.12)',
disabledBackground: 'rgba(0,0,0,0.07)',
focus: `rgba(${this.blackBase}, 0.12)`,
disabledBackground: `rgba(${this.blackBase}, 0.07)`,
disabledText: this.text.disabled,
disabledOpacity: 0.38,
};
@@ -217,7 +221,7 @@ class LightPalette implements ThemePaletteBase<Partial<ThemePaletteColor>> {
};
contrastThreshold = 3;
hoverFactor = 0.15;
hoverFactor = 0.03;
tonalOffset = 0.2;
}
@@ -240,7 +244,7 @@ export function createPalette(palette: ThemePaletteInput): ThemePalette {
function getContrastText(background: string) {
const contrastText =
getContrastRatio(background, dark.text.primary) >= contrastThreshold
getContrastRatio(background, dark.text.maxContrast) >= contrastThreshold
? dark.text.maxContrast
: light.text.maxContrast;
// todo, need color framework

View File

@@ -63,7 +63,7 @@ export interface ThemeTypographyInput {
htmlFontSize?: number;
}
const defaultFontFamily = '"Inter", "Helvetica", "Arial", sans-serif';
const defaultFontFamily = '"Roboto", "Helvetica", "Arial", sans-serif';
const defaultFontFamilyMonospace = "'Roboto Mono', monospace";
export function createTypography(palette: ThemePalette, typographyInput: ThemeTypographyInput = {}): ThemeTypography {
@@ -104,19 +104,19 @@ export function createTypography(palette: ThemePalette, typographyInput: ThemeTy
fontWeight,
fontSize: pxToRem(size),
lineHeight,
letterSpacing: `${letterSpacing}em`,
...(fontFamily === defaultFontFamily ? { letterSpacing: `${round(letterSpacing / size)}em` } : {}),
...casing,
});
const variants = {
h1: buildVariant(fontWeightMedium, 28, 1.2, -0.01),
h2: buildVariant(fontWeightMedium, 24, 1.2, -0.01),
h3: buildVariant(fontWeightMedium, 21, 1.3, -0.01),
h4: buildVariant(fontWeightRegular, 18, 1.4, -0.005),
h5: buildVariant(fontWeightRegular, 16, 1.334, -0.005),
h6: buildVariant(fontWeightRegular, 14, 1.6, -0.005),
body: buildVariant(fontWeightRegular, 14, 1.5, -0.005),
bodySmall: buildVariant(fontWeightRegular, 12, 1.5, -0.005),
h1: buildVariant(fontWeightLight, 28, 1.167, -0.25),
h2: buildVariant(fontWeightLight, 24, 1.2, 0),
h3: buildVariant(fontWeightRegular, 21, 1.167, 0),
h4: buildVariant(fontWeightRegular, 18, 1.235, 0.25),
h5: buildVariant(fontWeightRegular, 16, 1.334, 0),
h6: buildVariant(fontWeightMedium, 14, 1.6, 0.15),
body: buildVariant(fontWeightRegular, 14, 1.5, 0.15),
bodySmall: buildVariant(fontWeightRegular, 12, 1.5, 0.15),
};
const size = {
@@ -141,3 +141,7 @@ export function createTypography(palette: ThemePalette, typographyInput: ThemeTy
...variants,
};
}
function round(value: number) {
return Math.round(value * 1e5) / 1e5;
}

View File

@@ -43,6 +43,7 @@ export const parameters = {
dark: GrafanaDark,
light: GrafanaLight,
},
layout: 'fullscreen',
actions: { argTypesRegex: '^on[A-Z].*' },
options: {
showPanel: true,

View File

@@ -23,11 +23,11 @@ const createTheme = (theme: GrafanaTheme) => {
fontCode: theme.v2.typography.fontFamilyMonospace,
// Text colors
textColor: theme.v2.palette.text.primary,
textColor: theme.v2.palette.primary.text,
textInverseColor: theme.v2.palette.primary.contrastText,
// Toolbar default and active colors
barTextColor: theme.v2.palette.primary.text,
barTextColor: theme.v2.palette.text.primary,
barSelectedColor: theme.v2.palette.emphasize(theme.v2.palette.primary.text),
barBg: theme.v2.palette.layer1,

View File

@@ -2,7 +2,7 @@
exports[`CustomScrollbar renders correctly 1`] = `
<div
className="css-1xduqpt"
className="css-d4ozb2"
style={
Object {
"height": "auto",

View File

@@ -3,7 +3,6 @@ import { GrafanaTheme } from '@grafana/data';
import { focusCss } from '../../themes/mixins';
import { css as cssCore } from '@emotion/react';
import { css } from '@emotion/css';
import tinycolor from 'tinycolor2';
export const getFocusStyle = (theme: GrafanaTheme) => css`
&:focus {
@@ -12,11 +11,11 @@ export const getFocusStyle = (theme: GrafanaTheme) => css`
`;
export const getStyles = stylesFactory((theme: GrafanaTheme, isHorizontal: boolean) => {
const { spacing, palette } = theme;
const railColor = theme.isLight ? palette.gray5 : palette.dark6;
const trackColor = theme.isLight ? palette.blue85 : palette.blue77;
const handleColor = theme.isLight ? palette.blue85 : palette.blue80;
const blueOpacity = tinycolor(handleColor).setAlpha(0.2).toString();
const { spacing } = theme;
const railColor = theme.v2.palette.border2;
const trackColor = theme.v2.palette.primary.main;
const handleColor = theme.v2.palette.primary.main;
const blueOpacity = theme.v2.palette.primary.transparent;
const hoverSyle = `box-shadow: 0px 0px 0px 6px ${blueOpacity}`;
return {
@@ -37,6 +36,7 @@ export const getStyles = stylesFactory((theme: GrafanaTheme, isHorizontal: boole
.rc-slider-handle {
border: none;
background-color: ${handleColor};
box-shadow: ${theme.v2.shadows.z1};
cursor: pointer;
}
.rc-slider-handle:hover,
@@ -51,7 +51,6 @@ export const getStyles = stylesFactory((theme: GrafanaTheme, isHorizontal: boole
}
.rc-slider-rail {
background-color: ${railColor};
border: 1px solid ${railColor};
cursor: pointer;
}
`,

View File

@@ -9,7 +9,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
label: counter;
margin-left: ${theme.spacing.sm};
border-radius: ${theme.spacing.lg};
background-color: ${theme.colors.bg2};
background-color: ${theme.v2.palette.action.hover};
padding: ${theme.spacing.xxs} ${theme.spacing.sm};
color: ${theme.colors.textWeak};
font-weight: ${theme.typography.weight.semibold};

View File

@@ -50,16 +50,14 @@ export class UPlotAxisBuilder extends PlotConfigBuilder<AxisProps, Axis> {
theme,
} = this.props;
let { typography } = theme;
const font = `12px ${theme.v2.typography.fontFamily}`;
let font = `${typography.size.sm} ${typography.fontFamily.sansSerif}`;
const gridColor = theme.isDark ? theme.palette.gray25 : theme.palette.gray90;
const gridColor = theme.v2.isDark ? 'rgba(240, 250, 255, 0.09)' : 'rgba(0, 10, 23, 0.09)';
let config: Axis = {
scale: scaleKey,
show,
stroke: theme.colors.text,
stroke: theme.v2.palette.text.primary,
side: getUPlotSideFromAxis(placement),
font,
labelFont: font,

View File

@@ -299,15 +299,15 @@ describe('UPlotConfigBuilder', () => {
Object {
"axes": Array [
Object {
"font": "12px 'Inter', 'Helvetica Neue', Arial, sans-serif",
"font": "12px \\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif",
"gap": 5,
"grid": Object {
"show": false,
"stroke": "#2c3235",
"stroke": "rgba(240, 250, 255, 0.09)",
"width": 1,
},
"label": "test label",
"labelFont": "12px 'Inter', 'Helvetica Neue', Arial, sans-serif",
"labelFont": "12px \\"Roboto\\", \\"Helvetica\\", \\"Arial\\", sans-serif",
"labelSize": 18,
"scale": "scale-x",
"show": true,
@@ -315,10 +315,10 @@ describe('UPlotConfigBuilder', () => {
"size": [Function],
"space": [Function],
"splits": undefined,
"stroke": "rgba(255, 255, 255, 0.77)",
"stroke": "rgb(201, 209, 217)",
"ticks": Object {
"show": true,
"stroke": "#2c3235",
"stroke": "rgba(240, 250, 255, 0.09)",
"width": 1,
},
"timeZone": "browser",

View File

@@ -51,6 +51,10 @@ export function getElementStyles(theme: GrafanaThemeV2) {
margin: 0 0 ${theme.spacing(2)};
}
button {
letter-spacing: ${theme.typography.body.letterSpacing};
}
// Ex: 14px base font * 85% = about 12px
small {
font-size: ${theme.typography.bodySmall.fontSize};

View File

@@ -31,7 +31,7 @@ const theme: GrafanaThemeCommons = {
name: 'Grafana Default',
typography: {
fontFamily: {
sansSerif: "'Inter', 'Helvetica Neue', Arial, sans-serif",
sansSerif: "'Roboto', 'Helvetica Neue', Arial, sans-serif",
monospace: "'Roboto Mono', monospace",
},
size: {

View File

@@ -21,7 +21,7 @@ export function getCanvasContext() {
* @beta
*/
export function measureText(text: string, fontSize: number): TextMetrics {
const fontStyle = `${fontSize}px 'Inter'`;
const fontStyle = `${fontSize}px 'Roboto'`;
const cacheKey = text + fontStyle;
const fromCache = cache[cacheKey];

View File

@@ -1,14 +1,18 @@
import React from 'react';
import { GlobalStyles } from '../../themes';
import { GlobalStyles, useTheme } from '../../themes';
import { RenderFunction } from '../../types';
const PaddedStory: React.FunctionComponent<{}> = ({ children }) => {
const theme = useTheme();
return (
<div
style={{
width: '100%',
padding: '20px',
display: 'flex',
minHeight: '80vh',
background: `${theme.v2.palette.layer1}`,
}}
>
<GlobalStyles />