---
title: Integrate a Third-Party Color Picker Component
product: Survey Creator
description: Integrate third-party components into Survey Creator, for example, a Color Picker. Customize the Toolbox and Property Grid of your self-hosted form builder as your needs require. View our free demo for JavaScript to learn more.
framework: Vue 3
source: https://surveyjs.io/survey-creator/examples/custom-colorpicker-property-editor/vue3js
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Integrate a Third-Party Color Picker Component (Vue 3)

This example shows how to integrate a third-party Color Picker component into your survey and use this component as a property editor in the Property Grid. Refer to the following documentation articles for a step-by-step tutorial:

- [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="app" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0;"></div>
```

### `src/ColorComponent.vue`

```html
<template>
  <slider-picker
    v-if="props.question.isSlider"
    :modelValue="props.question.value"
    @update:modelValue="updateValue"
  ></slider-picker>
  <sketch-picker
    v-if="props.question.isSketch"
    :modelValue="props.question.value"
    @update:modelValue="updateValue"
  ></sketch-picker>
  <compact-picker
    v-if="props.question.isColorCompact"
    :modelValue="props.question.value"
    @update:modelValue="updateValue"
  ></compact-picker>
</template>
<script  lang="ts">
import { ElementFactory, Question, Serializer, SvgRegistry } from "survey-core";
import { PropertyGridEditorCollection, getLocaleStrings } from "survey-creator-core";

// 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 isSlider() {
    return this.colorPickerType === "Slider";
  }
  get isSketch() {
    return this.colorPickerType === "Sketch";
  }
  get isColorCompact() {
    return this.colorPickerType === "Compact";
  }

  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"],
    category: "general",
    visibleIndex: 2 // After the Name and Title
  }, {
    name: "disableAlpha:boolean",
    dependsOn: "colorPickerType",
    visibleIf: function (obj) {
      return obj.colorPickerType === "Sketch";
    },
    category: "general",
    visibleIndex: 3 // After the Name, Title, and Color Picker type
  }],
  function () {
    return new QuestionColorPickerModel("");
  },
  "question"
);

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

// Specify display names for the question type and its properties 
const locale = getLocaleStrings("en");
locale.qt[CUSTOM_TYPE] = "Color Picker";
locale.pe.colorPickerType = "Color picker type";
locale.pe.disableAlpha = "Disable alpha channel";

// Register an SVG icon for the question type
SvgRegistry.registerIcon(
  CUSTOM_TYPE,
  '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M24 21.4201C23.9387 22.1566 23.5894 22.8394 23.0278 23.3202C22.4662 23.8011 21.7376 24.0413 21 23.9888C20.2624 24.0413 19.5338 23.8011 18.9722 23.3202C18.4106 22.8394 18.0613 22.1566 18 21.4201C18 18.8513 21 16.2826 21 14.9932C21 16.2826 24 18.8513 24 21.4201ZM22 12.9942L11 1.99951L8.71 4.2884L10.12 5.70771L11 4.82814L18.17 11.9946L5.64 15.8028L2.83 12.9942L7.71 8.11653L9.29 9.70576C9.38296 9.79944 9.49356 9.8738 9.61542 9.92455C9.73728 9.97529 9.86799 10.0014 10 10.0014C10.132 10.0014 10.2627 9.97529 10.3846 9.92455C10.5064 9.8738 10.617 9.79944 10.71 9.70576C10.8037 9.61284 10.8781 9.5023 10.9289 9.3805C10.9797 9.2587 11.0058 9.12805 11.0058 8.99611C11.0058 8.86416 10.9797 8.73352 10.9289 8.61172C10.8781 8.48992 10.8037 8.37937 10.71 8.28645L3.71 1.28986C3.5217 1.10165 3.2663 0.995911 3 0.995911C2.7337 0.995911 2.4783 1.10165 2.29 1.28986C2.1017 1.47807 1.99591 1.73334 1.99591 1.99951C1.99591 2.26569 2.1017 2.52096 2.29 2.70917L6.29 6.70722L0 12.9942L10 22.9893L18 14.9932L22 12.9942Z" /></svg>'
);

// Register the `color-picker` as an editor for properties of the `color` type in the Survey Creator's Property Grid
PropertyGridEditorCollection.register({
  fit: function (prop) {
    return prop.type === "color";
  },
  getJSON: function () {
    return {
      type: CUSTOM_TYPE,
      colorPickerType: "Compact"
    };
  }
});

export default {
  inheritAttrs: false,
}
</script>
<script setup lang="ts">
const props = defineProps<{ question: QuestionColorPickerModel }>();

