---
title: Manage Theme Settings
product: Survey Creator
description: This demo illustrates how to customize the Theme Editor's settings panel by adding new settings or hiding unwanted ones. CSS Theme Editor is a fully integrated form styling tool that allows you to create form themes using a panel of UI controls.
framework: React
source: https://surveyjs.io/survey-creator/examples/theme-editor-modify-settings-panel/reactjs
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Manage Theme Settings (React)

SurveyJS Form Builder comes with a fully integrated Theme Editor. This styling tool enables form designers to create distinctive looks for their forms using a set of property editors. Internally, these editors modify SCSS variables. This demo shows how you can add custom property editors and hide unwanted editors from the Property Grid of the Theme Editor.

Theme Editor's Property Grid is [built upon a regular survey from the SurveyJS Form Library](https://surveyjs.io/survey-creator/documentation/property-grid-customization#add-custom-properties-to-the-property-grid). Therefore, Property Grid customization involves the same techniques that are used to customize surveys, namely adding and modifying properties of two SurveyJS classes: `ThemeModel` (implements the [`ITheme`](https://surveyjs.io/form-library/documentation/api-reference/itheme) interface) and `HeaderModel` (implements [`IHeader`](https://surveyjs.io/form-library/documentation/api-reference/iheader)). As public SurveyJS classes, they are serialized to JSON (see [Serialization and Deserialization](https://surveyjs.io/documentation/surveyjs-architecture#serialization-and-deserialization) for more information). Their serialization rules are registered under the `"theme"` and `"header"` aliases. To add or remove theme settings, you need to modify the JSON properties of these classes using the `Serializer` API as described below.

## Hide Settings from the Property Grid

To hide a specific theme or header setting from the Property Grid, access the corresponding JSON property using the `Serializer`'s `getProperty(className, propertyName)` method and set its `visible` attribute to `false`. The following code shows how to hide the "Background image" and related settings for the survey and its header:

```js
import { Serializer } from "survey-core";

Serializer.getProperty("theme", "backgroundImage").visible = false;
Serializer.getProperty("theme", "backgroundImageFit").visible = false;
Serializer.getProperty("theme", "backgroundImageAttachment").visible = false;
Serializer.getProperty("theme", "backgroundOpacity").visible = false;

Serializer.getProperty("header", "backgroundImage").visible = false;
Serializer.getProperty("header", "backgroundImageFit").visible = false;
Serializer.getProperty("header", "backgroundImageOpacity").visible = false;
Serializer.getProperty("header", "overlapEnabled").visible = false;
```

## Add Settings to the Property Grid

To add a custom setting to the Property Grid, add a corresponding property to the theme or header class using the `Serializer`'s `addProperty(className, propMeta)` method. Pass `"theme"` or `"header"` as the `className` parameter and an object with [property attributes](https://surveyjs.io/form-library/documentation/customize-question-types/add-custom-properties-to-a-form#survey-element-property-settings) as the `propMeta` parameter. Some of these attributes have specifics when used in Theme Editor:

- The [`type`](https://surveyjs.io/form-library/documentation/customize-question-types/add-custom-properties-to-a-form#type) attribute supports additional values:

    | `type` | Property editor(s) | Description |
    | ------ | --------------- | ----------- |
    | `"coloralpha"` | A color picker and an opacity editor | Use this type for color values that support alpha channel. The editors produce an RGBA color value. |
    | `"font"` | Editors for font family, weight, color, opacity, and size | Use this type for font settings. The editors produce the following object: `{ family: string, weight: string, size: number, color: string }` |
    | `"shadoweffects"` | Editors for shadow effects | Use this type for configuring shadow effects around survey elements. The editors produce a [`box-shadow`](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow) string value. |

- The [`category`](https://surveyjs.io/form-library/documentation/customize-question-types/add-custom-properties-to-a-form#category) attribute supports a different set of categories:

    | `category` | Category title | `categoryIndex` | Description |
    | ---------- | -------------- | --------------- | ----------- |
    | `"general"` | General | -1 | - |
    | `"header"` | Header | 100 | - |
    | `"background"` | Background | 200 | - |
    | `"appearance"` | Appearance | 300 | Has subcategories that depend on whether the "Advanced mode" toggle is ON or OFF |
    | `"appearancecolor"` | - | 100 | Advanced mode is OFF |
    | `"appearancefont"` | - | 200 | Advanced mode is OFF |
    | `"appearanceother"` | - | 300 | Advanced mode is OFF |
    | `"appearanceprimarycolor"` | - | 400 | Advanced mode is ON |
    | `"appearancepage"` | Page | 500 | Advanced mode is ON |
    | `"appearancequestion"` | Question box | 600 | Advanced mode is ON |
    | `"appearanceinput"` | Input element | 700 | Advanced mode is ON |
    | `"appearancelines"` | Lines | 800 | Advanced mode is ON |

- The [`name`](https://surveyjs.io/form-library/documentation/customize-question-types/add-custom-properties-to-a-form#name) attribute value must start with `--`, except for settings with `type: "font"`.         
This rule exists because most theme settings are directly mapped to SCSS variables, which must begin with `--`. However, a setting of the font type is mapped to an *object* whose *fields* are mapped to SCSS variables. Names for these font variables are constructed automatically and already include the `--` prefix.

This demo shows how to add two settings that customize question title font and matrix column and row title font. These settings are used instead of a "Title font" setting that specifies a single font for all titles. The following instructions describe how to implement this functionality:

1. Create two settings that customize title fonts separately.

    ```js
    import { Serializer } from "survey-core";

    Serializer.addProperty("theme", {
        name: "custom-question-title", // must start with `--` unless the `type` is `"font"`
        type: "font",
        displayName: "Question title font",
        category: "appearancequestion",
        default: { family: "Open Sans", weight: "600", size: 16, color: "rgba(0, 0, 0, 0.91)" }
    });

    Serializer.addProperty("theme", {
        name: "matrix-title",  // must start with `--` unless the `type` is `"font"`
        type: "font",
        displayName: "Matrix title font",
        category: "appearancequestion",
        default: { family: "Open Sans", weight: "600", size: 16, color: "rgba(0, 0, 0, 0.91)" }
    });
    ```
    These settings produce SCSS variables whose names are constructed based on the setting name. We will use these variables for styles in step 3.

    [View Source Code](https://github.com/surveyjs/survey-creator/blob/52649ef6fb6be3a3e9e1e7654ba2785ab056c6e2/packages/survey-creator-core/src/components/tabs/theme-custom-questions/font-settings.ts#L119-L128 (linkStyle))

2. Hide the default "Title font" setting.

    ```js
    Serializer.getProperty("theme", "questionTitle").visible = false;
    ```

3. Declare styles that apply the new SCSS variables and override the default styles.

    ```css
    .sd-title.sd-element__title {
        color: var(--sjs-font-custom-question-title-color, var(--sjs-font-questiontitle-color, var(--sjs-general-forecolor, #161616)));
        font-family: var(--sjs-font-custom-question-title-family, var(--sjs-font-questiontitle-family, var(--sjs-font-family, var(--font-family))));
        font-size: var(--sjs-font-custom-question-title-size, var(--sjs-font-questiontitle-size, var(--sjs-font-size, 16px)));
        font-weight: var(--sjs-font-custom-question-title-weight, var(--sjs-font-questiontitle-weight, 600));
    }
    .sd-table__cell--header,
    .sd-matrix__cell:first-of-type {
        color: var(--sjs-font-matrix-title-color, var(--sjs-font-questiontitle-color, var(--sjs-general-forecolor, #161616)));
        font-family: var(--sjs-font-matrix-title-family, var(--sjs-font-questiontitle-family, var(--sjs-font-family, var(--font-family))));
        font-size: var(--sjs-font-matrix-title-size, var(--sjs-font-questiontitle-size, var(--sjs-font-size, 16px)));
        font-weight: var(--sjs-font-matrix-title-weight, var(--sjs-font-questiontitle-weight, 600));
    }
    ```

Refer to the code listings for the full code example.

## Files

### `public/index.html`

```html
<!-- Uncomment the following lines to enable Ace Editor in the JSON Editor tab -->
<!-- 
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ace.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ext-searchbox.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/theme-clouds_midnight.js"></script>
-->

<div id="surveyCreatorContainer" style="position: absolute; height: 100%; width: 100%"></div>
```

### `src/survey_json.js`

```js
export const formJSON = {
  "elements": [
    {
      "type": "matrix",
      "name": "qualities",
      "title": "Please indicate if you agree or disagree with the following statements",
      "isRequired": true,
      "columns": [{
        "value": 5,
        "text": "Strongly agree"
      }, {
        "value": 4,
        "text": "Agree"
      }, {
        "value": 3,
        "text": "Neutral"
      }, {
        "value": 2,
        "text": "Disagree"
      }, {
        "value": 1,
        "text": "Strongly disagree"
      }],
      "rows": [{
        "value": "affordable",
        "text": "Product is affordable"
      }, {
        "value": "does-what-it-claims",
        "text": "Product does what it claims"
      }, {
        "value": "easy-to-use",
        "text": "Product is easy to use"
      }],
      "alternateRows": true
    }
  ]
}
```

### `src/theme_json.js`

```js
export const customTheme = {
  "themeName": "default",
  "colorPalette": "light",
  "isPanelless": false,
  "backgroundImage": "",
  "backgroundOpacity": 1,
  "backgroundImageAttachment": "scroll",
  "backgroundImageFit": "cover",
  "cssVariables": {
    "--sjs-font-custom-question-title-color": "rgba(99, 34, 137, 0.91)",
    "--sjs-font-matrix-title-color": "rgba(252, 3, 162, 0.91)",
    "--sjs2-color-bg-basic-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-utility-property-grid": "rgba(255, 255, 255, 1)",
    "--sjs2-color-utility-tabs": "rgba(255, 255, 255, 1)",
    "--sjs2-color-utility-toolbox": "rgba(255, 255, 255, 1)",
    "--sjs2-color-bg-basic-primary-dim": "rgba(248, 248, 248, 1)",
    "--sjs2-color-bg-neutral-tertiary-dim": "rgba(243, 243, 243, 1)",
    "--sjs2-color-utility-surface-survey-panelless": "rgba(243, 243, 243, 1)",
    "--sjs2-color-utility-surface-survey": "rgba(243, 243, 243, 1)",
    "--sjs2-color-bg-basic-secondary": "rgba(249, 249, 249, 1)",
    "--sjs2-color-bg-basic-secondary-dim": "rgba(243, 243, 243, 1)",
    "--sjs2-color-fg-basic-primary": "rgba(0, 0, 0, 0.91)",
    "--sjs2-color-fg-basic-secondary": "rgba(0, 0, 0, 0.45)",
    "--sjs2-color-project-brand-600": "rgba(25, 179, 148, 1)",
    "--sjs2-color-bg-brand-secondary": "rgba(25, 179, 148, 0.1)",
    "--sjs2-color-bg-brand-primary-dim": "rgba(20, 164, 139, 1)",
    "--sjs2-color-fg-brand-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-fg-brand-primary-disabled": "rgba(255, 255, 255, 0.25)",
    "--sjs2-base-unit-size": "8px",
    "--sjs2-base-unit-spacing": "8px",
    "--sjs2-base-unit-radius": "4px",
    "--sjs2-color-bg-accent-primary": "rgba(255, 152, 20, 1)",
    "--sjs2-color-bg-accent-secondary": "rgba(255, 152, 20, 0.1)",
    "--sjs2-color-bg-accent-secondary-dim": "rgba(255, 152, 20, 0.25)",
    "--sjs2-color-fg-accent-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-fg-accent-primary-disabled": "rgba(255, 255, 255, 0.25)",
    "--sjs2-border-effect-surface-default": "0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
    "--sjs2-border-effect-floating-default": "0px 2px 6px 0px rgba(0, 0, 0, 0.1),0px 8px 16px 0px rgba(0, 0, 0, 0.1)",
    "--sjs2-border-effect-component-formbox-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
    "--sjs2-border-effect-component-check-true-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
    "--sjs2-border-effect-component-check-false-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
    "--sjs2-color-border-basic-secondary": "rgba(0, 0, 0, 0.09)",
    "--sjs2-color-component-input-default-line": "rgba(0, 0, 0, 0.16)",
    "--sjs2-color-border-basic-secondary-overlay": "rgba(0, 0, 0, 0.16)",
    "--sjs2-color-bg-alert-primary": "rgba(229, 10, 62, 1)",
    "--sjs2-color-bg-alert-secondary": "rgba(229, 10, 62, 0.1)",
    "--sjs2-color-fg-alert-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-bg-positive-primary": "rgba(25, 179, 148, 1)",
    "--sjs2-color-bg-positive-secondary": "rgba(25, 179, 148, 0.1)",
    "--sjs2-color-fg-positive-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-bg-note-primary": "rgba(67, 127, 217, 1)",
    "--sjs2-color-bg-note-secondary": "rgba(67, 127, 217, 0.1)",
    "--sjs2-color-fg-note-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-bg-warning-primary": "rgba(255, 152, 20, 1)",
    "--sjs2-color-bg-warning-secondary": "rgba(255, 152, 20, 0.1)",
    "--sjs2-color-fg-warning-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-typography-font-weight-component-header-title": "700",
    "--sjs2-typography-font-size-component-header-description": "20px",
    "--sjs2-typography-font-weight-component-page-title": "700"
  },
  "headerView": "basic"
}
```

### `src/SurveyCreatorComponent.jsx`

```js
import React from "react";
import { SurveyCreator, SurveyCreatorComponent } from "survey-creator-react";
import "survey-core/survey.i18n";
import "survey-creator-core/survey-creator-core.i18n";
import { formJSON } from "./survey_json";
import { customTheme } from "./theme_json";
import { Serializer } from "survey-core";
import "survey-core/survey-core.css";
import "survey-creator-core/survey-creator-core.css";
import "./index.css";

import SurveyTheme from "survey-core/themes";
import { registerCreatorTheme, registerSurveyTheme } from "survey-creator-core";

registerSurveyTheme(SurveyTheme); // Add predefined Form Library UI themes
registerCreatorTheme(SurveyTheme); // Add predefined Survey Creator UI themes

// Create a setting that customizes question titles
Serializer.addProperty("theme", {
    name: "custom-question-title", // must start with `--` unless the `type` is `"font"`
    type: "font",
    displayName: "Question title font",
    category: "appearancequestion",
    default: { family: "Open Sans", weight: "600", size: 16, color: "rgba(0, 0, 0, 0.91)" }
});

// Create a setting that customizes matrix column and row titles separately from question titles
Serializer.addProperty("theme", {
    name: "matrix-title", // must start with `--` unless the `type` is `"font"`
    type: "font",
    displayName: "Matrix column and row title font",
    category: "appearancequestion",
    default: { family: "Open Sans", weight: "600", size: 16, color: "rgba(0, 0, 0, 0.91)" }
});

// Hide the default "Question box" > "Title font" setting
Serializer.getProperty("theme", "questionTitle").visible = false;

// Hide the "Background image" and related settings for the survey
Serializer.getProperty("theme", "backgroundImage").visible = false;
Serializer.getProperty("theme", "backgroundImageFit").visible = false;
Serializer.getProperty("theme", "backgroundImageAttachment").visible = false;
Serializer.getProperty("theme", "backgroundOpacity").visible = false;

// Hide the "Background image" and related settings for the survey header
Serializer.getProperty("header", "backgroundImage").visible = false;
Serializer.getProperty("header", "backgroundImageFit").visible = false;
Serializer.getProperty("header", "backgroundImageOpacity").visible = false;
Serializer.getProperty("header", "overlapEnabled").visible = false;
function SurveyCreatorRenderComponent() {
    const creator = new SurveyCreator({ showThemeTab: true });
    creator.JSON = formJSON;
    // Set the custom theme as an initial survey theme
    creator.theme = customTheme;
    
    // Activate Theme Editor
    creator.activeTab = "theme";
    return (<SurveyCreatorComponent creator={creator} />);
}

export default SurveyCreatorRenderComponent;
```

### `src/index.css`

```css
.sd-table__cell--header,
.sd-matrix__cell:first-of-type {
    color: var(--sjs-font-matrix-title-color, var(--sjs2-color-component-question-default-title, #161616));
    font-family: var(--sjs-font-matrix-title-family, var(--sjs2-typography-font-family-component-question-title));
    font-size: var(--sjs-font-matrix-title-size, var(--sjs2-typography-font-size-component-question-title, 16px));
    font-weight: var(--sjs-font-matrix-title-weight, var(--sjs2-typography-font-weight-component-question-title, 600));
}

.sd-title.sd-element__title {
    color: var(--sjs-font-custom-question-title-color, var(--sjs2-color-component-question-default-title, #161616));
    font-family: var(--sjs-font-custom-question-title-family, var(--sjs2-typography-font-family-component-question-title));
    font-size: var(--sjs-font-custom-question-title-size, var(--sjs2-typography-font-size-component-question-title, 16px));
    font-weight: var(--sjs-font-custom-question-title-weight, var(--sjs2-typography-font-weight-component-question-title, 600));
}
```

### `src/index.js`

```js
import React from "react";
import { createRoot } from "react-dom/client";
import SurveyCreatorRenderComponent from "./SurveyCreatorComponent";

const root = createRoot(document.getElementById("surveyCreatorContainer"));
root.render(<SurveyCreatorRenderComponent />);
```

### `package.json`

```json
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "survey-core": "latest",
    "survey-react-ui": "latest",
    "survey-creator-core": "latest",
    "survey-creator-react": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/survey-creator/examples/theme-editor-modify-settings-panel/angular.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/theme-editor-modify-settings-panel/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/theme-editor-modify-settings-panel/jquery.md)
- [Vanilla JS](https://surveyjs.io/survey-creator/examples/theme-editor-modify-settings-panel/vanillajs.md)
