or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

data-transformations.mddataframe-operations.mddatetime-operations.mdevent-system.mdfield-processing.mdindex.mdplugin-system.mdtheme-system.mdutility-functions.mdvalue-formatting.md
tile.json

theme-system.mddocs/

Theme System

Complete theming infrastructure including colors, typography, spacing, shadows, and visualization-specific color schemes for consistent styling across Grafana applications.

Capabilities

Theme Creation and Management

Functions for creating and managing theme instances.

/**
 * Creates a new theme instance with specified options
 * @param options - Theme creation options
 * @returns Complete GrafanaTheme2 instance
 */
function createTheme(options?: NewThemeOptions): GrafanaTheme2;

/**
 * Gets theme by identifier from registry
 * @param id - Theme identifier ('light', 'dark', etc.)
 * @returns Theme instance or undefined if not found
 */
function getThemeById(id: string): GrafanaTheme2 | undefined;

/**
 * Gets all built-in themes
 * @returns Array of built-in theme registry items
 */
function getBuiltInThemes(): ThemeRegistryItem[];

Usage Examples:

import { createTheme, getThemeById } from "@grafana/data";

// Create default theme
const theme = createTheme();

// Create dark theme
const darkTheme = createTheme({ name: 'dark' });

// Get existing theme
const lightTheme = getThemeById('light');

// Access theme properties
console.log(theme.colors.primary.main);
console.log(theme.typography.heading.h1.fontSize);
console.log(theme.spacing(2)); // Returns spacing unit * 2

Color Manipulation

Utility functions for color operations and transformations.

/**
 * Color manipulation utilities
 */
const colorManipulator: {
  /** Convert color to alpha variant */
  alpha(color: string, alpha: number): string;
  /** Darken color by specified amount */
  darken(color: string, coefficient: number): string;
  /** Lighten color by specified amount */
  lighten(color: string, coefficient: number): string;
  /** Emphasize color (darken or lighten based on luminance) */
  emphasize(color: string, coefficient?: number): string;
  /** Get color luminance */
  getLuminance(color: string): number;
  /** Get contrast ratio between two colors */
  getContrastRatio(foreground: string, background: string): number;
  /** Convert hex to RGB */
  hexToRgb(hex: string): { r: number; g: number; b: number } | null;
  /** Convert RGB to hex */
  rgbToHex(r: number, g: number, b: number): string;
  /** Convert HSL to RGB */
  hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number };
  /** Convert RGB to HSL */
  rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: number };
};

Theme Context

React context for theme access in components.

/**
 * React context for theme access
 */
const ThemeContext: React.Context<GrafanaTheme2>;

Type Definitions

/**
 * Main theme interface for Grafana 2.0+
 */
interface GrafanaTheme2 {
  /** Color palette and semantic colors */
  colors: ThemeColors;
  /** Typography scale and text styles */
  typography: ThemeTypography;
  /** Spacing scale and layout utilities */
  spacing: ThemeSpacing;
  /** Shadow definitions for depth */
  shadows: ThemeShadows;
  /** Shape properties (border radius, etc.) */
  shape: ThemeShape;
  /** Transition and animation settings */
  transitions: ThemeTransitions;
  /** Breakpoints for responsive design */
  breakpoints: ThemeBreakpoints;
  /** Z-index scale */
  zIndex: ThemeZIndices;
  /** Visualization-specific colors */
  visualization: ThemeVisualizationColors;
  /** Theme metadata */
  isDark: boolean;
  isLight: boolean;
  name: string;
}

/**
 * Theme creation options
 */
interface NewThemeOptions {
  /** Theme name identifier */
  name?: string;
  /** Color overrides */
  colors?: Partial<ThemeColors>;
  /** Typography overrides */
  typography?: Partial<ThemeTypography>;
  /** Spacing overrides */
  spacing?: Partial<ThemeSpacing>;
  /** Other component overrides */
  [key: string]: any;
}

/**
 * Theme color system
 */
interface ThemeColors {
  /** Mode information */
  mode: 'light' | 'dark';
  
