Compare commits

...

8 Commits

Author SHA1 Message Date
Ashley Harrison
a34787d2a4 make name and id required in the theme schema 2026-01-09 15:42:57 +00:00
Ashley Harrison
2ad1f04cf3 generate theme list at build time, don't do it at runtime 2026-01-09 14:52:52 +00:00
Ashley Harrison
a52ac632b7 generate theme json schema from zod 2026-01-08 10:42:33 +00:00
Ashley Harrison
2d43af56b5 error tidy up p2 2026-01-07 18:12:43 +00:00
Ashley Harrison
164b927f9d error tidy up 2026-01-07 18:12:04 +00:00
Ashley Harrison
29c5edf3ca use zod 2026-01-07 18:09:41 +00:00
Ashley Harrison
a5747231d3 automatically discover extra themes in go backend 2026-01-06 16:32:57 +00:00
Ashley Harrison
1c2ffcb653 convert all theme files to json 2026-01-06 13:56:24 +00:00
48 changed files with 2005 additions and 1535 deletions

View File

@@ -135,7 +135,7 @@ i18n-extract-enterprise:
@echo "Skipping i18n extract for Enterprise: not enabled"
else
i18n-extract-enterprise:
@echo "Extracting i18n strings for Enterprise"
@echo "Extracting i18n strings for Enterprise"
cd public/locales/enterprise && yarn run i18next-cli extract --sync-primary
endif
@@ -227,6 +227,10 @@ fix-cue:
gen-jsonnet:
go generate ./devenv/jsonnet
.PHONY: gen-themes
gen-themes:
go generate ./pkg/services/preference
.PHONY: update-workspace
update-workspace: gen-go
@echo "updating workspace"
@@ -244,6 +248,7 @@ build-go-fast: ## Build all Go binaries without updating workspace.
.PHONY: build-backend
build-backend: ## Build Grafana backend.
@echo "build backend"
$(MAKE) gen-themes
$(GO) run build.go $(GO_BUILD_FLAGS) build-backend
.PHONY: build-air

View File

