mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Theme: Extract extra theme definitions into their own directory (#98610)
extract theme definitions into their own directory
This commit is contained in:
parent
1ba9a27f70
commit
2e969686f0
@ -277,7 +277,7 @@ export function createColors(colors: ThemeColorsInput): ThemeColors {
|
|||||||
const getRichColor = ({ color, name }: GetRichColorProps): ThemeRichColor => {
|
const getRichColor = ({ color, name }: GetRichColorProps): ThemeRichColor => {
|
||||||
color = { ...color, name };
|
color = { ...color, name };
|
||||||
if (!color.main) {
|
if (!color.main) {
|
||||||
throw new Error(`Missing main color for ${name}`);
|
color.main = base[name].main;
|
||||||
}
|
}
|
||||||
if (!color.text) {
|
if (!color.text) {
|
||||||
color.text = color.main;
|
color.text = color.main;
|
||||||
@ -318,7 +318,9 @@ export function createColors(colors: ThemeColorsInput): ThemeColors {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RichColorNames = 'primary' | 'secondary' | 'info' | 'error' | 'success' | 'warning';
|
||||||
|
|
||||||
interface GetRichColorProps {
|
interface GetRichColorProps {
|
||||||
color: Partial<ThemeRichColor>;
|
color: Partial<ThemeRichColor>;
|
||||||
name: string;
|
name: RichColorNames;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ export interface NewThemeOptions {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
export function createTheme(options: NewThemeOptions = {}): GrafanaTheme2 {
|
export function createTheme(options: NewThemeOptions = {}): GrafanaTheme2 {
|
||||||
const {
|
const {
|
||||||
|
name,
|
||||||
colors: colorsInput = {},
|
colors: colorsInput = {},
|
||||||
spacing: spacingInput = {},
|
spacing: spacingInput = {},
|
||||||
shape: shapeInput = {},
|
shape: shapeInput = {},
|
||||||
@ -40,7 +41,7 @@ export function createTheme(options: NewThemeOptions = {}): GrafanaTheme2 {
|
|||||||
const visualization = createVisualizationColors(colors);
|
const visualization = createVisualizationColors(colors);
|
||||||
|
|
||||||
const theme = {
|
const theme = {
|
||||||
name: colors.mode === 'dark' ? 'Dark' : 'Light',
|
name: (name ?? colors.mode === 'dark') ? 'Dark' : 'Light',
|
||||||
isDark: colors.mode === 'dark',
|
isDark: colors.mode === 'dark',
|
||||||
isLight: colors.mode === 'light',
|
isLight: colors.mode === 'light',
|
||||||
colors,
|
colors,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Registry, RegistryItem } from '../utils/Registry';
|
import { Registry, RegistryItem } from '../utils/Registry';
|
||||||
|
|
||||||
import { createColors } from './createColors';
|
|
||||||
import { createTheme } from './createTheme';
|
import { createTheme } from './createTheme';
|
||||||
|
import * as extraThemes from './themeDefinitions';
|
||||||
import { GrafanaTheme2 } from './types';
|
import { GrafanaTheme2 } from './types';
|
||||||
|
|
||||||
export interface ThemeRegistryItem extends RegistryItem {
|
export interface ThemeRegistryItem extends RegistryItem {
|
||||||
@ -23,104 +23,44 @@ export function getThemeById(id: string): GrafanaTheme2 {
|
|||||||
* For internal use only
|
* For internal use only
|
||||||
*/
|
*/
|
||||||
export function getBuiltInThemes(includeExtras?: boolean) {
|
export function getBuiltInThemes(includeExtras?: boolean) {
|
||||||
return themeRegistry.list().filter((item) => {
|
const themes = themeRegistry.list().filter((item) => {
|
||||||
return includeExtras ? true : !item.isExtra;
|
return includeExtras ? true : !item.isExtra;
|
||||||
});
|
});
|
||||||
|
// sort themes alphabetically, but put built-in themes (default, dark, light, system) first
|
||||||
|
const sortedThemes = themes.sort((a, b) => {
|
||||||
|
if (a.isExtra && !b.isExtra) {
|
||||||
|
return 1;
|
||||||
|
} else if (!a.isExtra && b.isExtra) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return a.name.localeCompare(b.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return sortedThemes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There is also a backend list at services/perferences/themes.go
|
* There is also a backend list at pkg/services/preference/themes.go
|
||||||
*/
|
*/
|
||||||
const themeRegistry = new Registry<ThemeRegistryItem>(() => {
|
const themeRegistry = new Registry<ThemeRegistryItem>(() => {
|
||||||
return [
|
return [
|
||||||
{ id: 'system', name: 'System preference', build: getSystemPreferenceTheme },
|
{ id: 'system', name: 'System preference', build: getSystemPreferenceTheme },
|
||||||
{ id: 'dark', name: 'Dark', build: () => createTheme({ colors: { mode: 'dark' } }) },
|
{ id: 'dark', name: 'Dark', build: () => createTheme({ colors: { mode: 'dark' } }) },
|
||||||
{ id: 'light', name: 'Light', build: () => createTheme({ colors: { mode: 'light' } }) },
|
{ id: 'light', name: 'Light', build: () => createTheme({ colors: { mode: 'light' } }) },
|
||||||
{ id: 'debug', name: 'Debug', build: createDebug, isExtra: true },
|
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const [id, theme] of Object.entries(extraThemes)) {
|
||||||
|
themeRegistry.register({
|
||||||
|
id,
|
||||||
|
name: theme.name ?? '',
|
||||||
|
build: () => createTheme(theme),
|
||||||
|
isExtra: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getSystemPreferenceTheme() {
|
function getSystemPreferenceTheme() {
|
||||||
const mediaResult = window.matchMedia('(prefers-color-scheme: dark)');
|
const mediaResult = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
const id = mediaResult.matches ? 'dark' : 'light';
|
const id = mediaResult.matches ? 'dark' : 'light';
|
||||||
return getThemeById(id);
|
return getThemeById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* a very ugly theme that is useful for debugging and checking if the theme is applied correctly
|
|
||||||
* borders are red,
|
|
||||||
* backgrounds are blue,
|
|
||||||
* text is yellow,
|
|
||||||
* and grafana loves you <3
|
|
||||||
* (also corners are rounded, action states (hover, focus, selected) are purple)
|
|
||||||
*/
|
|
||||||
function createDebug(): GrafanaTheme2 {
|
|
||||||
const baseDarkColors = createColors({
|
|
||||||
mode: 'dark',
|
|
||||||
});
|
|
||||||
|
|
||||||
return createTheme({
|
|
||||||
name: 'Debug',
|
|
||||||
colors: {
|
|
||||||
mode: 'dark',
|
|
||||||
background: {
|
|
||||||
canvas: '#000033',
|
|
||||||
primary: '#000044',
|
|
||||||
secondary: '#000055',
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
primary: '#bbbb00',
|
|
||||||
secondary: '#888800',
|
|
||||||
disabled: '#444400',
|
|
||||||
link: '#dddd00',
|
|
||||||
maxContrast: '#ffff00',
|
|
||||||
},
|
|
||||||
border: {
|
|
||||||
weak: '#ff000044',
|
|
||||||
medium: '#ff000088',
|
|
||||||
strong: '#ff0000ff',
|
|
||||||
},
|
|
||||||
primary: {
|
|
||||||
...baseDarkColors.primary,
|
|
||||||
border: '#ff000088',
|
|
||||||
text: '#cccc00',
|
|
||||||
contrastText: '#ffff00',
|
|
||||||
shade: '#9900dd',
|
|
||||||
},
|
|
||||||
secondary: {
|
|
||||||
...baseDarkColors.secondary,
|
|
||||||
border: '#ff000088',
|
|
||||||
text: '#cccc00',
|
|
||||||
contrastText: '#ffff00',
|
|
||||||
shade: '#9900dd',
|
|
||||||
},
|
|
||||||
info: {
|
|
||||||
...baseDarkColors.info,
|
|
||||||
shade: '#9900dd',
|
|
||||||
},
|
|
||||||
warning: {
|
|
||||||
...baseDarkColors.warning,
|
|
||||||
shade: '#9900dd',
|
|
||||||
},
|
|
||||||
success: {
|
|
||||||
...baseDarkColors.success,
|
|
||||||
shade: '#9900dd',
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
...baseDarkColors.error,
|
|
||||||
shade: '#9900dd',
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
hover: '#9900dd',
|
|
||||||
focus: '#6600aa',
|
|
||||||
selected: '#440088',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
shape: {
|
|
||||||
borderRadius: 8,
|
|
||||||
},
|
|
||||||
spacing: {
|
|
||||||
gridSize: 10,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
70
packages/grafana-data/src/themes/themeDefinitions/debug.ts
Normal file
70
packages/grafana-data/src/themes/themeDefinitions/debug.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { NewThemeOptions } from '../createTheme';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a very ugly theme that is useful for debugging and checking if the theme is applied correctly
|
||||||
|
* borders are red,
|
||||||
|
* backgrounds are blue,
|
||||||
|
* text is yellow,
|
||||||
|
* and grafana loves you <3
|
||||||
|
* (also corners are rounded, action states (hover, focus, selected) are purple)
|
||||||
|
*/
|
||||||
|
const debugTheme: NewThemeOptions = {
|
||||||
|
name: 'Debug',
|
||||||
|
colors: {
|
||||||
|
mode: 'dark',
|
||||||
|
background: {
|
||||||
|
canvas: '#000033',
|
||||||
|
primary: '#000044',
|
||||||
|
secondary: '#000055',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
primary: '#bbbb00',
|
||||||
|
secondary: '#888800',
|
||||||
|
disabled: '#444400',
|
||||||
|
link: '#dddd00',
|
||||||
|
maxContrast: '#ffff00',
|
||||||
|
},
|
||||||
|
border: {
|
||||||
|
weak: '#ff000044',
|
||||||
|
medium: '#ff000088',
|
||||||
|
strong: '#ff0000ff',
|
||||||
|
},
|
||||||
|
primary: {
|
||||||
|
border: '#ff000088',
|
||||||
|
text: '#cccc00',
|
||||||
|
contrastText: '#ffff00',
|
||||||
|
shade: '#9900dd',
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
border: '#ff000088',
|
||||||
|
text: '#cccc00',
|
||||||
|
contrastText: '#ffff00',
|
||||||
|
shade: '#9900dd',
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
shade: '#9900dd',
|
||||||
|
},
|
||||||
|
warning: {
|
||||||
|
shade: '#9900dd',
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
shade: '#9900dd',
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
shade: '#9900dd',
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
hover: '#9900dd',
|
||||||
|
focus: '#6600aa',
|
||||||
|
selected: '#440088',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
spacing: {
|
||||||
|
gridSize: 10,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default debugTheme;
|
@ -0,0 +1 @@
|
|||||||
|
export { default as debug } from './debug';
|
Loading…
Reference in New Issue
Block a user