  /** Primary color palette */
  primary: ThemeRichColor;
  /** Secondary color palette */
  secondary: ThemeRichColor;
  /** Success color palette */
  success: ThemeRichColor;
  /** Warning color palette */
  warning: ThemeRichColor;
  /** Error color palette */
  error: ThemeRichColor;
  /** Info color palette */
  info: ThemeRichColor;
  
  /** Text colors */
  text: {
    primary: string;
    secondary: string;
    disabled: string;
    link: string;
    maxContrast: string;
  };
  
  /** Background colors */
  background: {
    canvas: string;
    primary: string;
    secondary: string;
  };
  
  /** Border colors */
  border: {
    weak: string;
    medium: string;
    strong: string;
  };
  
  /** Action colors */
  action: {
    hover: string;
    focus: string;
    selected: string;
    selectedBorder: string;
    disabledBackground: string;
    disabledText: string;
  };
  
  /** Emphasis colors */
  emphasize: (color: string, emphasis?: number) => string;
  
  /** Get contrasting text color */
  getContrastText: (background: string) => string;
}

/**
 * Rich color definition with multiple shades
 */
interface ThemeRichColor {
  /** Lightest shade */
  shade: string;
  /** Main color */
  main: string;
  /** Darker variant */
  dark: string;
  /** Text color that contrasts with main */
  contrastText: string;
  /** Border color variant */
  border: string;
  /** Transparent version */
  transparent: string;
}

/**
 * Typography system
 */
interface ThemeTypography {
  /** Font family stack */
  fontFamily: string;
  /** Monospace font family */
  fontFamilyMonospace: string;
  /** Font weight scale */
  fontWeightLight: number;
  fontWeightRegular: number;
  fontWeightMedium: number;
  fontWeightBold: number;
  
  /** Font size scale */
  size: {
    base: string;
    xs: string;
    sm: string;
    md: string;
    lg: string;
    xl: string;
  };
  
  /** Line height scale */
  lineHeight: {
    xs: number;
    sm: number;
    md: number;
    lg: number;
  };
  
  /** Heading styles */
  heading: {
    h1: ThemeTypographyVariant;
    h2: ThemeTypographyVariant;
    h3: ThemeTypographyVariant;
    h4: ThemeTypographyVariant;
    h5: ThemeTypographyVariant;
    h6: ThemeTypographyVariant;
  };
  
  /** Body text styles */
  body: ThemeTypographyVariant;
  bodySmall: ThemeTypographyVariant;
  
  /** Code text styles */
  code: ThemeTypographyVariant;
}

/**
 * Typography variant definition
 */
interface ThemeTypographyVariant {
  fontSize: string;
  lineHeight: number;
  fontWeight: number;
  fontFamily: string;
  letterSpacing?: string;
}

/**
 * Typography variant types
 */
type ThemeTypographyVariantTypes = 
  | 'h1' 
  | 'h2' 
  | 'h3' 
  | 'h4' 
  | 'h5' 
  | 'h6' 
  | 'body' 
  | 'bodySmall' 
  | 'code';

/**
 * Spacing system
 */
interface ThemeSpacing {
  /** Base grid unit */
  gridSize: number;
  /** Spacing function */
  (factor?: number): string;
  /** Spacing tokens */
  xs: string;
  sm: string;
  md: string;
  lg: string;
  xl: string;
}

/**
 * Spacing tokens
 */
interface ThemeSpacingTokens {
  xs: string;
  sm: string; 
  md: string;
  lg: string;
  xl: string;
}

/**
 * Shadow definitions
 */
interface ThemeShadows {
  z1: string;
  z2: string;
  z3: string;
}

/**
 * Shape properties
 */
interface ThemeShape {
  borderRadius: (size?: number) => string;
  radius: {
    default: string;
    pill: string;
    circle: string;
  };
}

/**
 * Transition system
 */
interface ThemeTransitions {
  /** Transition duration scale */
  duration: {
    shortest: number;
    shorter: number;
    short: number;
    standard: number;
    complex: number;
    enteringScreen: number;
    leavingScreen: number;
  };
  