@@ -62,8 +62,7 @@
"stats": "webpack --mode production --config scripts/webpack/webpack.prod.js --profile --json > compilation-stats.json",
"storybook": "yarn workspace @grafana/ui storybook --ci",
"storybook:build": "yarn workspace @grafana/ui storybook:build",
"themes-schema": "typescript-json-schema ./tsconfig.json NewThemeOptions --include 'packages/grafana-data/src/themes/createTheme.ts' --out public/app/features/theme-playground/schema.generated.json",
"themes-generate": "yarn themes-schema && esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --conditions=@grafana-app/source --platform=node --tsconfig=./scripts/cli/tsconfig.json | node",
"themes-generate": "yarn workspace @grafana/data themes-schema && esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --conditions=@grafana-app/source --platform=node --tsconfig=./scripts/cli/tsconfig.json | node",
"themes:usage": "eslint . --ignore-pattern '*.test.ts*' --ignore-pattern '*.spec.ts*' --cache --plugin '@grafana' --rule '{ @grafana/theme-token-usage: \"error\" }'",
"typecheck": "tsc --noEmit && yarn run packages:typecheck",
"plugins:build-bundled": "echo 'bundled plugins are no longer supported'",
@@ -254,7 +253,6 @@
"ts-jest": "29.4.0",
"ts-node": "10.9.2",
"typescript": "5.9.2",
"typescript-json-schema": "^0.65.1",
"webpack": "5.101.0",
"webpack-assets-manifest": "^5.1.0",
"webpack-cli": "6.0.1",
@@ -265,7 +263,7 @@
"webpackbar": "^7.0.0",
"yaml": "^2.0.0",
"yargs": "^18.0.0",
"zod": "^4.0.0"
"zod": "^4.3.0"
},
"dependencies": {
"@bsull/augurs": "^0.10.0",

View File

@@ -47,11 +47,12 @@
"LICENSE_APACHE2"
],
"scripts": {
"build": "tsc -p ./tsconfig.build.json && rollup -c rollup.config.ts --configPlugin esbuild",
"build": "yarn themes-schema && tsc -p ./tsconfig.build.json && rollup -c rollup.config.ts --configPlugin esbuild",
"clean": "rimraf ./dist ./compiled ./unstable ./package.tgz",
"typecheck": "tsc --emitDeclarationOnly false --noEmit",
"prepack": "cp package.json package.json.bak && node ../../scripts/prepare-npm-package.js",
"postpack": "mv package.json.bak package.json"
"postpack": "mv package.json.bak package.json",
"themes-schema": "tsx ./src/themes/scripts/generateSchema.ts"
},
"dependencies": {
"@braintree/sanitize-url": "7.0.1",
@@ -81,10 +82,12 @@
"tinycolor2": "1.6.0",
"tslib": "2.8.1",
"uplot": "1.6.32",
"xss": "^1.0.14"
"xss": "^1.0.14",
"zod": "^4.3.0"
},
"devDependencies": {
"@grafana/scenes": "6.38.0",
"@rollup/plugin-json": "6.1.0",
"@rollup/plugin-node-resolve": "16.0.1",
"@testing-library/react": "16.3.0",
"@types/history": "4.7.11",
@@ -101,6 +104,7 @@
"rollup": "^4.22.4",
"rollup-plugin-esbuild": "6.2.1",
"rollup-plugin-node-externals": "^8.0.0",
"tsx": "^4.21.0",
"typescript": "5.9.2"
},
"peerDependencies": {

View File

@@ -1,3 +1,4 @@
import json from '@rollup/plugin-json';
import { createRequire } from 'node:module';
import { entryPoint, plugins, esmOutput, cjsOutput } from '../rollup.config.parts';
@@ -8,13 +9,13 @@ const pkg = rq('./package.json');
export default [
{
input: entryPoint,
plugins,
plugins: [...plugins, json()],
output: [cjsOutput(pkg, 'grafana-data'), esmOutput(pkg, 'grafana-data')],
treeshake: false,
},
{
input: 'src/unstable.ts',
plugins,
plugins: [...plugins, json()],
output: [cjsOutput(pkg, 'grafana-data'), esmOutput(pkg, 'grafana-data')],
treeshake: false,
},

View File

@@ -106,3 +106,4 @@ export { findNumericFieldMinMax } from '../field/fieldOverrides';
export { type PanelOptionsSupplier } from '../panel/PanelPlugin';
export { sanitize, sanitizeUrl } from '../text/sanitize';
export { type NestedValueAccess, type NestedPanelOptions, isNestedPanelOptions } from '../utils/OptionsUIBuilders';
export { NewThemeOptionsSchema } from '../themes/createTheme';

View File

@@ -1,83 +1,103 @@
import { merge } from 'lodash';
import { z } from 'zod';
import { alpha, darken, emphasize, getContrastRatio, lighten } from './colorManipulator';
import { palette } from './palette';
import { DeepPartial, ThemeRichColor } from './types';
import { DeepRequired, ThemeRichColor, ThemeRichColorInputSchema } from './types';
const ThemeColorsModeSchema = z.enum(['light', 'dark']);
/** @internal */
export type ThemeColorsMode = 'light' | 'dark';
export type ThemeColorsMode = z.infer<typeof ThemeColorsModeSchema>;
const createThemeColorsBaseSchema = <TColor>(color: TColor) =>
z
.object({
mode: ThemeColorsModeSchema,
primary: color,
secondary: color,
info: color,
error: color,
success: color,
warning: color,
text: z.object({
primary: z.string().optional(),
secondary: z.string().optional(),
disabled: z.string().optional(),
link: z.string().optional(),
/** Used for auto white or dark text on colored backgrounds */
maxContrast: z.string().optional(),
}),
background: z.object({
/** Dashboard and body background */
canvas: z.string().optional(),
/** Primary content pane background (panels etc) */
primary: z.string().optional(),
/** Cards and elements that need to stand out on the primary background */
secondary: z.string().optional(),
/**
* For popovers and menu backgrounds. This is the same color as primary in most light themes but in dark
* themes it has a brighter shade to help give it contrast against the primary background.
**/
elevated: z.string().optional(),
}),
border: z.object({
weak: z.string().optional(),
medium: z.string().optional(),
strong: z.string().optional(),
}),
gradients: z.object({
brandVertical: z.string().optional(),
brandHorizontal: z.string().optional(),
}),
action: z.object({
/** Used for selected menu item / select option */
selected: z.string().optional(),
/**
* @alpha (Do not use from plugins)
* Used for selected items when background only change is not enough (Currently only used for FilterPill)
**/
selectedBorder: z.string().optional(),
/** Used for hovered menu item / select option */
hover: z.string().optional(),
/** Used for button/colored background hover opacity */
hoverOpacity: z.number().optional(),
/** Used focused menu item / select option */
focus: z.string().optional(),
/** Used for disabled buttons and inputs */
disabledBackground: z.string().optional(),
/** Disabled text */
disabledText: z.string().optional(),
/** Disablerd opacity */
disabledOpacity: z.number().optional(),
}),
hoverFactor: z.number(),
contrastThreshold: z.number(),
tonalOffset: z.number(),
})
.partial();
// Need to override the zod type to include the generic properly
/** @internal */
export interface ThemeColorsBase<TColor> {
mode: ThemeColorsMode;
export type ThemeColorsBase<TColor> = DeepRequired<
Omit<
z.infer<ReturnType<typeof createThemeColorsBaseSchema>>,
'primary' | 'secondary' | 'info' | 'error' | 'success' | 'warning'
>
> & {
primary: TColor;
secondary: TColor;
info: TColor;
error: TColor;
success: TColor;
warning: TColor;
text: {
primary: string;
secondary: string;
disabled: string;
link: string;
/** Used for auto white or dark text on colored backgrounds */
maxContrast: string;
};
background: {
/** Dashboard and body background */
canvas: string;
/** Primary content pane background (panels etc) */
primary: string;
/** Cards and elements that need to stand out on the primary background */
secondary: string;
/**
* For popovers and menu backgrounds. This is the same color as primary in most light themes but in dark
* themes it has a brighter shade to help give it contrast against the primary background.
**/
elevated: string;
};
border: {
weak: string;
medium: string;
strong: string;
};
gradients: {
brandVertical: string;
brandHorizontal: string;
};
action: {
/** Used for selected menu item / select option */
selected: string;
/**
* @alpha (Do not use from plugins)
* Used for selected items when background only change is not enough (Currently only used for FilterPill)
**/
selectedBorder: string;
/** Used for hovered menu item / select option */
hover: string;
/** Used for button/colored background hover opacity */
hoverOpacity: number;
/** Used focused menu item / select option */
focus: string;
/** Used for disabled buttons and inputs */
disabledBackground: string;
/** Disabled text */
disabledText: string;
/** Disablerd opacity */
disabledOpacity: number;
};
hoverFactor: number;
contrastThreshold: number;
tonalOffset: number;
}
};
export interface ThemeHoverStrengh {}
@@ -89,8 +109,10 @@ export interface ThemeColors extends ThemeColorsBase<ThemeRichColor> {
emphasize(color: string, amount?: number): string;
}
export const ThemeColorsInputSchema = createThemeColorsBaseSchema(ThemeRichColorInputSchema);
/** @internal */
export type ThemeColorsInput = DeepPartial<ThemeColorsBase<ThemeRichColor>>;
export type ThemeColorsInput = z.infer<typeof ThemeColorsInputSchema>;
class DarkColors implements ThemeColorsBase<Partial<ThemeRichColor>> {
mode: ThemeColorsMode = 'dark';

View File

@@ -1,3 +1,5 @@
import { z } from 'zod';
/** @beta */
export interface ThemeShape {
/**
@@ -34,9 +36,12 @@ export interface Radii {
}
/** @internal */
export interface ThemeShapeInput {
borderRadius?: number;
}
export const ThemeShapeInputSchema = z.object({
borderRadius: z.int().nonnegative().optional(),
});
/** @internal */
export type ThemeShapeInput = z.infer<typeof ThemeShapeInputSchema>;
export function createShape(options: ThemeShapeInput): ThemeShape {
const baseBorderRadius = options.borderRadius ?? 6;

View File

@@ -1,11 +1,15 @@
// Code based on Material UI
// The MIT License (MIT)
// Copyright (c) 2014 Call-Em-All
import { z } from 'zod';
/** @internal */
export type ThemeSpacingOptions = {
gridSize?: number;
};
export const ThemeSpacingOptionsSchema = z.object({
gridSize: z.int().positive().optional(),
});
/** @internal */
export type ThemeSpacingOptions = z.infer<typeof ThemeSpacingOptionsSchema>;
/** @internal */
export type ThemeSpacingArgument = number | string;

View File

@@ -1,28 +1,37 @@
import * as z from 'zod';
import { createBreakpoints } from './breakpoints';
import { createColors, ThemeColorsInput } from './createColors';
import { createColors, ThemeColorsInputSchema } from './createColors';
import { createComponents } from './createComponents';
import { createShadows } from './createShadows';
import { createShape, ThemeShapeInput } from './createShape';
import { createSpacing, ThemeSpacingOptions } from './createSpacing';
import { createShape, ThemeShapeInputSchema } from './createShape';
import { createSpacing, ThemeSpacingOptionsSchema } from './createSpacing';
import { createTransitions } from './createTransitions';
import { createTypography, ThemeTypographyInput } from './createTypography';
import { createTypography, ThemeTypographyInputSchema } from './createTypography';
import { createV1Theme } from './createV1Theme';
import { createVisualizationColors, ThemeVisualizationColorsInput } from './createVisualizationColors';
import { createVisualizationColors, ThemeVisualizationColorsInputSchema } from './createVisualizationColors';
import { GrafanaTheme2 } from './types';
import { zIndex } from './zIndex';
/** @internal */
export interface NewThemeOptions {
name?: string;
colors?: ThemeColorsInput;
spacing?: ThemeSpacingOptions;
shape?: ThemeShapeInput;
typography?: ThemeTypographyInput;
visualization?: ThemeVisualizationColorsInput;
}
export const NewThemeOptionsSchema = z.object({
name: z.string(),
id: z.string(),
colors: ThemeColorsInputSchema.optional(),
spacing: ThemeSpacingOptionsSchema.optional(),
shape: ThemeShapeInputSchema.optional(),
typography: ThemeTypographyInputSchema.optional(),
visualization: ThemeVisualizationColorsInputSchema.optional(),
});
/** @internal */
export function createTheme(options: NewThemeOptions = {}): GrafanaTheme2 {
export type NewThemeOptions = z.infer<typeof NewThemeOptionsSchema>;
/** @internal */
export function createTheme(
options: Omit<NewThemeOptions, 'id' | 'name'> & {
name?: NewThemeOptions['name'];
} = {}
): GrafanaTheme2 {
const {
name,
colors: colorsInput = {},

View File

@@ -1,6 +1,7 @@
// Code based on Material UI
// The MIT License (MIT)
// Copyright (c) 2014 Call-Em-All
import { z } from 'zod';
import { ThemeColors } from './createColors';
@@ -40,18 +41,20 @@ export interface ThemeTypographyVariant {
letterSpacing?: string;
}
export interface ThemeTypographyInput {
fontFamily?: string;
fontFamilyMonospace?: string;
fontSize?: number;
fontWeightLight?: number;
fontWeightRegular?: number;
fontWeightMedium?: number;
fontWeightBold?: number;
// hat's the font-size on the html element.
export const ThemeTypographyInputSchema = z.object({
fontFamily: z.string().optional(),
fontFamilyMonospace: z.string().optional(),
fontSize: z.number().positive().optional(),
fontWeightLight: z.number().positive().optional(),
fontWeightRegular: z.number().positive().optional(),
fontWeightMedium: z.number().positive().optional(),
fontWeightBold: z.number().positive().optional(),
// what's the font-size on the html element.
// 16px is the default font-size used by browsers.
htmlFontSize?: number;
}
htmlFontSize: z.number().positive().optional(),
});
export type ThemeTypographyInput = z.infer<typeof ThemeTypographyInputSchema>;
const defaultFontFamily = "'Inter', 'Helvetica', 'Arial', sans-serif";
const defaultFontFamilyMonospace = "'Roboto Mono', monospace";

View File

@@ -1,3 +1,5 @@
import { z } from 'zod';
import { FALLBACK_COLOR } from '../types/fieldColor';
import { ThemeColors } from './createColors';
@@ -26,29 +28,44 @@ export interface ThemeVizColor<T extends ThemeVizColorName> {
type ThemeVizColorName = 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'purple';
type ThemeVizColorShadeName<T extends ThemeVizColorName> =
| `super-light-${T}`
| `light-${T}`
| T
| `semi-dark-${T}`
| `dark-${T}`;
const createShadeSchema = <T>(color: T extends ThemeVizColorName ? T : never) =>
z.enum([`super-light-${color}`, `light-${color}`, color, `semi-dark-${color}`, `dark-${color}`]);
type ThemeVizHueGeneric<T> = T extends ThemeVizColorName
? {
name: T;
shades: Array<ThemeVizColor<T>>;
}
: never;
type ThemeVizColorShadeName<T extends ThemeVizColorName> = z.infer<ReturnType<typeof createShadeSchema<T>>>;
const createHueSchema = <T>(color: T extends ThemeVizColorName ? T : never) =>
z.object({
name: z.literal(color),
shades: z.array(
z.object({
color: z.string(),
name: createShadeSchema(color),
aliases: z.array(z.string()).optional(),
primary: z.boolean().optional(),
})
),
});
const ThemeVizHueSchema = z.union([
createHueSchema('red'),
createHueSchema('orange'),
createHueSchema('yellow'),
createHueSchema('green'),
createHueSchema('blue'),
createHueSchema('purple'),
]);
/**
* @alpha
*/
export type ThemeVizHue = ThemeVizHueGeneric<ThemeVizColorName>;
export type ThemeVizHue = z.infer<typeof ThemeVizHueSchema>;
export type ThemeVisualizationColorsInput = {
hues?: ThemeVizHue[];
palette?: string[];
};
export const ThemeVisualizationColorsInputSchema = z.object({
hues: z.array(ThemeVizHueSchema).optional(),
palette: z.array(z.string()).optional(),
});
export type ThemeVisualizationColorsInput = z.infer<typeof ThemeVisualizationColorsInputSchema>;
/**
* @internal

View File

@@ -1,6 +1,6 @@
import { Registry, RegistryItem } from '../utils/Registry';
import { createTheme } from './createTheme';
import { createTheme, NewThemeOptionsSchema } from './createTheme';
import * as extraThemes from './themeDefinitions';
import { GrafanaTheme2 } from './types';
@@ -42,9 +42,6 @@ export function getBuiltInThemes(allowedExtras: string[]) {
return sortedThemes;
}
/**
* There is also a backend list at pkg/services/preference/themes.go
*/
const themeRegistry = new Registry<ThemeRegistryItem>(() => {
return [
{ id: 'system', name: 'System preference', build: getSystemPreferenceTheme },
@@ -53,13 +50,19 @@ const themeRegistry = new Registry<ThemeRegistryItem>(() => {
];
});
for (const [id, theme] of Object.entries(extraThemes)) {
themeRegistry.register({
id,
name: theme.name ?? '',
build: () => createTheme(theme),
isExtra: true,
});
for (const [name, json] of Object.entries(extraThemes)) {
const result = NewThemeOptionsSchema.safeParse(json);
if (!result.success) {
console.error(`Invalid theme definition for theme ${name}: ${result.error.message}`);
} else {
const theme = result.data;
themeRegistry.register({
id: theme.id,
name: theme.name,
build: () => createTheme(theme),
isExtra: true,
});
}
}
function getSystemPreferenceTheme() {

View File

@@ -0,0 +1,608 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "string"
},
"colors": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": ["light", "dark"]
},
"primary": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"main": {
"type": "string"
},
"shade": {
"type": "string"
},
"text": {
"type": "string"
},
"border": {
"type": "string"
},
"transparent": {
"type": "string"
},
"borderTransparent": {
"type": "string"
},
"contrastText": {
"type": "string"
}
},
"additionalProperties": false
},
"secondary": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"main": {
"type": "string"
},
"shade": {
"type": "string"
},
"text": {
"type": "string"
},
"border": {
"type": "string"
},
"transparent": {
"type": "string"
},
"borderTransparent": {
"type": "string"
},
"contrastText": {
"type": "string"
}
},
"additionalProperties": false
},
"info": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"main": {
"type": "string"
},
"shade": {
"type": "string"
},
"text": {
"type": "string"
},
"border": {
"type": "string"
},
"transparent": {
"type": "string"
},
"borderTransparent": {
"type": "string"
},
"contrastText": {
"type": "string"
}
},
"additionalProperties": false
},
"error": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"main": {
"type": "string"
},
"shade": {
"type": "string"
},
"text": {
"type": "string"
},
"border": {
"type": "string"
},
"transparent": {
"type": "string"
},
"borderTransparent": {
"type": "string"
},
"contrastText": {
"type": "string"
}
},
"additionalProperties": false
},
"success": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"main": {
"type": "string"
},
"shade": {
"type": "string"
},
"text": {
"type": "string"
},
"border": {
"type": "string"
},
"transparent": {
"type": "string"
},
"borderTransparent": {
"type": "string"
},
"contrastText": {
"type": "string"
}
},
"additionalProperties": false
},
"warning": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"main": {
"type": "string"
},
"shade": {
"type": "string"
},
"text": {
"type": "string"
},
"border": {
"type": "string"
},
"transparent": {
"type": "string"
},
"borderTransparent": {
"type": "string"
},
"contrastText": {
"type": "string"
}
},
"additionalProperties": false
},
"text": {
"type": "object",
"properties": {
"primary": {
"type": "string"
},
"secondary": {
"type": "string"
},
"disabled": {
"type": "string"
},
"link": {
"type": "string"
},
"maxContrast": {
"type": "string"
}
},
"additionalProperties": false
},
"background": {
"type": "object",
"properties": {
"canvas": {
"type": "string"
},
"primary": {
"type": "string"
},
"secondary": {
"type": "string"
},
"elevated": {
"type": "string"
}
},
"additionalProperties": false
},
"border": {
"type": "object",
"properties": {
"weak": {
"type": "string"
},
"medium": {
"type": "string"
},
"strong": {
"type": "string"
}
},
"additionalProperties": false
},
"gradients": {
"type": "object",
"properties": {
"brandVertical": {
"type": "string"
},
"brandHorizontal": {
"type": "string"
}
},
"additionalProperties": false
},
"action": {
"type": "object",
"properties": {
"selected": {
"type": "string"
},
"selectedBorder": {
"type": "string"
},
"hover": {
"type": "string"
},
"hoverOpacity": {
"type": "number"
},
"focus": {
"type": "string"
},
"disabledBackground": {
"type": "string"
},
"disabledText": {
"type": "string"
},
"disabledOpacity": {
"type": "number"
}
},
"additionalProperties": false
},
"hoverFactor": {
"type": "number"
},
"contrastThreshold": {
"type": "number"
},
"tonalOffset": {
"type": "number"
}
},
"additionalProperties": false
},
"spacing": {
"type": "object",
"properties": {
"gridSize": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"additionalProperties": false
},
"shape": {
"type": "object",
"properties": {
"borderRadius": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"additionalProperties": false
},
"typography": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string"
},
"fontFamilyMonospace": {
"type": "string"
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0
},
"fontWeightLight": {
"type": "number",
"exclusiveMinimum": 0
},
"fontWeightRegular": {
"type": "number",
"exclusiveMinimum": 0
},
"fontWeightMedium": {
"type": "number",
"exclusiveMinimum": 0
},
"fontWeightBold": {
"type": "number",
"exclusiveMinimum": 0
},
"htmlFontSize": {
"type": "number",
"exclusiveMinimum": 0
}
},
"additionalProperties": false
},
"visualization": {
"type": "object",
"properties": {
"hues": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "red"
},
"shades": {
"type": "array",
"items": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"name": {
"type": "string",
"enum": ["super-light-red", "light-red", "red", "semi-dark-red", "dark-red"]
},
"aliases": {
"type": "array",
"items": {
"type": "string"
}
},
"primary": {
"type": "boolean"
}
},
"required": ["color", "name"],
"additionalProperties": false
}
}
},
"required": ["name", "shades"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "orange"
},
"shades": {
"type": "array",
"items": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"name": {
"type": "string",
"enum": ["super-light-orange", "light-orange", "orange", "semi-dark-orange", "dark-orange"]
},
"aliases": {
"type": "array",
"items": {
"type": "string"
}
},
"primary": {
"type": "boolean"
}
},
"required": ["color", "name"],
"additionalProperties": false
}
}
},
"required": ["name", "shades"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "yellow"
},
"shades": {
"type": "array",
"items": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"name": {
"type": "string",
"enum": ["super-light-yellow", "light-yellow", "yellow", "semi-dark-yellow", "dark-yellow"]
},
"aliases": {
"type": "array",
"items": {
"type": "string"
}
},
"primary": {
"type": "boolean"
}
},
"required": ["color", "name"],
"additionalProperties": false
}
}
},
"required": ["name", "shades"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "green"
},
"shades": {
"type": "array",
"items": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"name": {
"type": "string",
"enum": ["super-light-green", "light-green", "green", "semi-dark-green", "dark-green"]
},
"aliases": {
"type": "array",
"items": {
"type": "string"
}
},
"primary": {
"type": "boolean"
}
},
"required": ["color", "name"],
"additionalProperties": false
}
}
},
"required": ["name", "shades"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "blue"
},
"shades": {
"type": "array",
"items": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"name": {
"type": "string",
"enum": ["super-light-blue", "light-blue", "blue", "semi-dark-blue", "dark-blue"]
},
"aliases": {
"type": "array",
"items": {
"type": "string"
}
},
"primary": {
"type": "boolean"
}
},
"required": ["color", "name"],
"additionalProperties": false
}
}
},
"required": ["name", "shades"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "purple"
},
"shades": {
"type": "array",
"items": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"name": {
"type": "string",
"enum": ["super-light-purple", "light-purple", "purple", "semi-dark-purple", "dark-purple"]
},
"aliases": {
"type": "array",
"items": {
"type": "string"
}
},
"primary": {
"type": "boolean"
}
},
"required": ["color", "name"],
"additionalProperties": false
}
}
},
"required": ["name", "shades"],
"additionalProperties": false
}
]
}
},
"palette": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
}
},
"required": ["name", "id"],
"additionalProperties": false
}

