mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-04 10:30:00 -06:00
refactor: NumberQuestion
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { API, BlockTool, BlockToolData, ToolConfig } from "@editorjs/editorjs";
|
||||
import ReactDOM from "react-dom";
|
||||
import NumberQuestionComponent from "./NumberQuestionComponent";
|
||||
|
||||
//styles imports in angular.json
|
||||
interface NumberQuestionData extends BlockToolData {
|
||||
export interface NumberQuestionData extends BlockToolData {
|
||||
label: string;
|
||||
help: string;
|
||||
placeholder: string;
|
||||
@@ -12,8 +12,9 @@ interface NumberQuestionData extends BlockToolData {
|
||||
export default class NumberQuestion implements BlockTool {
|
||||
settings: { name: string; icon: string }[];
|
||||
api: API;
|
||||
data: any;
|
||||
wrapper: undefined | HTMLElement;
|
||||
data: NumberQuestionData;
|
||||
nodes: { holder: HTMLElement };
|
||||
config: ToolConfig;
|
||||
|
||||
static get toolbox(): { icon: string; title?: string } {
|
||||
return {
|
||||
@@ -24,30 +25,37 @@ export default class NumberQuestion implements BlockTool {
|
||||
};
|
||||
}
|
||||
|
||||
constructor({ data }: { api: API; config?: ToolConfig; data?: NumberQuestionData }) {
|
||||
this.wrapper = undefined;
|
||||
constructor({ api, config, data }: { api: API; config?: ToolConfig; data?: NumberQuestionData }) {
|
||||
this.api = api;
|
||||
this.config = config;
|
||||
|
||||
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 = {
|
||||
label: data.label || "",
|
||||
help: data.help || "",
|
||||
placeholder: data.placeholder || "",
|
||||
required: data.required !== undefined ? data.required : true,
|
||||
required: data.required || false,
|
||||
};
|
||||
|
||||
this.nodes = {
|
||||
holder: null,
|
||||
};
|
||||
}
|
||||
|
||||
save(block: HTMLDivElement) {
|
||||
return {
|
||||
...this.data,
|
||||
label: (block.firstElementChild.firstElementChild.firstElementChild as HTMLInputElement).value,
|
||||
placeholder: (block.firstElementChild.childNodes[1] as HTMLInputElement).value,
|
||||
help: (block.firstElementChild.lastElementChild as HTMLInputElement).value,
|
||||
};
|
||||
}
|
||||
// save(block: HTMLDivElement) {
|
||||
// return {
|
||||
// ...this.data,
|
||||
// label: (block.firstElementChild.firstElementChild.firstElementChild as HTMLInputElement).value,
|
||||
// placeholder: (block.firstElementChild.childNodes[1] as HTMLInputElement).value,
|
||||
// help: (block.firstElementChild.lastElementChild as HTMLInputElement).value,
|
||||
// };
|
||||
// }
|
||||
|
||||
renderSettings(): HTMLElement {
|
||||
const wrapper = document.createElement("div");
|
||||
@@ -69,52 +77,34 @@ export default class NumberQuestion implements BlockTool {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
const rootNode = document.createElement("div");
|
||||
|
||||
this.nodes.holder = rootNode;
|
||||
|
||||
const onDataChange = (newData: NumberQuestionData) => {
|
||||
this.data = {
|
||||
...newData,
|
||||
};
|
||||
};
|
||||
|
||||
ReactDOM.render(<NumberQuestionComponent onDataChange={onDataChange} data={this.data} />, rootNode);
|
||||
|
||||
return this.nodes.holder;
|
||||
}
|
||||
|
||||
save() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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]);
|
||||
|
||||
_toggleTune(tune: string) {
|
||||
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="text-md relative font-bold leading-7 text-gray-800 sm:truncate">
|
||||
<input
|
||||
type="text"
|
||||
id="label"
|
||||
defaultValue={this.data.label}
|
||||
className="w-full border-0 border-transparent p-0 ring-0 placeholder:text-gray-300 focus:ring-0"
|
||||
placeholder="Your Question"
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3 text-red-500">
|
||||
*
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
className="mt-1 block w-full max-w-sm rounded-md border-gray-300 text-sm text-gray-400 shadow-sm placeholder:text-gray-300"
|
||||
placeholder="optional placeholder"
|
||||
defaultValue={this.data.placeholder}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
id="help-text"
|
||||
defaultValue={this.data.help}
|
||||
className="mt-2 block w-full max-w-sm border-0 border-transparent p-0 text-sm font-light text-gray-500 ring-0 placeholder:text-gray-300 focus:ring-0"
|
||||
placeholder="optional help text"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
ReactDOM.render(toolView, this.wrapper);
|
||||
return this.wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import { useState } from "react";
|
||||
import type { NumberQuestionData } from "./NumberQuestion";
|
||||
|
||||
const DEFAULT_INITIAL_DATA = (): NumberQuestionData => {
|
||||
return {
|
||||
label: "",
|
||||
placeholder: "",
|
||||
help: "",
|
||||
required: false,
|
||||
};
|
||||
};
|
||||
|
||||
type Props = {
|
||||
data: NumberQuestionData;
|
||||
onDataChange: (newData: NumberQuestionData) => void;
|
||||
};
|
||||
|
||||
const NumberQuestionComponent = (props: Props) => {
|
||||
const [data, setData] = useState(props.data ? props.data : DEFAULT_INITIAL_DATA);
|
||||
|
||||
const updateData = (newData: NumberQuestionData) => {
|
||||
setData(newData);
|
||||
|
||||
if (props.onDataChange) {
|
||||
props.onDataChange(newData);
|
||||
}
|
||||
};
|
||||
|
||||
const onInputChange = (fieldName: string) => {
|
||||
return (e: React.FormEvent<HTMLInputElement>) => {
|
||||
const newData = {
|
||||
...data,
|
||||
};
|
||||
|
||||
newData[fieldName] = e.currentTarget.value;
|
||||
|
||||
updateData(newData);
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="pb-5">
|
||||
<div className="text-md relative font-bold leading-7 text-gray-800 sm:truncate">
|
||||
<input
|
||||
type="text"
|
||||
id="label"
|
||||
defaultValue={data.label}
|
||||
className="w-full border-0 border-transparent p-0 ring-0 placeholder:text-gray-300 focus:ring-0"
|
||||
placeholder="Your Question"
|
||||
onChange={onInputChange("label")}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3 text-red-500">
|
||||
*
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
className="mt-1 block w-full max-w-sm rounded-md border-gray-300 text-sm text-gray-400 shadow-sm placeholder:text-gray-300"
|
||||
placeholder="optional placeholder"
|
||||
defaultValue={data.placeholder}
|
||||
onChange={onInputChange("placeholder")}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
id="help-text"
|
||||
defaultValue={data.help}
|
||||
className="mt-2 block w-full max-w-sm border-0 border-transparent p-0 text-sm font-light text-gray-500 ring-0 placeholder:text-gray-300 focus:ring-0"
|
||||
placeholder="optional help text"
|
||||
onChange={onInputChange("help")}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NumberQuestionComponent;
|
||||
502
pnpm-lock.yaml
generated
502
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user