  /** Easing functions */
  easing: {
    easeInOut: string;
    easeOut: string;
    easeIn: string;
    sharp: string;
  };
  
  /** Create transition string */
  create: (props?: string | string[], options?: {
    duration?: number;
    easing?: string;
    delay?: number;
  }) => string;
}

/**
 * Breakpoint system
 */
interface ThemeBreakpoints {
  values: {
    xs: number;
    sm: number;
    md: number;
    lg: number;
    xl: number;
  };
  
  /** Media query helpers */
  up: (key: ThemeBreakpointsKey) => string;
  down: (key: ThemeBreakpointsKey) => string;
  between: (start: ThemeBreakpointsKey, end: ThemeBreakpointsKey) => string;
  only: (key: ThemeBreakpointsKey) => string;
}

/**
 * Breakpoint keys
 */
type ThemeBreakpointsKey = 'xs' | 'sm' | 'md' | 'lg' | 'xl';

/**
 * Z-index scale
 */
interface ThemeZIndices {
  background: number;
  element: number;
  content: number;
  dropdown: number;
  overlay: number;
  modal: number;
  sidemenu: number;
  tooltip: number;
}

/**
 * Visualization color system
 */
interface ThemeVisualizationColors {
  /** Categorical color palette */
  categorical: string[];
  /** Continuous color scales */
  continuous: {
    /** Blue-green scale */
    blue: string[];
    /** Red scale */
    red: string[];
    /** Green scale */
    green: string[];
    /** Purple scale */
    purple: string[];
    /** Yellow scale */  
    yellow: string[];
  };
  
  /** Diverging color scales */
  diverging: {
    /** Red-blue diverging */
    redBlue: string[];
    /** Green-red diverging */
    greenRed: string[];
    /** Blue-purple diverging */
    bluePurple: string[];
  };
  
  /** Get visualization color by index */
  getColorByName: (colorName: string) => ThemeVizColor;
  /** Get palette colors */
  getPalette: (name?: string) => ThemeVizHue;
}

/**
 * Visualization color definition
 */
interface ThemeVizColor {
  color: string;
  name: string;
}

/**
 * Visualization hue definition
 */
interface ThemeVizHue {
  name: string;
  colors: string[];
}

/**
 * Theme registry item
 */
interface ThemeRegistryItem {
  id: string;
  name: string;
  isDefault?: boolean;
  build: () => GrafanaTheme2;
}

Built-in Themes

The theme system includes several built-in themes:

Light Theme

  • ID: light
  • Name: Light
  • Default: Yes (for light mode)
  • Clean, bright appearance with light backgrounds

Dark Theme

  • ID: dark
  • Name: Dark
  • Default: Yes (for dark mode)
  • Dark backgrounds with light text for low-light environments

System Theme

  • ID: system
  • Name: System
  • Automatically switches between light and dark based on system preference

Usage Examples:

import { getThemeById, createTheme, ThemeContext } from "@grafana/data";
import React, { useContext } from "react";

// Get built-in theme
const darkTheme = getThemeById('dark');

// Create custom theme
const customTheme = createTheme({
  name: 'custom',
  colors: {
    primary: {
      main: '#ff6b35',
      dark: '#e55a2b',
      // ... other color properties
    }
  }
});

// Use theme in React component
function MyComponent() {
  const theme = useContext(ThemeContext);
  
  return (
    <div style={{
      backgroundColor: theme.colors.background.primary,
      color: theme.colors.text.primary,
      padding: theme.spacing(2),
      borderRadius: theme.shape.radius.default,
      fontSize: theme.typography.body.fontSize
    }}>
      Themed content
    </div>
  );
}

// Color manipulation
import { colorManipulator } from "@grafana/data";

const baseColor = '#3498db';
const lighterColor = colorManipulator.lighten(baseColor, 0.2);
const darkerColor = colorManipulator.darken(baseColor, 0.2);
const alphaColor = colorManipulator.alpha(baseColor, 0.5);