View File

@@ -0,0 +1,19 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { NewThemeOptionsSchema } from '../createTheme';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
fs.writeFileSync(
path.join(__dirname, '../schema.generated.json'),
JSON.stringify(
NewThemeOptionsSchema.toJSONSchema({
target: 'draft-07',
}),
undefined,
2
)
);

View File

@@ -0,0 +1,50 @@
{
"name": "Aubergine",
"id": "aubergine",
"colors": {
"mode": "dark",
"border": {
"weak": "#4F2A3D",
"medium": "#6A3C4B",
"strong": "#8C5A69"
},
"text": {
"primary": "#E5D0D6",
"secondary": "#D1A8C4",
"disabled": "#B7A0A6",
"link": "#A56BB6",
"maxContrast": "#FFFFFF"
},
"primary": {
"main": "#8C5A69"
},
"secondary": {
"main": "#6A3C4B",
"text": "#D1A8C4",
"border": "#8C5A69"
},
"background": {
"canvas": "#2E1F2D",
"primary": "#3C2136",
"secondary": "#4A2D47",
"elevated": "#4A2D47"
},
"action": {
"hover": "#6A3C4B",
"selected": "#8C5A69",
"selectedBorder": "#FFB300",
"focus": "#A56BB6",
"hoverOpacity": 0.1,
"disabledText": "#B7A0A6",
"disabledBackground": "#4A2D47",
"disabledOpacity": 0.38
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg, #6A3C4B 0%, #A56BB6 100%)",
"brandVertical": "linear-gradient(0deg, #6A3C4B 0%, #A56BB6 100%)"
},
"contrastThreshold": 4,
"hoverFactor": 0.07,
"tonalOffset": 0.15
}
}

View File

@@ -1,53 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const aubergineTheme: NewThemeOptions = {
name: 'Aubergine',
colors: {
mode: 'dark',
border: {
weak: '#4F2A3D',
medium: '#6A3C4B',
strong: '#8C5A69',
},
text: {
primary: '#E5D0D6',
secondary: '#D1A8C4',
disabled: '#B7A0A6',
link: '#A56BB6',
maxContrast: '#FFFFFF',
},
primary: {
main: '#8C5A69',
},
secondary: {
main: '#6A3C4B',
text: '#D1A8C4',
border: '#8C5A69',
},
background: {
canvas: '#2E1F2D',
primary: '#3C2136',
secondary: '#4A2D47',
elevated: '#4A2D47',
},
action: {
hover: '#6A3C4B',
selected: '#8C5A69',
selectedBorder: '#FFB300',
focus: '#A56BB6',
hoverOpacity: 0.1,
disabledText: '#B7A0A6',
disabledBackground: '#4A2D47',
disabledOpacity: 0.38,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg, #6A3C4B 0%, #A56BB6 100%)',
brandVertical: 'linear-gradient(0deg, #6A3C4B 0%, #A56BB6 100%)',
},
contrastThreshold: 4,
hoverFactor: 0.07,
tonalOffset: 0.15,
},
};
export default aubergineTheme;

View File

@@ -0,0 +1,60 @@
{
"name": "Debug",
"id": "debug",
"colors": {
"mode": "dark",
"background": {
"canvas": "#000033",
"primary": "#000044",
"secondary": "#000055",
"elevated": "#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
}
}

View File

@@ -1,71 +0,0 @@
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',
elevated: '#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;

View File

@@ -0,0 +1,71 @@
{
"name": "Desert bloom",
"id": "desertbloom",
"colors": {
"mode": "light",
"border": {
"weak": "rgba(0, 0, 0, 0.12)",
"medium": "rgba(0, 0, 0, 0.20)",
"strong": "rgba(0, 0, 0, 0.30)"
},
"text": {
"primary": "#333333",
"secondary": "#555555",
"disabled": "rgba(0, 0, 0, 0.5)",
"link": "#1A82E2",
"maxContrast": "#000000"
},
"primary": {
"main": "#FF6F61",
"text": "#FE6F61",
"border": "#E55B4D",
"name": "primary",
"shade": "#E55B4D",
"transparent": "#FF6F6126",
"contrastText": "#FFFFFF",
"borderTransparent": "#FF6F6140"
},
"secondary": {
"main": "#FFFFFF",
"text": "#695f53",
"border": "#d9cec0",
"name": "secondary",
"shade": "#d9cec0",
"transparent": "#FFFFFF26",
"contrastText": "#4c4339",
"borderTransparent": "#FFFFFF40"
},
"info": {
"main": "#1A82E2"
},
"success": {
"main": "#4CAF50"
},
"warning": {
"main": "#FFC107"
},
"background": {
"canvas": "#FFF8F0",
"primary": "#FFFFFF",
"secondary": "#f9f3e8",
"elevated": "#FFFFFF"
},
"action": {
"hover": "rgba(168, 156, 134, 0.12)",
"selected": "rgba(168, 156, 134, 0.36)",
"selectedBorder": "#FF6F61",
"focus": "rgba(168, 156, 134, 0.50)",
"hoverOpacity": 0.08,
"disabledText": "rgba(168, 156, 134, 0.5)",
"disabledBackground": "rgba(168, 156, 134, 0.06)",
"disabledOpacity": 0.38
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg,rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)",
"brandVertical": "linear-gradient(0deg, rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)"
},
"contrastThreshold": 3,
"hoverFactor": 0.03,
"tonalOffset": 0.15
}
}

View File

@@ -1,75 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const desertBloomTheme: NewThemeOptions = {
name: 'Desert bloom',
colors: {
mode: 'light',
border: {
weak: 'rgba(0, 0, 0, 0.12)',
medium: 'rgba(0, 0, 0, 0.20)',
strong: 'rgba(0, 0, 0, 0.30)',
},
text: {
primary: '#333333',
secondary: '#555555',
disabled: 'rgba(0, 0, 0, 0.5)',
link: '#1A82E2',
maxContrast: '#000000',
},
primary: {
main: '#FF6F61',
text: '#FE6F61',
border: '#E55B4D',
name: 'primary',
shade: '#E55B4D',
transparent: '#FF6F6126',
contrastText: '#FFFFFF',
borderTransparent: '#FF6F6140',
},
secondary: {
main: '#FFFFFF',
text: '#695f53',
border: '#d9cec0',
name: 'secondary',
shade: '#d9cec0',
transparent: '#FFFFFF26',
contrastText: '#4c4339',
borderTransparent: '#FFFFFF40',
},
info: {
main: '#1A82E2',
},
success: {
main: '#4CAF50',
},
warning: {
main: '#FFC107',
},
background: {
canvas: '#FFF8F0',
primary: '#FFFFFF',
secondary: '#f9f3e8',
elevated: '#FFFFFF',
},
action: {
hover: 'rgba(168, 156, 134, 0.12)',
selected: 'rgba(168, 156, 134, 0.36)',
selectedBorder: '#FF6F61',
focus: 'rgba(168, 156, 134, 0.50)',
hoverOpacity: 0.08,
disabledText: 'rgba(168, 156, 134, 0.5)',
disabledBackground: 'rgba(168, 156, 134, 0.06)',
disabledOpacity: 0.38,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg,rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)',
brandVertical: 'linear-gradient(0deg, rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)',
},
contrastThreshold: 3,
hoverFactor: 0.03,
tonalOffset: 0.15,
},
};
export default desertBloomTheme;

View File

@@ -0,0 +1,62 @@
{
"name": "Gilded grove",
"id": "gildedgrove",
"colors": {
"mode": "dark",
"border": {
"weak": "rgba(200, 200, 180, 0.12)",
"medium": "rgba(200, 200, 180, 0.20)",
"strong": "rgba(200, 200, 180, 0.30)"
},
"text": {
"primary": "rgb(250, 250, 239)",
"secondary": "rgba(200, 200, 180, 0.85)",
"disabled": "rgba(200, 200, 180, 0.6)",
"link": "#FEAC34",
"maxContrast": "#FFFFFF"
},
"primary": {
"main": "#FEAC34",
"text": "#FFD783",
"border": "#FFD783",
"name": "primary",
"shade": "rgb(255, 173, 80)",
"transparent": "#FEAC3426",
"contrastText": "#111614",
"borderTransparent": "#FFD78340"
},
"secondary": {
"main": "rgba(200, 200, 180, 0.10)",
"shade": "rgba(200, 200, 180, 0.14)",
"transparent": "rgba(200, 200, 180, 0.08)",
"text": "rgb(200, 200, 180)",
"contrastText": "rgb(200, 200, 180)",
"border": "rgba(200, 200, 180, 0.08)",
"name": "secondary",
"borderTransparent": "rgba(200, 200, 180, 0.25)"
},
"background": {
"canvas": "#111614",
"primary": "#1d2220",
"secondary": "#27312E",
"elevated": "#27312E"
},
"action": {
"hover": "rgba(200, 200, 180, 0.16)",
"selected": "rgba(200, 200, 180, 0.12)",
"selectedBorder": "#FEAC34",
"focus": "rgba(200, 200, 180, 0.16)",
"hoverOpacity": 0.08,
"disabledText": "rgba(200, 200, 180, 0.6)",
"disabledBackground": "rgba(200, 200, 180, 0.04)",
"disabledOpacity": 0.38
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg, #FEAC34 0%, #FFD783 100%)",
"brandVertical": "linear-gradient(0.01deg, #FEAC34 0.01%, #FFD783 99.99%)"
},
"contrastThreshold": 3,
"hoverFactor": 0.03,
"tonalOffset": 0.15
}
}

View File

@@ -1,65 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const gildedGroveTheme: NewThemeOptions = {
name: 'Gilded grove',
colors: {
mode: 'dark',
border: {
weak: 'rgba(200, 200, 180, 0.12)',
medium: 'rgba(200, 200, 180, 0.20)',
strong: 'rgba(200, 200, 180, 0.30)',
},
text: {
primary: 'rgb(250, 250, 239)',
secondary: 'rgba(200, 200, 180, 0.85)',
disabled: 'rgba(200, 200, 180, 0.6)',
link: '#FEAC34',
maxContrast: '#FFFFFF',
},
primary: {
main: '#FEAC34',
text: '#FFD783',
border: '#FFD783',
name: 'primary',
shade: 'rgb(255, 173, 80)',
transparent: '#FEAC3426',
contrastText: '#111614',
borderTransparent: '#FFD78340',
},
secondary: {
main: 'rgba(200, 200, 180, 0.10)',
shade: 'rgba(200, 200, 180, 0.14)',
transparent: 'rgba(200, 200, 180, 0.08)',
text: 'rgb(200, 200, 180)',
contrastText: 'rgb(200, 200, 180)',
border: 'rgba(200, 200, 180, 0.08)',
name: 'secondary',
borderTransparent: 'rgba(200, 200, 180, 0.25)',
},
background: {
canvas: '#111614',
primary: '#1d2220',
secondary: '#27312E',
elevated: '#27312E',
},
action: {
hover: 'rgba(200, 200, 180, 0.16)',
selected: 'rgba(200, 200, 180, 0.12)',
selectedBorder: '#FEAC34',
focus: 'rgba(200, 200, 180, 0.16)',
hoverOpacity: 0.08,
disabledText: 'rgba(200, 200, 180, 0.6)',
disabledBackground: 'rgba(200, 200, 180, 0.04)',
disabledOpacity: 0.38,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg, #FEAC34 0%, #FFD783 100%)',
brandVertical: 'linear-gradient(0.01deg, #FEAC34 0.01%, #FFD783 99.99%)',
},
contrastThreshold: 3,
hoverFactor: 0.03,
tonalOffset: 0.15,
},
};
export default gildedGroveTheme;

View File