function updateValue(val) {
  let hex = val.hex;
  if (!!hex) {
    props.question.value = hex.toLowerCase();
  }
}
</script>
```

### `src/survey_json.js`

```js
export const surveyJSON = {
  pages: [
    {
      name: "page1",
      elements: [
        {
          type: "color-picker",
          name: "question1",
          title: "Pick a color",
          colorPickerType: "Sketch"
        }
      ]
    }
  ]
};
  
```

### `src/App.vue`

```html
<template>
    <SurveyCreatorComponent :model="creator" />
</template>
<script setup lang="ts">
    import { SurveyCreatorModel } from "survey-creator-core";
    import { SurveyCreatorComponent } from "survey-creator-vue";
    import { surveyJSON } from "./survey_json";
    import { Serializer } from "survey-core";
    import "survey-core/survey.i18n";
    import "survey-creator-core/survey-creator-core.i18n";
    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

    function applyBackground(color) {
      setTimeout(() => {
        const surveyEl = document.getElementsByClassName("sd-root-modern")[0];
        if (!!surveyEl) {
          surveyEl.style.setProperty("--background", color);
        }
      }, 50);
    };
    
    function handleActiveTabChange(sender, options) {
      if (options.tabName === "preview" || options.tabName === "designer") {
        applyBackground(sender.survey.backgroundColor);
      }
    };
    const creator = new SurveyCreatorModel();
    
    Serializer.addProperty("survey", {
      name: "backgroundColor",
      displayName: "Background color",
      type: "color",
      category: "general",
      visibleIndex: 3,
      onSetValue: (survey, value) => {
        survey.setPropertyValue("backgroundColor", value);
        applyBackground(value);
      }
    });
    
    creator.onActiveTabChanged.add(handleActiveTabChange);
    creator.JSON = surveyJSON;
    
</script>
```

### `src/index.css`

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

### `src/main.ts`

```ts
import { createApp } from "vue";
import App from "./App.vue";
import ColorComponent from "./ColorComponent.vue";
import { Sketch, Compact, Slider } from "@lk77/vue3-color";

const app = createApp(App);
app.component("survey-color-picker", ColorComponent);
app.component("slider-picker", Slider);
app.component("sketch-picker", Sketch);
app.component("compact-picker", Compact);
app.mount("#app");
```

### `src/shims-vue.d.ts`

```ts
/* eslint-disable */
declare module "*.vue" {
    import type { DefineComponent } from "vue"
    const component: DefineComponent<{}, {}, any>
    export default component
}
```

### `.eslintrc.js`

```js
module.exports = {
    root: true,
    env: {
        node: true
    },
    extends: [
        "plugin:vue/vue3-essential",
        "eslint:recommended",
        "@vue/typescript/recommended",
        "@vue/prettier",
        "@vue/prettier/@typescript-eslint"
    ],
    parserOptions: {
        ecmaVersion: 2020
    },
    rules: {
        "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
        "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off"
    },
    overrides: [
        {
            files: [
                "**/__tests__/*.{j,t}s?(x)",
                "**/tests/unit/**/*.spec.{j,t}s?(x)"
            ],
            env: {
                jest: true
            }
        }
    ]
};
```

### `babel.config.js`

```js
module.exports = {
  presets: ["@vue/cli-plugin-babel/preset"]
};
```

### `package.json`

```json
{
  "name": "surveyjs-library-vue3",
  "version": "0.1.0",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "tslib": "2.6.1",
    "vue": "^3.4.1",
    "@lk77/vue3-color": "latest",
    "survey-core": "latest",
    "survey-vue3-ui": "latest",
    "survey-creator-core": "latest",
    "survey-creator-vue": "latest",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^2.33.0",
    "@typescript-eslint/parser": "^2.33.0",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-pwa": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-typescript": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/eslint-config-prettier": "^6.0.0",
    "@vue/eslint-config-typescript": "^5.0.2",
    "@vue/test-utils": "^2.0.0-0",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.1.3",
    "eslint-plugin-vue": "^7.0.0-0",
    "node-sass": "^4.12.0",
    "prettier": "^1.19.1",
    "sass-loader": "^8.0.2",
    "typescript": "~3.9.3"
  }
}
```

### `tsconfig.json`

```json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "jest"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/survey-creator/examples/custom-colorpicker-property-editor/angular.md)
- [React](https://surveyjs.io/survey-creator/examples/custom-colorpicker-property-editor/reactjs.md)
