---
title: Add a Custom Question Type
product: Form Library
description: With SurveyJS, you can customize not only the look of your forms and surveys in a no-code editor, but also use custom question types. View a free demo for JavaScript to learn how to add a custom color picker question to your form builder.
framework: React
source: https://surveyjs.io/form-library/examples/add-custom-question-type-to-form-builder/reactjs
index: https://surveyjs.io/form-library/examples/overview.md
---

# Add a Custom Question Type (React)

Custom question types allow you to extend the functionality of your survey by modifying predefined question types or integrating third-party components. This example shows how to create a custom question type based on a third-party Color Picker component.

Refer to the documentation articles below for a step-by-step tutorial. The same instructions apply if you implement custom question types that are not based on third-party components.

- [Integrate Third-Party React Components](https://surveyjs.io/form-library/documentation/customize-question-types/third-party-component-integration-react)
- [Integrate Third-Party Angular Components](https://surveyjs.io/form-library/documentation/customize-question-types/third-party-component-integration-angular)
- [Integrate Third-Party Vue 3 Components](/form-library/documentation/customize-question-types/third-party-component-integration-vue)

## Files

### `public/index.html`

```html
<div id="surveyElement" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; min-height: 100%; height:100%"></div>
```

### `src/ColorComponent.jsx`

```js
import React from "react";
import { ElementFactory, Question, Serializer } from "survey-core";
import { SliderPicker, SketchPicker, CompactPicker } from "react-color";
import { SurveyQuestionElementBase, ReactQuestionFactory } from "survey-react-ui";

// Must use lowercase
const CUSTOM_TYPE = "color-picker";

export class QuestionColorPickerModel extends Question {
  getType() {
    return CUSTOM_TYPE;
  }

  get colorPickerType() {
    return this.getPropertyValue("colorPickerType");
  }
  set colorPickerType(val) {
    this.setPropertyValue("colorPickerType", val);
  }

  get disableAlpha() {
    return this.getPropertyValue("disableAlpha");
  }
  set disableAlpha(val) {
    this.setPropertyValue("disableAlpha", val);
  }
}

// Add question type metadata for further serialization into JSON
Serializer.addClass(
  CUSTOM_TYPE,
  [{
    name: "colorPickerType",
    default: "Slider",
    choices: ["Slider", "Sketch", "Compact"]
  }, {
    name: "disableAlpha:boolean",
    dependsOn: "colorPickerType",
    visibleIf: function (obj) {
      return obj.colorPickerType === "Sketch";
    }
  }],
  function () {
    return new QuestionColorPickerModel("");
  },
  "question"
);

ElementFactory.Instance.registerElement(CUSTOM_TYPE, (name) => {
  return new QuestionColorPickerModel(name);
});

// A class that renders questions of the new type in the UI
export class SurveyQuestionColorPicker extends SurveyQuestionElementBase {
  constructor(props) {
    super(props);
    this.state = { value: this.question.value };
  }
  get question() {
    return this.questionBase;
  }
  get value() {
    return this.question.value;
  }
  get disableAlpha() {
    return this.question.disableAlpha;
  }
  get type() {
    return this.question.colorPickerType;
  }
  handleColorChange = (data) => {
    this.question.value = data.hex;
  };
  // Support the read-only and design modes
  get style() {
    return this.question.getPropertyValue("readOnly") ||
      this.question.isDesignMode ? { pointerEvents: "none" } : undefined;
  }

  renderColor(type) {
    switch (type) {
      case "Slider": {
        return (<SliderPicker color={this.value} onChange={this.handleColorChange} />);
      }
      case "Sketch": {
        return (<SketchPicker color={this.value} disableAlpha={this.disableAlpha} onChange={this.handleColorChange} />);
      }
      case "Compact": {
        return (<CompactPicker color={this.value} onChange={this.handleColorChange} />);
      }
      default:
        return <div>Unknown type</div>;
    }
  }

  renderElement() {
    return <div style={this.style}>{this.renderColor(this.type)}</div>;
  }
}

// Register `SurveyQuestionColorPicker` as a class that renders `color-picker` questions 
ReactQuestionFactory.Instance.registerQuestion(CUSTOM_TYPE, (props) => {
  return React.createElement(SurveyQuestionColorPicker, props);
});
```

### `src/SurveyComponent.jsx`

```js
import React from "react";
import { Model } from "survey-core";
import { Survey } from "survey-react-ui";
import "survey-core/survey-core.min.css";
import "./index.css";
import { json } from "./json";
import { ColorComponent } from "./ColorComponent";

function SurveyComponent() {
    const survey = new Model(json);
    survey.onComplete.add((sender, options) => {
        console.log(JSON.stringify(sender.data, null, 3));
    });
    survey.data = {
        "slider-color": "#fa28ff",
        "sketch-color": "#7cd279",
        "compact-color": "#f18d36"
    };
    return (<Survey model={survey} />);
}

export default SurveyComponent;
```

### `src/index.css`

```css
.vc-sketch-presets {
    white-space: normal;
}
```

### `src/index.js`

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

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

### `src/json.js`

```js
export const json = {
  "elements": [
    {
      "type": "color-picker",
      "name": "slider-color",
      "title": "Color picker type = Slider"
    },
    {
      "type": "color-picker",
      "name": "sketch-color",
      "title": "Color picker type = Sketch",
      "colorPickerType": "Sketch"
    },
    {
      "type": "color-picker",
      "name": "compact-color",
      "title": "Color picker type = Compact",
      "colorPickerType": "Compact"
    }
  ]
};
```

### `package.json`

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

## Other Frameworks

- [Angular](https://surveyjs.io/form-library/examples/add-custom-question-type-to-form-builder/angular.md)
- [Vue 3](https://surveyjs.io/form-library/examples/add-custom-question-type-to-form-builder/vue3js.md)