@@ -0,0 +1,52 @@
{
"name": "Gloom",
"id": "gloom",
"colors": {
"mode": "dark",
"border": {
"weak": "rgba(210, 210, 220, 0.12)",
"medium": "rgba(210, 210, 220, 0.20)",
"strong": "rgba(210, 210, 220, 0.30)"
},
"text": {
"primary": "rgb(210, 210, 220)",
"secondary": "rgba(210, 210, 220, 0.65)",
"disabled": "rgba(210, 210, 220, 0.48)",
"link": "#f99a5c",
"maxContrast": "#FFF"
},
"primary": {
"main": "#ff934d",
"text": "#f99a5c",
"border": "#ff934d",
"name": "primary"
},
"secondary": {
"main": "rgba(195, 195, 245, 0.10)",
"shade": "rgba(195, 195, 245, 0.14)",
"transparent": "rgba(195, 195, 245, 0.08)",
"text": "rgba(195, 195, 245)",
"contrastText": "rgb(195, 195, 245)",
"border": "rgba(195, 195, 245, 0.08)"
},
"background": {
"canvas": "#000",
"primary": "#121118",
"secondary": "#211e28",
"elevated": "#211e28"
},
"action": {
"hover": "rgba(195, 195, 245, 0.07)",
"selected": "rgba(195, 195, 245, 0.11)",
"selectedBorder": "#ff934d",
"focus": "rgba(195, 195, 245, 0.07)",
"hoverOpacity": 0.05,
"disabledText": "rgba(210, 210, 220, 0.48)",
"disabledBackground": "rgba(210, 210, 220, 0.04)",
"disabledOpacity": 0.38
},
"contrastThreshold": 3,
"hoverFactor": 0.03,
"tonalOffset": 0.15
}
}

View File

@@ -1,80 +0,0 @@
import { NewThemeOptions } from '../createTheme';
/**
* Torkel's GrafanaCon theme
* very WIP state
*/
const whiteBase = `210, 210, 220`;
const secondaryBase = `195, 195, 245`;
//const brandMain = '#3d71d9';
//const brandText = '#6e9fff';
const brandMain = '#ff934d';
const brandText = '#f99a5c';
const disabledText = `rgba(${whiteBase}, 0.48)`;
const gloomTheme: NewThemeOptions = {
name: 'Gloom',
colors: {
mode: 'dark',
border: {
weak: `rgba(${whiteBase}, 0.12)`,
medium: `rgba(${whiteBase}, 0.20)`,
strong: `rgba(${whiteBase}, 0.30)`,
},
text: {
primary: `rgb(${whiteBase})`,
secondary: `rgba(${whiteBase}, 0.65)`,
disabled: disabledText,
link: brandText,
maxContrast: '#FFF',
},
primary: {
main: brandMain,
text: brandText,
border: brandMain,
name: 'primary',
},
secondary: {
main: `rgba(${secondaryBase}, 0.10)`,
shade: `rgba(${secondaryBase}, 0.14)`,
transparent: `rgba(${secondaryBase}, 0.08)`,
text: `rgba(${secondaryBase})`,
contrastText: `rgb(${secondaryBase})`,
border: `rgba(${secondaryBase}, 0.08)`,
},
background: {
canvas: '#000',
primary: '#121118',
secondary: '#211e28',
elevated: '#211e28',
},
action: {
hover: `rgba(${secondaryBase}, 0.07)`,
selected: `rgba(${secondaryBase}, 0.11)`,
selectedBorder: brandMain,
focus: `rgba(${secondaryBase}, 0.07)`,
hoverOpacity: 0.05,
disabledText: disabledText,
disabledBackground: `rgba(${whiteBase}, 0.04)`,
disabledOpacity: 0.38,
},
// gradients: {
// brandHorizontal: 'linear-gradient(270deg, #ff934d 0%, #FEAC34 100%)',
// brandVertical: 'linear-gradient(0.01deg, #ff934d 0.01%, #FEAC34 99.99%)',
// },
contrastThreshold: 3,
hoverFactor: 0.03,
tonalOffset: 0.15,
},
};
export default gloomTheme;

View File

@@ -1,12 +1,12 @@
export { default as aubergine } from './aubergine';
export { default as debug } from './debug';
export { default as desertbloom } from './desertbloom';
export { default as gildedgrove } from './gildedgrove';
export { default as mars } from './mars';
export { default as matrix } from './matrix';
export { default as sapphiredusk } from './sapphiredusk';
export { default as synthwave } from './synthwave';
export { default as tron } from './tron';
export { default as victorian } from './victorian';
export { default as zen } from './zen';
export { default as gloom } from './gloom';
export { default as aubergine } from './aubergine.json';
export { default as debug } from './debug.json';
export { default as desertbloom } from './desertbloom.json';
export { default as gildedgrove } from './gildedgrove.json';
export { default as mars } from './mars.json';
export { default as matrix } from './matrix.json';
export { default as sapphiredusk } from './sapphiredusk.json';
export { default as synthwave } from './synthwave.json';
export { default as tron } from './tron.json';
export { default as victorian } from './victorian.json';
export { default as zen } from './zen.json';
export { default as gloom } from './gloom.json';

View File

@@ -0,0 +1,50 @@
{
"name": "Mars",
"id": "mars",
"colors": {
"mode": "dark",
"border": {
"weak": "rgba(210, 90, 60, 0.2)",
"medium": "rgba(210, 90, 60, 0.35)",
"strong": "rgba(210, 90, 60, 0.5)"
},
"text": {
"primary": "#DDDDDD",
"secondary": "#BBBBBB",
"disabled": "rgba(221, 221, 221, 0.5)",
"link": "#FF6F61",
"maxContrast": "#FFFFFF"
},
"primary": {
"main": "#FF6F61"
},
"secondary": {
"main": "#6a2f2f",
"text": "#BBBBBB",
"border": "rgba(210, 90, 60, 0.2)"
},
"background": {
"canvas": "#3C1E1E",
"primary": "#522626",
"secondary": "#6A2F2F",
"elevated": "#6A2F2F"
},
"action": {
"hover": "rgba(210, 90, 60, 0.16)",
"selected": "rgba(210, 90, 60, 0.12)",
"selectedBorder": "#FF6F61",
"focus": "rgba(210, 90, 60, 0.16)",
"hoverOpacity": 0.08,
"disabledText": "rgba(221, 221, 221, 0.5)",
"disabledBackground": "rgba(210, 90, 60, 0.08)",
"disabledOpacity": 0.38
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg, #FF6F61 0%, #D25A3C 100%)",
"brandVertical": "linear-gradient(0.01deg, #FF6F61 0.01%, #D25A3C 99.99%)"
},
"contrastThreshold": 3,
"hoverFactor": 0.05,
"tonalOffset": 0.2
}
}

View File

@@ -1,53 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const marsTheme: NewThemeOptions = {
name: 'Mars',
colors: {
mode: 'dark',
border: {
weak: 'rgba(210, 90, 60, 0.2)',
medium: 'rgba(210, 90, 60, 0.35)',
strong: 'rgba(210, 90, 60, 0.5)',
},
text: {
primary: '#DDDDDD',
secondary: '#BBBBBB',
disabled: 'rgba(221, 221, 221, 0.5)',
link: '#FF6F61',
maxContrast: '#FFFFFF',
},
primary: {
main: '#FF6F61',
},
secondary: {
main: '#6a2f2f',
text: '#BBBBBB',
border: 'rgba(210, 90, 60, 0.2)',
},
background: {
canvas: '#3C1E1E',
primary: '#522626',
secondary: '#6A2F2F',
elevated: '#6A2F2F',
},
action: {
hover: 'rgba(210, 90, 60, 0.16)',
selected: 'rgba(210, 90, 60, 0.12)',
selectedBorder: '#FF6F61',
focus: 'rgba(210, 90, 60, 0.16)',
hoverOpacity: 0.08,
disabledText: 'rgba(221, 221, 221, 0.5)',
disabledBackground: 'rgba(210, 90, 60, 0.08)',
disabledOpacity: 0.38,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg, #FF6F61 0%, #D25A3C 100%)',
brandVertical: 'linear-gradient(0.01deg, #FF6F61 0.01%, #D25A3C 99.99%)',
},
contrastThreshold: 3,
hoverFactor: 0.05,
tonalOffset: 0.2,
},
};
export default marsTheme;

View File

@@ -0,0 +1,41 @@
{
"name": "Matrix",
"id": "matrix",
"colors": {
"mode": "dark",
"background": {
"canvas": "#000000",
"primary": "#020202",
"secondary": "#080808",
"elevated": "#080808"
},
"text": {
"primary": "#00c017",
"secondary": "#008910",
"disabled": "#006a0c",
"link": "#00ff41",
"maxContrast": "#00ff41"
},
"border": {
"weak": "#008f1144",
"medium": "#008f1188",
"strong": "#008910"
},
"primary": {
"main": "#008910"
},
"secondary": {
"text": "#008910"
},
"gradients": {
"brandVertical": "linear-gradient(0deg, #008910 0%, #00ff41 100%)",
"brandHorizontal": "linear-gradient(90deg, #008910 0%, #00ff41 100%)"
}
},
"shape": {
"borderRadius": 0
},
"typography": {
"fontFamily": "monospace"
}
}

View File

@@ -1,44 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const matrixTheme: NewThemeOptions = {
name: 'Matrix',
colors: {
mode: 'dark',
background: {
canvas: '#000000',
primary: '#020202',
secondary: '#080808',
elevated: '#080808',
},
text: {
primary: '#00c017',
secondary: '#008910',
disabled: '#006a0c',
link: '#00ff41',
maxContrast: '#00ff41',
},
border: {
weak: '#008f1144',
medium: '#008f1188',
strong: '#008910',
},
primary: {
main: '#008910',
},
secondary: {
text: '#008910',
},
gradients: {
brandVertical: 'linear-gradient(0deg, #008910 0%, #00ff41 100%)',
brandHorizontal: 'linear-gradient(90deg, #008910 0%, #00ff41 100%)',
},
},
shape: {
borderRadius: 0,
},
typography: {
fontFamily: 'monospace',
},
};
export default matrixTheme;

View File

@@ -0,0 +1,76 @@
{
"name": "Sapphire dusk",
"id": "sapphiredusk",
"colors": {
"mode": "dark",
"border": {
"weak": "#232e47",
"medium": "#2c3853",
"strong": "#404d6b"
},
"text": {
"primary": "#FFFFFF",
"secondary": "#bcccdd",
"disabled": "#838da5",
"link": "#93EBF0",
"maxContrast": "#FFFFFF"
},
"primary": {
"main": "#93EBF0",
"text": "#a8e9ed",
"border": "#93ebf0",
"name": "primary",
"shade": "#c0f5d9",
"transparent": "#93EBF029",
"contrastText": "#111614",
"borderTransparent": "#93ebf040"
},
"secondary": {
"main": "#2c364f",
"shade": "#36415e",
"transparent": "rgba(200, 200, 180, 0.08)",
"text": "#d1dfff",
"contrastText": "#acfeff",
"border": "rgba(200, 200, 180, 0.08)",
"name": "secondary",
"borderTransparent": "rgba(200, 200, 180, 0.25)"
},
"info": {
"main": "#4d4593",
"text": "#a8e9ed",
"border": "#5d54a7"
},
"error": {
"main": "#c63370"
},
"success": {
"main": "#1A7F4B"
},
"warning": {
"main": "#D448EA"
},
"background": {
"canvas": "#1e273d",
"primary": "#12192e",
"secondary": "#212c47",
"elevated": "#212c47"
},
"action": {
"hover": "#364057",
"selected": "#364260",
"selectedBorder": "#D448EA",
"focus": "#364057",
"hoverOpacity": 0.08,
"disabledText": "#838da5",
"disabledBackground": "rgba(54, 64, 87, 0.2)",
"disabledOpacity": 0.38
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg, #D346EF 0%, #2C83FE 100%)",
"brandVertical": "linear-gradient(0deg, #D346EF 0%, #2C83FE 100%)"
},
"contrastThreshold": 3,
"hoverFactor": 0.03,
"tonalOffset": 0.15
}
}

View File

@@ -1,79 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const sapphireDuskTheme: NewThemeOptions = {
name: 'Sapphire dusk',
colors: {
mode: 'dark',
border: {
weak: '#232e47',
medium: '#2c3853',
strong: '#404d6b',
},
text: {
primary: '#FFFFFF',
secondary: '#bcccdd',
disabled: '#838da5',
link: '#93EBF0',
maxContrast: '#FFFFFF',
},
primary: {
main: '#93EBF0',
text: '#a8e9ed',
border: '#93ebf0',
name: 'primary',
shade: '#c0f5d9',
transparent: '#93EBF029',
contrastText: '#111614',
borderTransparent: '#93ebf040',
},
secondary: {
main: '#2c364f',
shade: '#36415e',
transparent: 'rgba(200, 200, 180, 0.08)',
text: '#d1dfff',
contrastText: '#acfeff',
border: 'rgba(200, 200, 180, 0.08)',
name: 'secondary',
borderTransparent: 'rgba(200, 200, 180, 0.25)',
},
info: {
main: '#4d4593',
text: '#a8e9ed',
border: '#5d54a7',
},
error: {
main: '#c63370',
},
success: {
main: '#1A7F4B',
},
warning: {
main: '#D448EA',
},
background: {
canvas: '#1e273d',
primary: '#12192e',
secondary: '#212c47',
elevated: '#212c47',
},
action: {
hover: '#364057',
selected: '#364260',
selectedBorder: '#D448EA',
focus: '#364057',
hoverOpacity: 0.08,
disabledText: '#838da5',
disabledBackground: 'rgba(54, 64, 87, 0.2)',
disabledOpacity: 0.38,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg, #D346EF 0%, #2C83FE 100%)',
brandVertical: 'linear-gradient(0deg, #D346EF 0%, #2C83FE 100%)',
},
contrastThreshold: 3,
hoverFactor: 0.03,
tonalOffset: 0.15,
},
};
export default sapphireDuskTheme;

