---
title: "Theming Overview"
framework: javascript
version: "2.1.2"
---

# Theming Overview

Theming refers to the process of adjusting design elements such as colours, borders and spacing to match your applications' design.

Studio provides a range of methods for customising its appearance. These are described in brief below.

Studio shares the same theming API as AG Grid. For in depth details on customising themes, see the [AG Grid Theming Documentation](https://ag-grid.com/javascript-data-grid/theming/).

The default Studio theme is exported as `studioTheme`.

## Colours and Dark Mode

Changing the colour scheme within Studio can be done by creating multiple themes, and updating the value of the `theme` property. However, a common use case is to toggle between modes, such as light and dark.

#### Theme Modes

```ts
import {
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
  studioTheme,
} from "ag-studio";

const theme = studioTheme
  .withParams(
    {
      backgroundColor: "#FFE8E0",
      foregroundColor: "#361008CC",
      browserColorScheme: "light",
    },
    "light-red",
  )
  .withParams(
    {
      backgroundColor: "#201008",
      foregroundColor: "#FFFFFFCC",
      browserColorScheme: "dark",
    },
    "dark-red",
  );

const initialState: AgReportState = {
  pages: [
    {
      id: "a",
      widgets: {
        "1": {
          type: "grid",
          dataMapping: {
            cols: [
              { id: "medals.country" },
              { id: "medals.sport" },
              { id: "medals.gold", aggregation: "sum" },
              { id: "medals.silver", aggregation: "sum" },
              { id: "medals.bronze", aggregation: "sum" },
              { id: "medals.total", aggregation: "sum" },
            ],
          },
        },
        "2": {
          type: "column-chart-grouped",
          dataMapping: {
            categoryKey: [{ id: "medals.country" }],
            valueKey: [
              { id: "medals.gold", aggregation: "sum" },
              { id: "medals.silver", aggregation: "sum" },
              { id: "medals.bronze", aggregation: "sum" },
            ],
          },
        },
      },
      widgetLayout: {
        "1": {
          xTrack: 0,
          yTrack: 0,
          xSpan: 24,
          ySpan: 16,
        },
        "2": {
          xTrack: 0,
          yTrack: 16,
          xSpan: 24,
          ySpan: 16,
        },
      },
    },
  ],
  selectedPageId: "a",
  panels: {
    filters: {
      collapsed: true,
    },
  },
};

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  theme,
  onApiReady: () => {
    updateModeData("light-red");
  },
};

let studioApi: AgStudioApi;

function toggleMode() {
  const currentMode = document.body.dataset.agThemeMode;
  const newMode = currentMode === "dark-red" ? "light-red" : "dark-red";
  updateModeData(newMode);
  document.getElementById("toggleMode")!.textContent =
    `Switch to ${newMode === "dark-red" ? "Light" : "Dark"} Mode`;
}

function updateModeData(newMode: "dark-red" | "light-red") {
  document.body.dataset.agThemeMode = newMode;
}

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
fetch("https://www.ag-grid.com/studio/example-assets/olympic-winners.json")
  .then((response) => response.json())
  .then((data) =>
    studioApi!.setProperty("data", {
      sources: [{ id: "medals", data }],
    }),
  );

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).toggleMode = toggleMode;
}
```

[Live example: Theme Modes](https://www.ag-grid.com/studio/examples/theming/theme-modes/typescript/)

Studio supports controlling the colour scheme by setting the `data-ag-theme-mode="mode"` attribute on the `<html>` or `<body>` elements elements, where `mode` is any of:

- `light`
- `dark`
- `dark-blue`

> **Note**
>
> If your Studio instance is inside Shadow DOM or you only want to change the mode of some Studio instances on a page, you may set the attribute on any ancestor element of Studio that has the `ag-theme-mode` class on it:
>
> ```html
> <div class="ag-theme-mode" data-ag-theme-mode="dark">
>     ...
> </div>
> ```

It is also possible to define your own colour modes, by passing the mode name to the second parameter of `withParams`. The example above defines custom colour schemes for light and dark mode and switches between them by setting the `data-ag-theme-mode` attribute on the `body` element:

```js
const myTheme = studioTheme
    .withParams(
        {
            backgroundColor: '#FFE8E0',
            foregroundColor: '#361008CC',
            browserColorScheme: 'light',
        },
        'light-red'
    )
    .withParams(
        {
            backgroundColor: '#201008',
            foregroundColor: '#FFFFFFCC',
            browserColorScheme: 'dark',
        },
        'dark-red'
    );
```

## Theme Params

#### Theme Params

```ts
import {
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
  studioTheme,
} from "ag-studio";

const theme = studioTheme.withParams({
  gridCellTextColor: "pink",
  chartAxisLineColor: "blue",
});

const initialState: AgReportState = {
  pages: [
    {
      id: "a",
      widgets: {
        "1": {
          type: "grid",
          dataMapping: {
            cols: [
              { id: "medals.country" },
              { id: "medals.sport" },
              { id: "medals.gold", aggregation: "sum" },
              { id: "medals.silver", aggregation: "sum" },
              { id: "medals.bronze", aggregation: "sum" },
              { id: "medals.total", aggregation: "sum" },
            ],
          },
        },
        "2": {
          type: "column-chart-grouped",
          dataMapping: {
            categoryKey: [{ id: "medals.country" }],
            valueKey: [
              { id: "medals.gold", aggregation: "sum" },
              { id: "medals.silver", aggregation: "sum" },
              { id: "medals.bronze", aggregation: "sum" },
            ],
          },
        },
      },
      widgetLayout: {
        "1": {
          xTrack: 0,
          yTrack: 0,
          xSpan: 24,
          ySpan: 16,
        },
        "2": {
          xTrack: 0,
          yTrack: 16,
          xSpan: 24,
          ySpan: 16,
        },
      },
    },
  ],
  selectedPageId: "a",
  panels: {
    filters: {
      collapsed: true,
    },
  },
};

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  theme,
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
fetch("https://www.ag-grid.com/studio/example-assets/olympic-winners.json")
  .then((response) => response.json())
  .then((data) =>
    studioApi!.setProperty("data", {
      sources: [{ id: "medals", data }],
    }),
  );
```

[Live example: Theme Params](https://www.ag-grid.com/studio/examples/theming/theme-params/typescript/)

The example above demonstrates customising Studio by setting theme params via both the theme `withParams` method and CSS variables.

```js
const studioProperties = {
    theme: studioTheme.withParams({
        gridCellTextColor: 'pink',
        chartAxisLineColor: 'blue',
    }),

    // other studio properties ...
}
```

```
--ag-chart-palette-fills-1-color: yellow
```

The CSS variable name is the theme param name in kebab-case, with an `--ag-` prefix. E.g. `foregroundColor` becomes `--ag-foreground-color`.

The theme params are split into five types:

- [Shared Theme Params](https://www.ag-grid.com/studio/javascript/studio-theme#shared-theme-params---agstudiosharedthemeparams) (no prefix) - these may affect the Studio UI, grid widgets, and chart widgets.
- [Studio Theme Params](https://www.ag-grid.com/studio/javascript/studio-theme#studio-theme-params---agstudiocorethemeparams) (prefixed `studio`) - these only affect the Studio UI.
- [Grid Theme Params](https://www.ag-grid.com/studio/javascript/studio-theme#grid-theme-params---agstudiogridthemeparams) (prefixed `grid`) - these only affect grid widgets.
- [Chart Theme Params](https://www.ag-grid.com/studio/javascript/studio-theme#chart-theme-params---agstudiochartthemeparams) (prefixed `chart`) - these only affect chart widgets.
- [Default Theme Params](https://www.ag-grid.com/studio/javascript/studio-theme#default-theme-params) (no prefix) - these params are used for the default Studio theme (`studioTheme`). They are not used if you are creating your own Studio theme via `createStudioTheme()`.

In most cases, the Studio, grid and chart theme params will inherit from the equivalent shared theme param.

E.g. `gridTextColor` and `chartTextColor` both inherit from `textColor`.

See the [Theme Reference](https://www.ag-grid.com/studio/javascript/studio-theme/) for the full list of theme params.

## Icons

Studio shares the [AG Grid Icons](https://ag-grid.com/javascript-data-grid/custom-icons/#provided-icons), and adds additional icons.

### Swapping the Provided Icon Set

To swap out provided icon set, first [Swap out the AG Grid Icon Set](https://www.ag-grid.com/javascript-data-grid/custom-icons/#swapping-the-provided-icon-set). Then provide your own icon set for Studio.

```
const myTheme = studioTheme
    .withPart(gridIconSet)
    .withPart(
        createPart({
            feature: 'iconSetStudio',
            css: myCustomIconCss,
        })
    );
```

### Replacing Individual Icons

Replacing individual icons depends on the icon source. If the icon is one of the [AG Grid Icons](https://ag-grid.com/javascript-data-grid/custom-icons/#provided-icons), then follow the [AG Grid Guide to Replacing Individual Icons](https://www.ag-grid.com/javascript-data-grid/custom-icons/#replacing-individual-icons). Replacing Studio icons is similar, but uses the `studioIconOverrides` function instead.

#### Replacing Individual Icons

```ts
import {
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
  studioIconOverrides,
  studioTheme,
} from "ag-studio";

const theme = studioTheme.withPart(
  studioIconOverrides({
    type: "image",
    icons: {
      "double-chevron-right": {
        url: "https://www.ag-grid.com/studio/images/brandmark.svg",
      },
    },
  }),
);

const initialState: AgReportState = {
  pages: [
    {
      id: "a",
    },
  ],
  selectedPageId: "a",
};

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  theme,
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
fetch("https://www.ag-grid.com/studio/example-assets/olympic-winners.json")
  .then((response) => response.json())
  .then((data) =>
    studioApi!.setProperty("data", {
      sources: [{ id: "medals", data }],
    }),
  );
```

[Live example: Replacing Individual Icons](https://www.ag-grid.com/studio/examples/theming/replacing-individual-icons/typescript/)

The example above replaces the collapse icon in the panels with the AG Studio logo.

```
const myTheme = studioTheme
    .withPart(
        studioIconOverrides({
            type: 'image',
            icons: {
                'double-chevron-right': {
                    url: 'https://www.ag-grid.com/studio/images/brandmark.svg',
                },
            },
        })
    );
```

## Understanding CSS Rule Maintenance and Breaking Changes

With each release of Studio we add features and improve existing ones, and as a result the DOM structure changes with every release - even minor releases. Of course we test and update the CSS rules in our themes to make sure they still work, and this includes ensuring that customisations made via CSS custom properties do not break between releases. But if you have written your own CSS rules, you will need to test and update them.

The simpler your CSS rules are, the less likely they are to break between releases. Prefer selectors that target a single class name where possible.

## Adapting an Existing AG Grid Theme for Studio

It's possible to adapt an existing AG Grid theme to a Studio theme. The grid theme cannot be passed directly to Studio, but custom parts or params can.

Any params that exist in both the AG Grid theme params and [AgStudioSharedThemeParams](https://www.ag-grid.com/studio/javascript/studio-theme#shared-theme-params---agstudiosharedthemeparams) can be re-used directly. These will affect the whole of Studio.

The other params can be prefixed with `grid` to target the grid widgets only. E.g. `headerColumnBorder` becomes `gridHeaderColumnBorder`.

> **Note**
>
> Only AG Grid themes using the theming API can be used in Studio. Legacy themes are not supported.
