Files
formbricks-formbricks/components/editorjs/tools/TextQuestion.tsx
Matthias Nannt aa648f9b2d Feature/add question types (#9)
* add new question types: email, website, phone, number & multiple choice
2022-07-29 07:21:32 +09:00

127 lines
4.4 KiB
TypeScript

import { API, BlockTool, BlockToolData, ToolConfig } from "@editorjs/editorjs";
import ReactDOM from "react-dom";
//styles imports in angular.json
interface TextQuestionData extends BlockToolData {
label: string;
placeholder: string;
required: boolean;
}
export default class TextQuestion implements BlockTool {
settings: { name: string; icon: string }[];
api: API;
data: any;
wrapper: undefined | HTMLElement;
static get toolbox(): { icon: string; title?: string } {
return {
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-align-justify"><line x1="21" y1="10" x2="3" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="21" y1="18" x2="3" y2="18"></line></svg>`,
title: "Text Question",
};
}
constructor({
data,
}: {
api: API;
config?: ToolConfig;
data?: TextQuestionData;
}) {
this.wrapper = undefined;
this.settings = [
{
name: "required",
icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 512" class="w-3 h-3"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M471.99 334.43L336.06 256l135.93-78.43c7.66-4.42 10.28-14.2 5.86-21.86l-32.02-55.43c-4.42-7.65-14.21-10.28-21.87-5.86l-135.93 78.43V16c0-8.84-7.17-16-16.01-16h-64.04c-8.84 0-16.01 7.16-16.01 16v156.86L56.04 94.43c-7.66-4.42-17.45-1.79-21.87 5.86L2.15 155.71c-4.42 7.65-1.8 17.44 5.86 21.86L143.94 256 8.01 334.43c-7.66 4.42-10.28 14.21-5.86 21.86l32.02 55.43c4.42 7.65 14.21 10.27 21.87 5.86l135.93-78.43V496c0 8.84 7.17 16 16.01 16h64.04c8.84 0 16.01-7.16 16.01-16V339.14l135.93 78.43c7.66 4.42 17.45 1.8 21.87-5.86l32.02-55.43c4.42-7.65 1.8-17.43-5.86-21.85z"/></svg>`,
},
];
this.data = data;
this.data = {
label: data.label || "",
placeholder: data.placeholder || "",
required: data.required !== undefined ? data.required : true,
};
}
save(block: HTMLDivElement) {
return {
...this.data,
label: (
block.firstElementChild.firstElementChild
.firstElementChild as HTMLInputElement
).value,
placeholder: (
block.firstElementChild.lastElementChild as HTMLInputElement
).value,
};
}
renderSettings(): HTMLElement {
const wrapper = document.createElement("div");
this.settings.forEach((tune) => {
let button = document.createElement("div");
button.classList.add("cdx-settings-button");
button.classList.toggle(
"cdx-settings-button--active",
this.data[tune.name]
);
button.innerHTML = tune.icon;
wrapper.appendChild(button);
button.addEventListener("click", () => {
this._toggleTune(tune.name);
button.classList.toggle("cdx-settings-button--active");
});
});
return wrapper;
}
/**
* @private
* Click on the Settings Button
* @param {string} tune — tune name from this.settings
*/
_toggleTune(tune) {
this.wrapper.classList.toggle(tune.name, !!this.data[tune.name]);
if (tune === "required") {
this.data.required = !this.data.required;
this.wrapper.childNodes[0].childNodes[0].childNodes[1].textContent = this
.data.required
? "*"
: "";
}
}
render(): HTMLElement {
this.wrapper = document.createElement("div");
const toolView = (
<div className="pb-5">
<div className="relative font-bold leading-7 text-gray-800 text-md sm:truncate">
<input
type="text"
id="label"
defaultValue={this.data.label}
className="w-full p-0 border-0 border-transparent ring-0 focus:ring-0 placeholder:text-gray-300"
placeholder="Your Question"
/>
<div className="absolute inset-y-0 right-0 flex items-center pr-3 text-red-500 pointer-events-none">
*
</div>
</div>
<input
type="text"
className="block w-full max-w-sm mt-1 text-sm text-gray-400 border-gray-300 rounded-md shadow-sm placeholder:text-gray-300"
placeholder="optional placeholder"
defaultValue={this.data.placeholder}
/>
</div>
);
ReactDOM.render(toolView, this.wrapper);
return this.wrapper;
}
}