View File

@@ -0,0 +1,50 @@
{
"name": "Synthwave",
"id": "synthwave",
"colors": {
"mode": "dark",
"border": {
"weak": "rgba(255, 20, 147, 0.12)",
"medium": "rgba(255, 20, 147, 0.20)",
"strong": "rgba(255, 20, 147, 0.30)"
},
"text": {
"primary": "#E0E0E0",
"secondary": "rgba(224, 224, 224, 0.75)",
"disabled": "rgba(224, 224, 224, 0.5)",
"link": "#FF69B4",
"maxContrast": "#FFFFFF"
},
"primary": {
"main": "#FF1493"
},
"secondary": {
"main": "#37183a",
"text": "rgba(224, 224, 224, 0.75)",
"border": "rgba(255, 20, 147, 0.10)"
},
"background": {
"canvas": "#1A1A2E",
"primary": "#16213E",
"secondary": "#0F3460",
"elevated": "#0F3460"
},
"action": {
"hover": "rgba(255, 20, 147, 0.16)",
"selected": "rgba(255, 20, 147, 0.12)",
"selectedBorder": "#FF1493",
"focus": "rgba(255, 20, 147, 0.16)",
"hoverOpacity": 0.08,
"disabledText": "rgba(224, 224, 224, 0.5)",
"disabledBackground": "rgba(255, 20, 147, 0.08)",
"disabledOpacity": 0.38
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg, #FF1493 0%, #1E90FF 100%)",
"brandVertical": "linear-gradient(0.01deg, #FF1493 0.01%, #1E90FF 99.99%)"
},
"contrastThreshold": 3,
"hoverFactor": 0.03,
"tonalOffset": 0.15
}
}

View File

@@ -1,53 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const synthwaveTheme: NewThemeOptions = {
name: 'Synthwave',
colors: {
mode: 'dark',
border: {
weak: 'rgba(255, 20, 147, 0.12)',
medium: 'rgba(255, 20, 147, 0.20)',
strong: 'rgba(255, 20, 147, 0.30)',
},
text: {
primary: '#E0E0E0',
secondary: 'rgba(224, 224, 224, 0.75)',
disabled: 'rgba(224, 224, 224, 0.5)',
link: '#FF69B4',
maxContrast: '#FFFFFF',
},
primary: {
main: '#FF1493',
},
secondary: {
main: '#37183a',
text: 'rgba(224, 224, 224, 0.75)',
border: 'rgba(255, 20, 147, 0.10)',
},
background: {
canvas: '#1A1A2E',
primary: '#16213E',
secondary: '#0F3460',
elevated: '#0F3460',
},
action: {
hover: 'rgba(255, 20, 147, 0.16)',
selected: 'rgba(255, 20, 147, 0.12)',
selectedBorder: '#FF1493',
focus: 'rgba(255, 20, 147, 0.16)',
hoverOpacity: 0.08,
disabledText: 'rgba(224, 224, 224, 0.5)',
disabledBackground: 'rgba(255, 20, 147, 0.08)',
disabledOpacity: 0.38,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg, #FF1493 0%, #1E90FF 100%)',
brandVertical: 'linear-gradient(0.01deg, #FF1493 0.01%, #1E90FF 99.99%)',
},
contrastThreshold: 3,
hoverFactor: 0.03,
tonalOffset: 0.15,
},
};
export default synthwaveTheme;

View File

@@ -0,0 +1,50 @@
{
"name": "Tron",
"id": "tron",
"colors": {
"mode": "dark",
"border": {
"weak": "rgba(0, 255, 255, 0.12)",
"medium": "rgba(0, 255, 255, 0.20)",
"strong": "rgba(0, 255, 255, 0.30)"
},
"text": {
"primary": "#E0E0E0",
"secondary": "rgba(224, 224, 224, 0.75)",
"disabled": "rgba(224, 224, 224, 0.5)",
"link": "#00FFFF",
"maxContrast": "#FFFFFF"
},
"primary": {
"main": "#00FFFF"
},
"secondary": {
"main": "#0b2e36",
"text": "rgba(224, 224, 224, 0.75)",
"border": "rgba(0, 255, 255, 0.10)"
},
"background": {
"canvas": "#0A0F18",
"primary": "#0F1B2A",
"secondary": "#152234",
"elevated": "#152234"
},
"action": {
"hover": "rgba(0, 255, 255, 0.16)",
"selected": "rgba(0, 255, 255, 0.12)",
"selectedBorder": "#00FFFF",
"focus": "rgba(0, 255, 255, 0.16)",
"hoverOpacity": 0.08,
"disabledText": "rgba(224, 224, 224, 0.5)",
"disabledBackground": "rgba(0, 255, 255, 0.08)",
"disabledOpacity": 0.38
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg, #00FFFF 0%, #29ABE2 100%)",
"brandVertical": "linear-gradient(0.01deg, #00FFFF 0.01%, #29ABE2 99.99%)"
},
"contrastThreshold": 3,
"hoverFactor": 0.05,
"tonalOffset": 0.2
}
}

View File

@@ -1,53 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const tronTheme: NewThemeOptions = {
name: 'Tron',
colors: {
mode: 'dark',
border: {
weak: 'rgba(0, 255, 255, 0.12)',
medium: 'rgba(0, 255, 255, 0.20)',
strong: 'rgba(0, 255, 255, 0.30)',
},
text: {
primary: '#E0E0E0',
secondary: 'rgba(224, 224, 224, 0.75)',
disabled: 'rgba(224, 224, 224, 0.5)',
link: '#00FFFF',
maxContrast: '#FFFFFF',
},
primary: {
main: '#00FFFF',
},
secondary: {
main: '#0b2e36',
text: 'rgba(224, 224, 224, 0.75)',
border: 'rgba(0, 255, 255, 0.10)',
},
background: {
canvas: '#0A0F18',
primary: '#0F1B2A',
secondary: '#152234',
elevated: '#152234',
},
action: {
hover: 'rgba(0, 255, 255, 0.16)',
selected: 'rgba(0, 255, 255, 0.12)',
selectedBorder: '#00FFFF',
focus: 'rgba(0, 255, 255, 0.16)',
hoverOpacity: 0.08,
disabledText: 'rgba(224, 224, 224, 0.5)',
disabledBackground: 'rgba(0, 255, 255, 0.08)',
disabledOpacity: 0.38,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg, #00FFFF 0%, #29ABE2 100%)',
brandVertical: 'linear-gradient(0.01deg, #00FFFF 0.01%, #29ABE2 99.99%)',
},
contrastThreshold: 3,
hoverFactor: 0.05,
tonalOffset: 0.2,
},
};
export default tronTheme;

View File

@@ -0,0 +1,54 @@
{
"name": "Victorian",
"id": "victorian",
"colors": {
"mode": "dark",
"border": {
"weak": "#3A2C22",
"medium": "#3A2C22",
"strong": "#4B3D32"
},
"text": {
"primary": "#D9D0A2",
"secondary": "#C4B89B",
"disabled": "#A89F91",
"link": "#C28A4D",
"maxContrast": "#FFFFFF"
},
"primary": {
"main": "#C28A4D"
},
"secondary": {
"main": "#3A2C22",
"text": "#C4B89B",
"border": "#4B3D32"
},
"background": {
"canvas": "#1F1510",
"primary": "#2C1A13",
"secondary": "#402A21",
"elevated": "#402A21"
},
"action": {
"hover": "#3A2C22",
"selected": "#4B3D32",
"selectedBorder": "#C28A4D",
"focus": "#C28A4D",
"hoverOpacity": 0.1,
"disabledText": "#A89F91",
"disabledBackground": "#402A21",
"disabledOpacity": 0.38
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg, #D9D0a1 0%, #C28A4D 100%)",
"brandVertical": "linear-gradient(0.01deg, #D9D0a1 0.01%, #C28A4D 99.99%)"
},
"contrastThreshold": 4,
"hoverFactor": 0.07,
"tonalOffset": 0.15
},
"typography": {
"fontFamily": "\"Georgia\", \"Times New Roman\", serif",
"fontFamilyMonospace": "'Courier New', monospace"
}
}

View File

@@ -1,57 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const victorianTheme: NewThemeOptions = {
name: 'Victorian',
colors: {
mode: 'dark',
border: {
weak: '#3A2C22',
medium: '#3A2C22',
strong: '#4B3D32',
},
text: {
primary: '#D9D0A2',
secondary: '#C4B89B',
disabled: '#A89F91',
link: '#C28A4D',
maxContrast: '#FFFFFF',
},
primary: {
main: '#C28A4D',
},
secondary: {
main: '#3A2C22',
text: '#C4B89B',
border: '#4B3D32',
},
background: {
canvas: '#1F1510',
primary: '#2C1A13',
secondary: '#402A21',
elevated: '#402A21',
},
action: {
hover: '#3A2C22',
selected: '#4B3D32',
selectedBorder: '#C28A4D',
focus: '#C28A4D',
hoverOpacity: 0.1,
disabledText: '#A89F91',
disabledBackground: '#402A21',
disabledOpacity: 0.38,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg, #D9D0a1 0%, #C28A4D 100%)',
brandVertical: 'linear-gradient(0.01deg, #D9D0a1 0.01%, #C28A4D 99.99%)',
},
contrastThreshold: 4,
hoverFactor: 0.07,
tonalOffset: 0.15,
},
typography: {
fontFamily: '"Georgia", "Times New Roman", serif',
fontFamilyMonospace: "'Courier New', monospace",
},
};
export default victorianTheme;

View File

@@ -0,0 +1,50 @@
{
"name": "Zen",
"id": "zen",
"colors": {
"mode": "light",
"text": {
"primary": "#333333",
"secondary": "#666666",
"disabled": "#B8B8B8",
"link": "#4F9F6E",
"maxContrast": "#000000"
},
"border": {
"weak": "#B1B7B3",
"medium": "#A2A8A2",
"strong": "#7C7F7A"
},
"primary": {
"main": "#6D8E6D"
},
"secondary": {
"main": "#E0E0E0",
"text": "#666666",
"border": "#A2A8A2"
},
"background": {
"canvas": "#F4F4F4",
"primary": "#E9E9E9",
"secondary": "#D8D8D8",
"elevated": "#E9E9E9"
},
"action": {
"hover": "#D1D1D1",
"selected": "#B8B8B8",
"selectedBorder": "#88B88B",
"hoverOpacity": 0.1,
"focus": "#D1D1D1",
"disabledBackground": "#E0E0E0",
"disabledText": "#B8B8B8",
"disabledOpacity": 0.5
},
"gradients": {
"brandHorizontal": "linear-gradient(270deg, #88B88B 0%, #6D8E6D 100%)",
"brandVertical": "linear-gradient(0.01deg, #88B88B 0.01%, #6D8E6D 99.99%)"
},
"contrastThreshold": 3,
"hoverFactor": 0.03,
"tonalOffset": 0.2
}
}

View File

@@ -1,53 +0,0 @@
import { NewThemeOptions } from '../createTheme';
const zenTheme: NewThemeOptions = {
name: 'Zen',
colors: {
mode: 'light',
text: {
primary: '#333333',
secondary: '#666666',
disabled: '#B8B8B8',
link: '#4F9F6E',
maxContrast: '#000000',
},
border: {
weak: '#B1B7B3',
medium: '#A2A8A2',
strong: '#7C7F7A',
},
primary: {
main: '#6D8E6D',
},
secondary: {
main: '#E0E0E0',
text: '#666666',
border: '#A2A8A2',
},
background: {
canvas: '#F4F4F4',
primary: '#E9E9E9',
secondary: '#D8D8D8',
elevated: '#E9E9E9',
},
action: {
hover: '#D1D1D1',
selected: '#B8B8B8',
selectedBorder: '#88B88B',
hoverOpacity: 0.1,
focus: '#D1D1D1',
disabledBackground: '#E0E0E0',
disabledText: '#B8B8B8',
disabledOpacity: 0.5,
},
gradients: {
brandHorizontal: 'linear-gradient(270deg, #88B88B 0%, #6D8E6D 100%)',
brandVertical: 'linear-gradient(0.01deg, #88B88B 0.01%, #6D8E6D 99.99%)',
},
contrastThreshold: 3,
hoverFactor: 0.03,
tonalOffset: 0.2,
},
};
export default zenTheme;

