---
title: Implement a Descriptive Text Element
product: Survey Creator
description: Descriptive Text is an element that enables you to create engaging introductions, disclaimers, and add descriptive textual content anywhere within your survey. View our free demo for JavaScript to learn more.
framework: React
source: https://surveyjs.io/survey-creator/examples/custom-descriptive-text-element/reactjs
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Implement a Descriptive Text Element (React)

A Descriptive Text survey element displays a long piece of text. You can use this element to add introductions, disclaimers, or other explanatory texts to your survey. This demo shows how to implement a custom Descriptive Text question type for Survey Creator in Angular and React applications.

A Descriptive Text question type contains the following two custom properties. All other properties are inherited from the `QuestionNonValue` class.

- `caption`: `String`\
A message displayed by the question type.

- `textSize`: `"small"` | `"medium"` | `"large"`\
The size of the text. Text sizes correspond to HTML heading levels as follows:

    | Text size  | Heading |
    | ---------- | ------- |
    | `"large"`  | `<h2>`  |
    | `"medium"` | `<h3>`  |
    | `"small"`  | `<h4>`  |

This demo uses comments in code to guide you through the implementation. If you need more detailed explanations, please refer to help topics about third-party component integration listed below. They cover the same steps because the integration process is very similar to the process of custom question type implementation.

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

## 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 surveyJSON = {
  "title": "Customer Feedback Survey",
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "descriptivetext",
          "name": "heading",
          "textSize": "large",
          "caption": "This survey is designed to gather feedback from our users. Your responses will help us improve our products and services. Thank you for participating!"
        },
        {
          "type": "radiogroup",
          "name": "satisfaction-level",
          "title": "How satisfied are you with our products?",
          "choices": [
            "Very satisfied",
            "Satisfied",
            "Neutral",
            "Dissatisfied",
            "Very dissatisfied"
          ]
        }
      ]
    }
  ]
}
```

### `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 { ElementFactory, QuestionNonValue, Serializer, settings, surveyLocalization } from "survey-core";
import { SurveyQuestionElementBase, ReactQuestionFactory, SurveyElementBase } from "survey-react-ui";
import { surveyJSON } from "./survey_json";
import { getLocaleStrings } from "survey-creator-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 } from "survey-creator-core";

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

const CUSTOM_QUESTION_TYPE = "descriptivetext";

// A model that extends the Question class and inherits all its properties and methods
class DescriptiveTextModel extends QuestionNonValue {
    constructor() {
        super();
        // Create a `LocalizableString` object for the `caption` property
        this.createLocString({
            name: "caption",
            supportsMarkdown: true,
            translationKey: "descriptiveTextCaption"
        });
    }
    getType() {
        return CUSTOM_QUESTION_TYPE;
    }
    get textSize() {
        return this.getPropertyValue("textSize");
    }
    set textSize(val) {
        this.setPropertyValue("textSize", val);
    }
    // Returns caption text that corresponds to the current locale
    get caption() {
        return this.getLocalizableStringText("caption");
    }
    // Sets caption text for the current locale
    set caption(val) {
        this.setLocalizableStringText("caption", val);
    }
    // Returns a `LocalizationString` object for the `caption` property
    get locCaption() {
        return this.getLocalizableString("caption");
    }
}

// Register `DescriptiveTextModel` as a constructor for the "descriptivetext" question type
ElementFactory.Instance.registerElement(CUSTOM_QUESTION_TYPE, (name) => {
    return new DescriptiveTextModel(name);
});

// Configure JSON serialization and deserialization rules for the custom properties
Serializer.addClass(
    CUSTOM_QUESTION_TYPE,
    [
        {
            name: "caption:text",
            category: "general",
            visibleIndex: 2,
            serializationProperty: "locCaption"
        },
        {
            name: "textSize",
            category: "general",
            visibleIndex: 3,
            default: "medium",
            choices: [
                { value: "small", text: "Small" },
                { value: "medium", text: "Medium" },
                { value: "large", text: "Large" }
            ]
        }
    ],
    function () {
        return new DescriptiveTextModel("");
    },
    "question"
);

// Change default values for inherited properties
Serializer.getProperty(CUSTOM_QUESTION_TYPE, "showNumber").defaultValue = false;
Serializer.getProperty(CUSTOM_QUESTION_TYPE, "titleLocation").defaultValue = "hidden";

// A class that renders a Descriptive Text question
class SurveyQuestionDescriptiveText extends SurveyQuestionElementBase {
    get question() {
        return this.questionBase;
    }
    renderElement() {
        const textSize = this.question.textSize || "medium";
        const locStr = SurveyElementBase.renderLocString(this.question.locCaption);
        return React.createElement(
            "span",
            {
                className: `descriptiveText ${textSize}`,
                tabIndex: 0,
                style: { overflow: "hidden", display: "block" }
            },
            locStr
        );
    }
}

// Register `SurveyQuestionDescriptiveText` as a class that renders the Descriptive Text question type
ReactQuestionFactory.Instance.registerQuestion(
    CUSTOM_QUESTION_TYPE,
    (props) => {
        return React.createElement(SurveyQuestionDescriptiveText, props);
    }
);

// Specify captions to display on the design surface and in Property Grid
const locale = getLocaleStrings("en");
locale.qt[CUSTOM_QUESTION_TYPE] = "Descriptive Text";
locale.pe.caption = "Caption text";
locale.pe.textSize = "Text size";

// Use the Text icon for the Descriptive Text question type
settings.customIcons["icon-descriptivetext"] = "icon-text";

// Specify the default value for the Descriptive Text caption
const enStrings = surveyLocalization.getLocaleStrings("en");
enStrings["descriptiveTextCaption"] = "Default Header Text";
function SurveyCreatorRenderComponent() {
    const creator = new SurveyCreator();
    const propertyStopList = [
        "title",
        "description",
        "isRequired",
        "readOnly",
        "requiredErrorText",
        "validators",
        "useDisplayValuesInDynamicTexts",
        "valueName",
        "clearIfInvisible",
        "defaultValue",
        "correctAnswer",
        "enableIf",
        "defaultValueExpression",
        "requiredIf",
        "descriptionLocation",
        "width",
        "minWidth",
        "maxWidth"
    ];
    // Hide inherited properties that do not apply to the Descriptive Text element
    creator.onPropertyShowing.add((_, options) => {
        if (options.element.getType() === "descriptivetext") {
            options.show = propertyStopList.indexOf(options.property.name) === -1;
        }
    });
    creator.JSON = surveyJSON;
    
    return (<SurveyCreatorComponent creator={creator} />);
}

export default SurveyCreatorRenderComponent;
```

### `src/index.css`

```css
.descriptiveText.small {
    font-size: 0.875rem;
    font-weight: normal;
}

.descriptiveText.medium {
    font-size: 1rem;
    font-weight: bold;
}

.descriptiveText.large {
    font-size: 1.25rem;
    font-weight: bold;
}
```

### `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/custom-descriptive-text-element/angular.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/custom-descriptive-text-element/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/custom-descriptive-text-element/jquery.md)
- [Vanilla JS](https://surveyjs.io/survey-creator/examples/custom-descriptive-text-element/vanillajs.md)