View File

@@ -1,3 +1,5 @@
import { z } from 'zod';
import { GrafanaTheme } from '../types/theme';
import { ThemeBreakpoints } from './breakpoints';
@@ -35,27 +37,36 @@ export interface GrafanaTheme2 {
flags: {};
}
/** @alpha */
export interface ThemeRichColor {
export const ThemeRichColorInputSchema = z.object({
/** color intent (primary, secondary, info, error, etc) */
name: string;
name: z.string().optional(),
/** Main color */
main: string;
main: z.string().optional(),
/** Used for hover */
shade: string;
shade: z.string().optional(),
/** Used for text */
text: string;
text: z.string().optional(),
/** Used for borders */
border: string;
border: z.string().optional(),
/** Used subtly colored backgrounds */
transparent: string;
transparent: z.string().optional(),
/** Used for weak colored borders like larger alert/banner boxes and smaller badges and tags */
borderTransparent: string;
borderTransparent: z.string().optional(),
/** Text color for text ontop of main */
contrastText: string;
}
contrastText: z.string().optional(),
});
export const ThemeRichColorSchema = ThemeRichColorInputSchema.required();
/** @alpha */
export type ThemeRichColor = z.infer<typeof ThemeRichColorSchema>;
/** @internal */
export type DeepPartial<T> = {
[P in keyof T]?: DeepPartial<T[P]>;
};
/** @internal */
export type DeepRequired<T> = Required<{
[P in keyof T]: T[P] extends Required<T[P]> ? T[P] : DeepRequired<T[P]>;
}>;

View File

@@ -9,5 +9,4 @@
* and be subject to the standard policies
*/
// This is a dummy export so typescript doesn't error importing an "empty module"
export const unstable = {};
export { default as themeJsonSchema } from './themes/schema.generated.json';

View File

@@ -0,0 +1,90 @@
//go:build ignore
package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
)
type Colors struct {
Mode string `json:"mode"`
}
type ThemeDefinition struct {
Colors Colors `json:"colors"`
Id string `json:"id"`
}
func main() {
themesPath := filepath.Join("..", "..", "..", "packages", "grafana-data", "src", "themes", "themeDefinitions")
// Check if the themes directory exists
if _, err := os.Stat(themesPath); os.IsNotExist(err) {
fmt.Fprintf(os.Stderr, "Themes directory not found: %s\n", themesPath)
os.Exit(1)
}
output := `// Code generated by go generate; DO NOT EDIT.
package pref
var themes = []ThemeDTO{
{ID: "light", Type: "light"},
{ID: "dark", Type: "dark"},
{ID: "system", Type: "dark"},
`
err := filepath.WalkDir(themesPath, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
// Only process json files
if d.IsDir() || !strings.HasSuffix(d.Name(), ".json") {
return nil
}
fileBytes, readErr := os.ReadFile(path)
if readErr != nil {
fmt.Fprintf(os.Stderr, "Error reading file %s: %v\n", path, readErr)
return nil // Continue processing other files
}
var themeDef ThemeDefinition
jsonErr := json.Unmarshal(fileBytes, &themeDef)
if jsonErr != nil {
fmt.Fprintf(os.Stderr, "Error parsing JSON from %s: %v\n", path, jsonErr)
return nil // Continue processing other files
}
themeId := themeDef.Id
themeType := "dark" // default fallback
if themeDef.Colors.Mode != "" {
themeType = themeDef.Colors.Mode
}
output += fmt.Sprintf("\t{ID: %q, Type: %q, IsExtra: true},\n", themeId, themeType)
return nil
})
if err != nil {
fmt.Fprintf(os.Stderr, "Error walking themes directory: %v\n", err)
os.Exit(1)
}
output += "}\n"
// Write the generated file
outputPath := filepath.Join("themes_generated.go")
if err := os.WriteFile(outputPath, []byte(output), 0644); err != nil {
fmt.Fprintf(os.Stderr, "Error writing output file: %v\n", err)
os.Exit(1)
}
fmt.Printf("Successfully generated themes_generated.go\n")
}

View File

@@ -1,3 +1,5 @@
//go:generate go run generate_themes.go
package pref
type ThemeDTO struct {
@@ -6,24 +8,6 @@ type ThemeDTO struct {
IsExtra bool `json:"isExtra"`
}
var themes = []ThemeDTO{
{ID: "light", Type: "light"},
{ID: "dark", Type: "dark"},
{ID: "system", Type: "dark"},
{ID: "debug", Type: "dark", IsExtra: true},
{ID: "aubergine", Type: "dark", IsExtra: true},
{ID: "desertbloom", Type: "light", IsExtra: true},
{ID: "gildedgrove", Type: "dark", IsExtra: true},
{ID: "mars", Type: "dark", IsExtra: true},
{ID: "matrix", Type: "dark", IsExtra: true},
{ID: "sapphiredusk", Type: "dark", IsExtra: true},
{ID: "synthwave", Type: "dark", IsExtra: true},
{ID: "tron", Type: "dark", IsExtra: true},
{ID: "victorian", Type: "dark", IsExtra: true},
{ID: "zen", Type: "light", IsExtra: true},
{ID: "gloom", Type: "dark", IsExtra: true},
}
func GetThemeByID(id string) *ThemeDTO {
for _, theme := range themes {
if theme.ID == id {

View File

@@ -0,0 +1,21 @@
// Code generated by go generate; DO NOT EDIT.
package pref
var themes = []ThemeDTO{
{ID: "light", Type: "light"},
{ID: "dark", Type: "dark"},
{ID: "system", Type: "dark"},
{ID: "aubergine", Type: "dark", IsExtra: true},
{ID: "debug", Type: "dark", IsExtra: true},
{ID: "desertbloom", Type: "light", IsExtra: true},
{ID: "gildedgrove", Type: "dark", IsExtra: true},
{ID: "gloom", Type: "dark", IsExtra: true},
{ID: "mars", Type: "dark", IsExtra: true},
{ID: "matrix", Type: "dark", IsExtra: true},
{ID: "sapphiredusk", Type: "dark", IsExtra: true},
{ID: "synthwave", Type: "dark", IsExtra: true},
{ID: "tron", Type: "dark", IsExtra: true},
{ID: "victorian", Type: "dark", IsExtra: true},
{ID: "zen", Type: "light", IsExtra: true},
}

View File

@@ -1,3 +0,0 @@
# Regenerating the schema
The json schema for the theme options is generated using [typescript-json-schema](https://github.com/YousefED/typescript-json-schema). The schema should be regenerated automatically if the types change. If you need to manually regenerate, run `yarn themes-schema`.

View File

@@ -2,7 +2,8 @@ import { css } from '@emotion/css';
import { useId, useState } from 'react';
import { createTheme, GrafanaTheme2, NewThemeOptions } from '@grafana/data';
import { experimentalThemeDefinitions } from '@grafana/data/internal';
import { experimentalThemeDefinitions, NewThemeOptionsSchema } from '@grafana/data/internal';
import { themeJsonSchema } from '@grafana/data/unstable';
import { t } from '@grafana/i18n';
import { useChromeHeaderHeight } from '@grafana/runtime';
import { CodeEditor, Combobox, Field, Stack, useStyles2 } from '@grafana/ui';
@@ -16,24 +17,33 @@ import { getNavModel } from '../../core/selectors/navModel';
import { ThemeProvider } from '../../core/utils/ConfigProvider';
import { useDispatch, useSelector } from '../../types/store';
import schema from './schema.generated.json';
const themeMap: Record<string, NewThemeOptions> = {
dark: {
name: 'Dark',
id: 'dark',
colors: {
mode: 'dark',
},
},
light: {
name: 'Light',
id: 'light',
colors: {
mode: 'light',
},
},
...experimentalThemeDefinitions,
};
// Add additional themes
for (const [name, json] of Object.entries(experimentalThemeDefinitions)) {
const result = NewThemeOptionsSchema.safeParse(json);
if (!result.success) {
console.error(`Invalid theme definition for theme ${name}: ${result.error.message}`);
} else {
themeMap[result.data.id] = result.data;
}
}
const themeOptions = Object.entries(themeMap).map(([key, theme]) => ({
label: theme.name,
value: key,
@@ -59,16 +69,20 @@ export default function ThemePlayground() {
const theme = createTheme(themeInput);
setTheme(theme);
} catch (error) {
dispatch(notifyApp(createErrorNotification(`Failed to create theme: ${error}`)));
dispatch(notifyApp(createErrorNotification('Failed to create theme', `${error}`)));
}
};
const onEditorBlur = (value: string) => {
try {
const themeInput: NewThemeOptions = JSON.parse(value);
updateThemePreview(themeInput);
const themeInput = NewThemeOptionsSchema.safeParse(JSON.parse(value));
if (!themeInput.success) {
dispatch(notifyApp(createErrorNotification('Failed to parse theme', themeInput.error.issues[0].message)));
} else {
updateThemePreview(themeInput.data);
}
} catch (error) {
dispatch(notifyApp(createErrorNotification(`Failed to parse JSON: ${error}`)));
dispatch(notifyApp(createErrorNotification('Failed to parse JSON', `${error}`)));
}
};
@@ -115,7 +129,7 @@ export default function ThemePlayground() {
{
uri: 'theme-schema',
fileMatch: ['*'],
schema,
schema: themeJsonSchema,
},
],
});

View File

@@ -1,551 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"DeepPartial<ThemeColorsBase<ThemeRichColor>>": {
"properties": {
"action": {
"$ref": "#/definitions/DeepPartial<{selected:string;selectedBorder:string;hover:string;hoverOpacity:number;focus:string;disabledBackground:string;disabledText:string;disabledOpacity:number;}>"
},
"background": {
"$ref": "#/definitions/DeepPartial<{canvas:string;primary:string;secondary:string;elevated:string;}>"
},
"border": {
"$ref": "#/definitions/DeepPartial<{weak:string;medium:string;strong:string;}>"
},
"contrastThreshold": {
"type": "number"
},
"error": {
"$ref": "#/definitions/DeepPartial<ThemeRichColor>"
},
"gradients": {
"$ref": "#/definitions/DeepPartial<{brandVertical:string;brandHorizontal:string;}>"
},
"hoverFactor": {
"type": "number"
},
"info": {
"$ref": "#/definitions/DeepPartial<ThemeRichColor>"
},
"mode": {
"enum": [
"dark",
"light"
],
"type": "string"
},
"primary": {
"$ref": "#/definitions/DeepPartial<ThemeRichColor>"
},
"secondary": {
"$ref": "#/definitions/DeepPartial<ThemeRichColor>"
},
"success": {
"$ref": "#/definitions/DeepPartial<ThemeRichColor>"
},
"text": {
"$ref": "#/definitions/DeepPartial<{primary:string;secondary:string;disabled:string;link:string;maxContrast:string;}>"
},
"tonalOffset": {
"type": "number"
},
"warning": {
"$ref": "#/definitions/DeepPartial<ThemeRichColor>"
}
},
"type": "object"
},
"DeepPartial<ThemeRichColor>": {
"properties": {
"border": {
"description": "Used for borders",
"type": "string"
},
"borderTransparent": {
"description": "Used for weak colored borders like larger alert/banner boxes and smaller badges and tags",
"type": "string"
},
"contrastText": {
"description": "Text color for text ontop of main",
"type": "string"
},
"main": {
"description": "Main color",
"type": "string"
},
"name": {
"description": "color intent (primary, secondary, info, error, etc)",
"type": "string"
},
"shade": {
"description": "Used for hover",
"type": "string"
},
"text": {
"description": "Used for text",
"type": "string"
},
"transparent": {
"description": "Used subtly colored backgrounds",
"type": "string"
}
},
"type": "object"
},
"DeepPartial<{brandVertical:string;brandHorizontal:string;}>": {
"properties": {
"brandHorizontal": {
"type": "string"
},
"brandVertical": {
"type": "string"
}
},
"type": "object"
},
"DeepPartial<{canvas:string;primary:string;secondary:string;elevated:string;}>": {
"properties": {
"canvas": {
"description": "Dashboard and body background",
"type": "string"
},
"elevated": {
"description": "For popovers and menu backgrounds. This is the same color as primary in most light themes but in dark\nthemes it has a brighter shade to help give it contrast against the primary background.",
"type": "string"
},
"primary": {
"description": "Primary content pane background (panels etc)",
"type": "string"
},
"secondary": {
"description": "Cards and elements that need to stand out on the primary background",
"type": "string"
}
},
"type": "object"
},
"DeepPartial<{primary:string;secondary:string;disabled:string;link:string;maxContrast:string;}>": {
"properties": {
"disabled": {
"type": "string"
},
"link": {
"type": "string"
},
"maxContrast": {
"description": "Used for auto white or dark text on colored backgrounds",
"type": "string"
},
"primary": {
"type": "string"
},
"secondary": {
"type": "string"
}
},
"type": "object"
},
"DeepPartial<{selected:string;selectedBorder:string;hover:string;hoverOpacity:number;focus:string;disabledBackground:string;disabledText:string;disabledOpacity:number;}>": {
"properties": {
"disabledBackground": {
"description": "Used for disabled buttons and inputs",
"type": "string"
},
"disabledOpacity": {
"description": "Disablerd opacity",
"type": "number"
},
"disabledText": {
"description": "Disabled text",
"type": "string"
},
"focus": {
"description": "Used focused menu item / select option",
"type": "string"
},
"hover": {
"description": "Used for hovered menu item / select option",
"type": "string"
},
"hoverOpacity": {
"description": "Used for button/colored background hover opacity",
"type": "number"
},
"selected": {
"description": "Used for selected menu item / select option",
"type": "string"
},
"selectedBorder": {
"type": "string"
}
},
"type": "object"
},
"DeepPartial<{weak:string;medium:string;strong:string;}>": {
"properties": {
"medium": {
"type": "string"
},
"strong": {
"type": "string"
},
"weak": {
"type": "string"
}
},
"type": "object"
},
"ThemeShapeInput": {
"properties": {
"borderRadius": {
"type": "number"
}
},
"type": "object"
},
"ThemeTypographyInput": {
"properties": {
"fontFamily": {
"type": "string"
},
"fontFamilyMonospace": {
"type": "string"
},
"fontSize": {
"type": "number"
},
"fontWeightBold": {
"type": "number"
},
"fontWeightLight": {
"type": "number"
},
"fontWeightMedium": {
"type": "number"
},
"fontWeightRegular": {
"type": "number"
},
"htmlFontSize": {
"type": "number"
}
},
"type": "object"
},
"ThemeVizColor<\"blue\">": {
"properties": {
"aliases": {
"items": {
"type": "string"
},
"type": "array"
},
"color": {
"type": "string"
},
"name": {
"$ref": "#/definitions/ThemeVizColorShadeName_4"
},
"primary": {
"type": "boolean"
}
},
"type": "object"
},
"ThemeVizColor<\"green\">": {
"properties": {
"aliases": {
"items": {
"type": "string"
},
"type": "array"
},
"color": {
"type": "string"
},
"name": {
"$ref": "#/definitions/ThemeVizColorShadeName_3"
},
"primary": {
"type": "boolean"
}
},
"type": "object"
},
"ThemeVizColor<\"orange\">": {
"properties": {
"aliases": {
"items": {
"type": "string"
},
"type": "array"
},
"color": {
"type": "string"
},
"name": {
"$ref": "#/definitions/ThemeVizColorShadeName_1"
},
"primary": {
"type": "boolean"
}
},
"type": "object"
},
"ThemeVizColor<\"purple\">": {
"properties": {
"aliases": {
"items": {
"type": "string"
},
"type": "array"
},
"color": {
"type": "string"
},
"name": {
"$ref": "#/definitions/ThemeVizColorShadeName_5"
},
"primary": {
"type": "boolean"
}
},
"type": "object"
},
"ThemeVizColor<\"red\">": {
"properties": {
"aliases": {
"items": {
"type": "string"
},
"type": "array"
},
"color": {
"type": "string"
},
"name": {
"$ref": "#/definitions/ThemeVizColorShadeName"
},
"primary": {
"type": "boolean"
}
},
"type": "object"
},
"ThemeVizColor<\"yellow\">": {
"properties": {
"aliases": {
"items": {
"type": "string"
},
"type": "array"
},
"color": {
"type": "string"
},
"name": {
"$ref": "#/definitions/ThemeVizColorShadeName_2"
},
"primary": {
"type": "boolean"
}
},
"type": "object"
},
"ThemeVizColorShadeName": {
"enum": [
"dark-red",
"light-red",
"red",
"semi-dark-red",
"super-light-red"
],
"type": "string"
},
"ThemeVizColorShadeName_1": {
"enum": [
"dark-orange",
"light-orange",
"orange",
"semi-dark-orange",
"super-light-orange"
],
"type": "string"
},
"ThemeVizColorShadeName_2": {
"enum": [
"dark-yellow",
"light-yellow",
"semi-dark-yellow",
"super-light-yellow",
"yellow"
],
"type": "string"
},
"ThemeVizColorShadeName_3": {
"enum": [
"dark-green",
"green",
"light-green",
"semi-dark-green",
"super-light-green"
],
"type": "string"
},
"ThemeVizColorShadeName_4": {
"enum": [
"blue",
"dark-blue",
"light-blue",
"semi-dark-blue",
"super-light-blue"
],
"type": "string"
},
"ThemeVizColorShadeName_5": {
"enum": [
"dark-purple",
"light-purple",
"purple",
"semi-dark-purple",
"super-light-purple"
],
"type": "string"
},
"ThemeVizHue": {
"anyOf": [
{
"properties": {
"name": {
"const": "red",
"type": "string"
},
"shades": {
"items": {
"$ref": "#/definitions/ThemeVizColor<\"red\">"
},
"type": "array"
}
},
"type": "object"
},
{
"properties": {
"name": {
"const": "orange",
"type": "string"
},
"shades": {
"items": {
"$ref": "#/definitions/ThemeVizColor<\"orange\">"
},
"type": "array"
}
},
"type": "object"
},
{
"properties": {
"name": {
"const": "yellow",
"type": "string"
},
"shades": {
"items": {
"$ref": "#/definitions/ThemeVizColor<\"yellow\">"
},
"type": "array"
}
},
"type": "object"
},
{
"properties": {
"name": {
"const": "green",
"type": "string"
},
"shades": {
"items": {
"$ref": "#/definitions/ThemeVizColor<\"green\">"
},
"type": "array"
}
},
"type": "object"
},
{
"properties": {
"name": {
"const": "blue",
"type": "string"
},
"shades": {
"items": {
"$ref": "#/definitions/ThemeVizColor<\"blue\">"
},
"type": "array"
}
},
"type": "object"
},
{
"properties": {
"name": {
"const": "purple",
"type": "string"
},
"shades": {
"items": {
"$ref": "#/definitions/ThemeVizColor<\"purple\">"
},
"type": "array"
}
},
"type": "object"
}
]
}
},
"properties": {
"colors": {
"$ref": "#/definitions/DeepPartial<ThemeColorsBase<ThemeRichColor>>"
},
"name": {
"type": "string"
},
"shape": {
"$ref": "#/definitions/ThemeShapeInput"
},
"spacing": {
"properties": {
"gridSize": {
"type": "number"
}
},
"type": "object"
},
"typography": {
"$ref": "#/definitions/ThemeTypographyInput"
},
"visualization": {
"properties": {
"hues": {
"items": {
"$ref": "#/definitions/ThemeVizHue"
},
"type": "array"
},
"palette": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
}
},
"type": "object"
}

388
yarn.lock
View File

@@ -1964,6 +1964,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/aix-ppc64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/aix-ppc64@npm:0.27.2"
conditions: os=aix & cpu=ppc64
languageName: node
linkType: hard
"@esbuild/android-arm64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/android-arm64@npm:0.25.8"
@@ -1971,6 +1978,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/android-arm64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/android-arm64@npm:0.27.2"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
"@esbuild/android-arm@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/android-arm@npm:0.25.8"
@@ -1978,6 +1992,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/android-arm@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/android-arm@npm:0.27.2"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
"@esbuild/android-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/android-x64@npm:0.25.8"
@@ -1985,6 +2006,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/android-x64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/android-x64@npm:0.27.2"
conditions: os=android & cpu=x64
languageName: node
linkType: hard
"@esbuild/darwin-arm64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/darwin-arm64@npm:0.25.8"
@@ -1992,6 +2020,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/darwin-arm64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/darwin-arm64@npm:0.27.2"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@esbuild/darwin-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/darwin-x64@npm:0.25.8"
@@ -1999,6 +2034,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/darwin-x64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/darwin-x64@npm:0.27.2"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@esbuild/freebsd-arm64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/freebsd-arm64@npm:0.25.8"
@@ -2006,6 +2048,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/freebsd-arm64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/freebsd-arm64@npm:0.27.2"
conditions: os=freebsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/freebsd-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/freebsd-x64@npm:0.25.8"
@@ -2013,6 +2062,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/freebsd-x64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/freebsd-x64@npm:0.27.2"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/linux-arm64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-arm64@npm:0.25.8"
@@ -2020,6 +2076,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-arm64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-arm64@npm:0.27.2"
conditions: os=linux & cpu=arm64
languageName: node
linkType: hard
"@esbuild/linux-arm@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-arm@npm:0.25.8"
@@ -2027,6 +2090,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-arm@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-arm@npm:0.27.2"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"@esbuild/linux-ia32@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-ia32@npm:0.25.8"
@@ -2034,6 +2104,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-ia32@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-ia32@npm:0.27.2"
conditions: os=linux & cpu=ia32
languageName: node
linkType: hard
"@esbuild/linux-loong64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-loong64@npm:0.25.8"
@@ -2041,6 +2118,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-loong64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-loong64@npm:0.27.2"
conditions: os=linux & cpu=loong64
languageName: node
linkType: hard
"@esbuild/linux-mips64el@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-mips64el@npm:0.25.8"
@@ -2048,6 +2132,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-mips64el@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-mips64el@npm:0.27.2"
conditions: os=linux & cpu=mips64el
languageName: node
linkType: hard
"@esbuild/linux-ppc64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-ppc64@npm:0.25.8"
@@ -2055,6 +2146,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-ppc64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-ppc64@npm:0.27.2"
conditions: os=linux & cpu=ppc64
languageName: node
linkType: hard
"@esbuild/linux-riscv64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-riscv64@npm:0.25.8"
@@ -2062,6 +2160,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-riscv64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-riscv64@npm:0.27.2"
conditions: os=linux & cpu=riscv64
languageName: node
linkType: hard
"@esbuild/linux-s390x@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-s390x@npm:0.25.8"
@@ -2069,6 +2174,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-s390x@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-s390x@npm:0.27.2"
conditions: os=linux & cpu=s390x
languageName: node
linkType: hard
"@esbuild/linux-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-x64@npm:0.25.8"
@@ -2076,6 +2188,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-x64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/linux-x64@npm:0.27.2"
conditions: os=linux & cpu=x64
languageName: node
linkType: hard
"@esbuild/netbsd-arm64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/netbsd-arm64@npm:0.25.8"
@@ -2083,6 +2202,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/netbsd-arm64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/netbsd-arm64@npm:0.27.2"
conditions: os=netbsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/netbsd-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/netbsd-x64@npm:0.25.8"
@@ -2090,6 +2216,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/netbsd-x64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/netbsd-x64@npm:0.27.2"
conditions: os=netbsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/openbsd-arm64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/openbsd-arm64@npm:0.25.8"
@@ -2097,6 +2230,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/openbsd-arm64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/openbsd-arm64@npm:0.27.2"
conditions: os=openbsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/openbsd-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/openbsd-x64@npm:0.25.8"
@@ -2104,6 +2244,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/openbsd-x64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/openbsd-x64@npm:0.27.2"
conditions: os=openbsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/openharmony-arm64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/openharmony-arm64@npm:0.25.8"
@@ -2111,6 +2258,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/openharmony-arm64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/openharmony-arm64@npm:0.27.2"
conditions: os=openharmony & cpu=arm64
languageName: node
linkType: hard
"@esbuild/sunos-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/sunos-x64@npm:0.25.8"
@@ -2118,6 +2272,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/sunos-x64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/sunos-x64@npm:0.27.2"
conditions: os=sunos & cpu=x64
languageName: node
linkType: hard
"@esbuild/win32-arm64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/win32-arm64@npm:0.25.8"
@@ -2125,6 +2286,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/win32-arm64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/win32-arm64@npm:0.27.2"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@esbuild/win32-ia32@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/win32-ia32@npm:0.25.8"
@@ -2132,6 +2300,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/win32-ia32@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/win32-ia32@npm:0.27.2"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
"@esbuild/win32-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/win32-x64@npm:0.25.8"
@@ -2139,6 +2314,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/win32-x64@npm:0.27.2":
version: 0.27.2
resolution: "@esbuild/win32-x64@npm:0.27.2"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.7.0":
version: 4.7.0
resolution: "@eslint-community/eslint-utils@npm:4.7.0"
@@ -3109,6 +3291,7 @@ __metadata:
"@grafana/scenes": "npm:6.38.0"
"@grafana/schema": "npm:12.4.0-pre"
"@leeoniya/ufuzzy": "npm:1.0.19"
"@rollup/plugin-json": "npm:6.1.0"
"@rollup/plugin-node-resolve": "npm:16.0.1"
"@testing-library/react": "npm:16.3.0"
"@types/d3-interpolate": "npm:^3.0.0"
@@ -3147,9 +3330,11 @@ __metadata:
string-hash: "npm:^1.1.3"
tinycolor2: "npm:1.6.0"
tslib: "npm:2.8.1"
tsx: "npm:^4.21.0"
typescript: "npm:5.9.2"
uplot: "npm:1.6.32"
xss: "npm:^1.0.14"
zod: "npm:^4.3.0"
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
@@ -10765,15 +10950,6 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^18.11.9":
version: 18.19.129
resolution: "@types/node@npm:18.19.129"
dependencies:
undici-types: "npm:~5.26.4"
checksum: 10/0db4cb246d6012b1b523661a59c2e8e0b24527f1c02cfa3deb8e0b884492a07f2547c5353f56272b70037408e3dbe690ae923b8073fd7b0814e389148245e59f
languageName: node
linkType: hard
"@types/nodemailer@npm:*":
version: 6.4.15
resolution: "@types/nodemailer@npm:6.4.15"
@@ -17189,6 +17365,95 @@ __metadata:
languageName: node
linkType: hard
"esbuild@npm:~0.27.0":
version: 0.27.2
resolution: "esbuild@npm:0.27.2"
dependencies:
"@esbuild/aix-ppc64": "npm:0.27.2"
"@esbuild/android-arm": "npm:0.27.2"
"@esbuild/android-arm64": "npm:0.27.2"
"@esbuild/android-x64": "npm:0.27.2"
"@esbuild/darwin-arm64": "npm:0.27.2"
"@esbuild/darwin-x64": "npm:0.27.2"
"@esbuild/freebsd-arm64": "npm:0.27.2"
"@esbuild/freebsd-x64": "npm:0.27.2"
"@esbuild/linux-arm": "npm:0.27.2"
"@esbuild/linux-arm64": "npm:0.27.2"
"@esbuild/linux-ia32": "npm:0.27.2"
"@esbuild/linux-loong64": "npm:0.27.2"
"@esbuild/linux-mips64el": "npm:0.27.2"
"@esbuild/linux-ppc64": "npm:0.27.2"
"@esbuild/linux-riscv64": "npm:0.27.2"
"@esbuild/linux-s390x": "npm:0.27.2"
"@esbuild/linux-x64": "npm:0.27.2"
"@esbuild/netbsd-arm64": "npm:0.27.2"
"@esbuild/netbsd-x64": "npm:0.27.2"
"@esbuild/openbsd-arm64": "npm:0.27.2"
"@esbuild/openbsd-x64": "npm:0.27.2"
"@esbuild/openharmony-arm64": "npm:0.27.2"
"@esbuild/sunos-x64": "npm:0.27.2"
"@esbuild/win32-arm64": "npm:0.27.2"
"@esbuild/win32-ia32": "npm:0.27.2"
"@esbuild/win32-x64": "npm:0.27.2"
dependenciesMeta:
"@esbuild/aix-ppc64":
optional: true
"@esbuild/android-arm":
optional: true
"@esbuild/android-arm64":
optional: true
"@esbuild/android-x64":
optional: true
"@esbuild/darwin-arm64":
optional: true
"@esbuild/darwin-x64":
optional: true
"@esbuild/freebsd-arm64":
optional: true
"@esbuild/freebsd-x64":
optional: true
"@esbuild/linux-arm":
optional: true
"@esbuild/linux-arm64":
optional: true
"@esbuild/linux-ia32":
optional: true
"@esbuild/linux-loong64":
optional: true
"@esbuild/linux-mips64el":
optional: true
"@esbuild/linux-ppc64":
optional: true
"@esbuild/linux-riscv64":
optional: true
"@esbuild/linux-s390x":
optional: true
"@esbuild/linux-x64":
optional: true
"@esbuild/netbsd-arm64":
optional: true
"@esbuild/netbsd-x64":
optional: true
"@esbuild/openbsd-arm64":
optional: true
"@esbuild/openbsd-x64":
optional: true
"@esbuild/openharmony-arm64":
optional: true
"@esbuild/sunos-x64":
optional: true
"@esbuild/win32-arm64":
optional: true
"@esbuild/win32-ia32":
optional: true
"@esbuild/win32-x64":
optional: true
bin:
esbuild: bin/esbuild
checksum: 10/7f1229328b0efc63c4184a61a7eb303df1e99818cc1d9e309fb92600703008e69821e8e984e9e9f54a627da14e0960d561db3a93029482ef96dc82dd267a60c2
languageName: node
linkType: hard
"escalade@npm:^3.1.1, escalade@npm:^3.2.0":
version: 3.2.0
resolution: "escalade@npm:3.2.0"
@@ -18784,6 +19049,16 @@ __metadata:
languageName: node
linkType: hard
"fsevents@npm:~2.3.3":
version: 2.3.3
resolution: "fsevents@npm:2.3.3"
dependencies:
node-gyp: "npm:latest"
checksum: 10/4c1ade961ded57cdbfbb5cac5106ec17bc8bccd62e16343c569a0ceeca83b9dfef87550b4dc5cbb89642da412b20c5071f304c8c464b80415446e8e155a038c0
conditions: os=darwin
languageName: node
linkType: hard
"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin<compat/fsevents>":
version: 2.3.2
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin<compat/fsevents>::version=2.3.2&hash=df0bf1"
@@ -18793,6 +19068,15 @@ __metadata:
languageName: node
linkType: hard
"fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin<compat/fsevents>":
version: 2.3.3
resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin<compat/fsevents>::version=2.3.3&hash=df0bf1"
dependencies:
node-gyp: "npm:latest"
conditions: os=darwin
languageName: node
linkType: hard
"function-bind@npm:^1.1.2":
version: 1.1.2
resolution: "function-bind@npm:1.1.2"
@@ -19007,6 +19291,15 @@ __metadata:
languageName: node
linkType: hard
"get-tsconfig@npm:^4.7.5":
version: 4.13.0
resolution: "get-tsconfig@npm:4.13.0"
dependencies:
resolve-pkg-maps: "npm:^1.0.0"
checksum: 10/3603c6da30e312636e4c20461e779114c9126601d1eca70ee4e36e3e3c00e3c21892d2d920027333afa2cc9e20998a436b14abe03a53cde40742581cb0e9ceb2
languageName: node
linkType: hard
"get-uri@npm:^6.0.1":
version: 6.0.5
resolution: "get-uri@npm:6.0.5"
@@ -19253,7 +19546,7 @@ __metadata:
languageName: node
linkType: hard
"glob@npm:^7.0.3, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7":
"glob@npm:^7.0.3, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6":
version: 7.2.3
resolution: "glob@npm:7.2.3"
dependencies:
@@ -19795,7 +20088,6 @@ __metadata:
tween-functions: "npm:^1.2.0"
type-fest: "npm:^4.18.2"
typescript: "npm:5.9.2"
typescript-json-schema: "npm:^0.65.1"
uplot: "npm:1.6.32"
uuid: "npm:11.1.0"
vis-data: "npm:^8.0.0"
@@ -19811,7 +20103,7 @@ __metadata:
whatwg-fetch: "npm:3.6.20"
yaml: "npm:^2.0.0"
yargs: "npm:^18.0.0"
zod: "npm:^4.0.0"
zod: "npm:^4.3.0"
dependenciesMeta:
cypress:
built: true
@@ -26755,13 +27047,6 @@ __metadata:
languageName: node
linkType: hard
"path-equal@npm:^1.2.5":
version: 1.2.5
resolution: "path-equal@npm:1.2.5"
checksum: 10/fa4ef398dea6bd7bf36c5fe62b5f5c2c14fe1f1340cf355eb8a40c86577318dfa0401df86464bb0cc33ed227f115b2afec10d1adaa64260dedbbc23d33f3abbb
languageName: node
linkType: hard
"path-exists@npm:^3.0.0":
version: 3.0.0
resolution: "path-exists@npm:3.0.0"
@@ -30217,13 +30502,6 @@ __metadata:
languageName: node
linkType: hard
"safe-stable-stringify@npm:^2.2.0":
version: 2.5.0
resolution: "safe-stable-stringify@npm:2.5.0"
checksum: 10/2697fa186c17c38c3ca5309637b4ac6de2f1c3d282da27cd5e1e3c88eca0fb1f9aea568a6aabdf284111592c8782b94ee07176f17126031be72ab1313ed46c5c
languageName: node
linkType: hard
"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0":
version: 2.1.2
resolution: "safer-buffer@npm:2.1.2"
@@ -32785,7 +33063,7 @@ __metadata:
languageName: node
linkType: hard
"ts-node@npm:10.9.2, ts-node@npm:^10.9.1":
"ts-node@npm:10.9.2":
version: 10.9.2
resolution: "ts-node@npm:10.9.2"
dependencies:
@@ -32892,6 +33170,22 @@ __metadata:
languageName: node
linkType: hard
"tsx@npm:^4.21.0":
version: 4.21.0
resolution: "tsx@npm:4.21.0"
dependencies:
esbuild: "npm:~0.27.0"
fsevents: "npm:~2.3.3"
get-tsconfig: "npm:^4.7.5"
dependenciesMeta:
fsevents:
optional: true
bin:
tsx: dist/cli.mjs
checksum: 10/7afedeff855ba98c47dc28b33d7e8e253c4dc1f791938db402d79c174bdf806b897c1a5f91e5b1259c112520c816f826b4c5d98f0bad7e95b02dec66fedb64d2
languageName: node
linkType: hard
"tuf-js@npm:^2.2.1":
version: 2.2.1
resolution: "tuf-js@npm:2.2.1"
@@ -33127,24 +33421,6 @@ __metadata:
languageName: node
linkType: hard
"typescript-json-schema@npm:^0.65.1":
version: 0.65.1
resolution: "typescript-json-schema@npm:0.65.1"
dependencies:
"@types/json-schema": "npm:^7.0.9"
"@types/node": "npm:^18.11.9"
glob: "npm:^7.1.7"
path-equal: "npm:^1.2.5"
safe-stable-stringify: "npm:^2.2.0"
ts-node: "npm:^10.9.1"
typescript: "npm:~5.5.0"
yargs: "npm:^17.1.1"
bin:
typescript-json-schema: bin/typescript-json-schema
checksum: 10/50a1935378639d5d47e452702766a3fdab22e1d06192f26f81b79e0da504e71af987ff21cb13909479a202aad8d1216a654f16ebda2ee2056b5f859584b4c7d2
languageName: node
linkType: hard
"typescript-string-operations@npm:^1.4.1":
version: 1.5.1
resolution: "typescript-string-operations@npm:1.5.1"
@@ -33152,7 +33428,7 @@ __metadata:
languageName: node
linkType: hard
"typescript@npm:5.5.4, typescript@npm:~5.5.0":
"typescript@npm:5.5.4":
version: 5.5.4
resolution: "typescript@npm:5.5.4"
bin:
@@ -33182,7 +33458,7 @@ __metadata:
languageName: node
linkType: hard
"typescript@patch:typescript@npm%3A5.5.4#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A~5.5.0#optional!builtin<compat/typescript>":
"typescript@patch:typescript@npm%3A5.5.4#optional!builtin<compat/typescript>":
version: 5.5.4
resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin<compat/typescript>::version=5.5.4&hash=379a07"
bin:
@@ -33271,13 +33547,6 @@ __metadata:
languageName: node
linkType: hard
"undici-types@npm:~5.26.4":
version: 5.26.5
resolution: "undici-types@npm:5.26.5"
checksum: 10/0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd
languageName: node
linkType: hard
"undici-types@npm:~7.16.0":
version: 7.16.0
resolution: "undici-types@npm:7.16.0"
@@ -34823,7 +35092,7 @@ __metadata:
languageName: node
linkType: hard
"yargs@npm:17.7.2, yargs@npm:^17.0.1, yargs@npm:^17.1.1, yargs@npm:^17.3.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2":
"yargs@npm:17.7.2, yargs@npm:^17.0.1, yargs@npm:^17.3.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2":
version: 17.7.2
resolution: "yargs@npm:17.7.2"
dependencies:
@@ -34947,13 +35216,20 @@ __metadata:
languageName: node
linkType: hard
"zod@npm:^3.25 || ^4.0, zod@npm:^4.0.0":
"zod@npm:^3.25 || ^4.0":
version: 4.1.13
resolution: "zod@npm:4.1.13"
checksum: 10/0679190318928f69fcb07751063719de232c663b13955fcdb55db59839569d39f3f29b955cb0cba7af0b724233f88c06b3e84c550397ad4e68f8088fa6799d88
languageName: node
linkType: hard
"zod@npm:^4.3.0":
version: 4.3.5
resolution: "zod@npm:4.3.5"
checksum: 10/3148bd52e56ab7c1641ec397e6be6eddbb1d8f5db71e95baab9bb9622a0ea49d8a385885fc1c22b90fa6d8c5234e051f4ef5d469cfe3fb90198d5a91402fd89c
languageName: node
linkType: hard
"zstddec@npm:^0.1.0":
version: 0.1.0
resolution: "zstddec@npm:0.1.0"