|
@@ -148,15 +150,15 @@ export const MatrixQuestion = ({
|
{question.columns.map((column, columnIndex) => (
+ onClick={() => {
handleSelect(
getLocalizedValue(column, languageCode),
getLocalizedValue(row, languageCode)
- )
- }
+ );
+ }}
onKeyDown={(e) => {
if (e.key === " ") {
e.preventDefault();
@@ -174,7 +176,7 @@ export const MatrixQuestion = ({
type="radio"
tabIndex={-1}
required={question.required}
- id={`${row}-${column}`}
+ id={`row${rowIndex.toString()}-column${columnIndex.toString()}`}
name={getLocalizedValue(row, languageCode)}
value={getLocalizedValue(column, languageCode)}
checked={
@@ -199,7 +201,6 @@ export const MatrixQuestion = ({
{}}
tabIndex={isCurrent ? 0 : -1}
/>
{!isFirstQuestion && (
@@ -212,4 +213,4 @@ export const MatrixQuestion = ({
);
-};
+}
diff --git a/packages/surveys/src/components/questions/MultipleChoiceMultiQuestion.tsx b/packages/surveys/src/components/questions/multiple-choice-multi-question.tsx
similarity index 87%
rename from packages/surveys/src/components/questions/MultipleChoiceMultiQuestion.tsx
rename to packages/surveys/src/components/questions/multiple-choice-multi-question.tsx
index ab817ff1ae..bb26e1e984 100644
--- a/packages/surveys/src/components/questions/MultipleChoiceMultiQuestion.tsx
+++ b/packages/surveys/src/components/questions/multiple-choice-multi-question.tsx
@@ -1,14 +1,14 @@
-import { BackButton } from "@/components/buttons/BackButton";
-import { SubmitButton } from "@/components/buttons/SubmitButton";
-import { Headline } from "@/components/general/Headline";
-import { QuestionMedia } from "@/components/general/QuestionMedia";
-import { Subheader } from "@/components/general/Subheader";
-import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
+import { BackButton } from "@/components/buttons/back-button";
+import { SubmitButton } from "@/components/buttons/submit-button";
+import { Headline } from "@/components/general/headline";
+import { QuestionMedia } from "@/components/general/question-media";
+import { Subheader } from "@/components/general/subheader";
+import { ScrollableContainer } from "@/components/wrappers/scrollable-container";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn, getShuffledChoicesIds } from "@/lib/utils";
import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
-import { TResponseData, TResponseTtc } from "@formbricks/types/responses";
+import { type TResponseData, type TResponseTtc } from "@formbricks/types/responses";
import type { TSurveyMultipleChoiceQuestion, TSurveyQuestionId } from "@formbricks/types/surveys/types";
interface MultipleChoiceMultiProps {
@@ -26,7 +26,7 @@ interface MultipleChoiceMultiProps {
currentQuestionId: TSurveyQuestionId;
}
-export const MultipleChoiceMultiQuestion = ({
+export function MultipleChoiceMultiQuestion({
question,
value,
onChange,
@@ -39,7 +39,7 @@ export const MultipleChoiceMultiQuestion = ({
setTtc,
autoFocusEnabled,
currentQuestionId,
-}: MultipleChoiceMultiProps) => {
+}: MultipleChoiceMultiProps) {
const [startTime, setStartTime] = useState(performance.now());
const isMediaAvailable = question.imageUrl || question.videoUrl;
useTtc(question.id, ttc, setTtc, startTime, setStartTime, question.id === currentQuestionId);
@@ -47,8 +47,9 @@ export const MultipleChoiceMultiQuestion = ({
const shuffledChoicesIds = useMemo(() => {
if (question.shuffleOption) {
return getShuffledChoicesIds(question.choices, question.shuffleOption);
- } else return question.choices.map((choice) => choice.id);
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ }
+ return question.choices.map((choice) => choice.id);
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to recompute this when the shuffleOption changes
}, [question.shuffleOption, question.choices.length, question.choices[question.choices.length - 1].id]);
const getChoicesWithoutOtherLabels = useCallback(
@@ -63,9 +64,9 @@ export const MultipleChoiceMultiQuestion = ({
useEffect(() => {
setOtherSelected(
- !!value &&
- ((Array.isArray(value) ? value : [value]) as string[]).some((item) => {
- return getChoicesWithoutOtherLabels().includes(item) === false;
+ Boolean(value) &&
+ (Array.isArray(value) ? value : [value]).some((item) => {
+ return !getChoicesWithoutOtherLabels().includes(item);
})
);
setOtherValue(
@@ -81,8 +82,8 @@ export const MultipleChoiceMultiQuestion = ({
}
if (question.shuffleOption === "none" || question.shuffleOption === undefined) return question.choices;
return shuffledChoicesIds.map((choiceId) => {
- const choice = question.choices.find((choice) => {
- return choice.id === choiceId;
+ const choice = question.choices.find((currentChoice) => {
+ return currentChoice.id === choiceId;
});
return choice;
});
@@ -115,19 +116,21 @@ export const MultipleChoiceMultiQuestion = ({
const newValue = value.filter((v) => {
return questionChoiceLabels.includes(v);
});
- return onChange({ [question.id]: [...newValue, item] });
- } else {
- return onChange({ [question.id]: [...value, item] });
+ onChange({ [question.id]: [...newValue, item] });
+ return;
}
+ onChange({ [question.id]: [...value, item] });
+ return;
}
- return onChange({ [question.id]: [item] }); // if not array, make it an array
+ onChange({ [question.id]: [item] }); // if not array, make it an array
};
const removeItem = (item: string) => {
if (Array.isArray(value)) {
- return onChange({ [question.id]: value.filter((i) => i !== item) });
+ onChange({ [question.id]: value.filter((i) => i !== item) });
+ return;
}
- return onChange({ [question.id]: [] }); // if not array, make it an array
+ onChange({ [question.id]: [] }); // if not array, make it an array
};
return (
@@ -135,7 +138,7 @@ export const MultipleChoiceMultiQuestion = ({
key={question.id}
onSubmit={(e) => {
e.preventDefault();
- const newValue = (value as string[])?.filter((item) => {
+ const newValue = value.filter((item) => {
return getChoicesWithoutOtherLabels().includes(item) || item === otherValue;
}); // filter out all those values which are either in getChoicesWithoutOtherLabels() (i.e. selected by checkbox) or the latest entered otherValue
onChange({ [question.id]: newValue });
@@ -146,7 +149,9 @@ export const MultipleChoiceMultiQuestion = ({
className="fb-w-full">
- {isMediaAvailable && }
+ {isMediaAvailable ? (
+
+ ) : null}
{
- if ((e.target as HTMLInputElement)?.checked) {
+ if ((e.target as HTMLInputElement).checked) {
addItem(getLocalizedValue(choice.label, languageCode));
} else {
removeItem(getLocalizedValue(choice.label, languageCode));
@@ -214,7 +219,7 @@ export const MultipleChoiceMultiQuestion = ({
);
})}
- {otherOption && (
+ {otherOption ? (
- )}
+ ) : null}
@@ -302,4 +307,4 @@ export const MultipleChoiceMultiQuestion = ({
);
-};
+}
diff --git a/packages/surveys/src/components/questions/MultipleChoiceSingleQuestion.tsx b/packages/surveys/src/components/questions/multiple-choice-single-question.tsx
similarity index 88%
rename from packages/surveys/src/components/questions/MultipleChoiceSingleQuestion.tsx
rename to packages/surveys/src/components/questions/multiple-choice-single-question.tsx
index 51864d16fb..03099c3f7c 100644
--- a/packages/surveys/src/components/questions/MultipleChoiceSingleQuestion.tsx
+++ b/packages/surveys/src/components/questions/multiple-choice-single-question.tsx
@@ -1,14 +1,14 @@
-import { BackButton } from "@/components/buttons/BackButton";
-import { SubmitButton } from "@/components/buttons/SubmitButton";
-import { Headline } from "@/components/general/Headline";
-import { QuestionMedia } from "@/components/general/QuestionMedia";
-import { Subheader } from "@/components/general/Subheader";
-import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
+import { BackButton } from "@/components/buttons/back-button";
+import { SubmitButton } from "@/components/buttons/submit-button";
+import { Headline } from "@/components/general/headline";
+import { QuestionMedia } from "@/components/general/question-media";
+import { Subheader } from "@/components/general/subheader";
+import { ScrollableContainer } from "@/components/wrappers/scrollable-container";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn, getShuffledChoicesIds } from "@/lib/utils";
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
-import { TResponseData, TResponseTtc } from "@formbricks/types/responses";
+import { type TResponseData, type TResponseTtc } from "@formbricks/types/responses";
import type { TSurveyMultipleChoiceQuestion, TSurveyQuestionId } from "@formbricks/types/surveys/types";
interface MultipleChoiceSingleProps {
@@ -26,7 +26,7 @@ interface MultipleChoiceSingleProps {
currentQuestionId: TSurveyQuestionId;
}
-export const MultipleChoiceSingleQuestion = ({
+export function MultipleChoiceSingleQuestion({
question,
value,
onChange,
@@ -39,7 +39,7 @@ export const MultipleChoiceSingleQuestion = ({
setTtc,
autoFocusEnabled,
currentQuestionId,
-}: MultipleChoiceSingleProps) => {
+}: MultipleChoiceSingleProps) {
const [startTime, setStartTime] = useState(performance.now());
const [otherSelected, setOtherSelected] = useState(false);
const otherSpecify = useRef(null);
@@ -49,20 +49,21 @@ export const MultipleChoiceSingleQuestion = ({
const shuffledChoicesIds = useMemo(() => {
if (question.shuffleOption) {
return getShuffledChoicesIds(question.choices, question.shuffleOption);
- } else return question.choices.map((choice) => choice.id);
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ }
+ return question.choices.map((choice) => choice.id);
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- only want to run this effect when question.choices changes
}, [question.shuffleOption, question.choices.length, question.choices[question.choices.length - 1].id]);
useTtc(question.id, ttc, setTtc, startTime, setStartTime, question.id === currentQuestionId);
const questionChoices = useMemo(() => {
- if (!question.choices) {
+ if (!question.choices.length) {
return [];
}
if (question.shuffleOption === "none" || question.shuffleOption === undefined) return question.choices;
return shuffledChoicesIds.map((choiceId) => {
- const choice = question.choices.find((choice) => {
- return choice.id === choiceId;
+ const choice = question.choices.find((selectedChoice) => {
+ return selectedChoice.id === choiceId;
});
return choice;
});
@@ -109,7 +110,9 @@ export const MultipleChoiceSingleQuestion = ({
className="fb-w-full">
- {isMediaAvailable && }
+ {isMediaAvailable ? (
+
+ ) : null}
{getLocalizedValue(choice.label, languageCode)}
@@ -173,7 +176,7 @@ export const MultipleChoiceSingleQuestion = ({
);
})}
- {otherOption && (
+ {otherOption ? (
- {otherSelected && (
+ {otherSelected ? (
0
+ ? getLocalizedValue(question.otherOptionPlaceholder, languageCode)
+ : "Please specify"
}
required={question.required}
aria-labelledby={`${otherOption.id}-label`}
/>
- )}
+ ) : null}
- )}
+ ) : null}
@@ -259,4 +264,4 @@ export const MultipleChoiceSingleQuestion = ({
);
-};
+}
diff --git a/packages/surveys/src/components/questions/NPSQuestion.tsx b/packages/surveys/src/components/questions/nps-question.tsx
similarity index 82%
rename from packages/surveys/src/components/questions/NPSQuestion.tsx
rename to packages/surveys/src/components/questions/nps-question.tsx
index 2d388e09cd..bf0db74b74 100644
--- a/packages/surveys/src/components/questions/NPSQuestion.tsx
+++ b/packages/surveys/src/components/questions/nps-question.tsx
@@ -1,14 +1,14 @@
-import { BackButton } from "@/components/buttons/BackButton";
-import { SubmitButton } from "@/components/buttons/SubmitButton";
-import { Headline } from "@/components/general/Headline";
-import { QuestionMedia } from "@/components/general/QuestionMedia";
-import { Subheader } from "@/components/general/Subheader";
-import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
+import { BackButton } from "@/components/buttons/back-button";
+import { SubmitButton } from "@/components/buttons/submit-button";
+import { Headline } from "@/components/general/headline";
+import { QuestionMedia } from "@/components/general/question-media";
+import { Subheader } from "@/components/general/subheader";
+import { ScrollableContainer } from "@/components/wrappers/scrollable-container";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn } from "@/lib/utils";
import { useState } from "preact/hooks";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
-import { TResponseData, TResponseTtc } from "@formbricks/types/responses";
+import { type TResponseData, type TResponseTtc } from "@formbricks/types/responses";
import type { TSurveyNPSQuestion, TSurveyQuestionId } from "@formbricks/types/surveys/types";
interface NPSQuestionProps {
@@ -26,7 +26,7 @@ interface NPSQuestionProps {
currentQuestionId: TSurveyQuestionId;
}
-export const NPSQuestion = ({
+export function NPSQuestion({
question,
value,
onChange,
@@ -38,7 +38,7 @@ export const NPSQuestion = ({
ttc,
setTtc,
currentQuestionId,
-}: NPSQuestionProps) => {
+}: NPSQuestionProps) {
const [startTime, setStartTime] = useState(performance.now());
const [hoveredNumber, setHoveredNumber] = useState(-1);
const isMediaAvailable = question.imageUrl || question.videoUrl;
@@ -60,7 +60,9 @@ export const NPSQuestion = ({
};
const getNPSOptionColor = (idx: number) => {
- return idx > 8 ? "fb-bg-emerald-100" : idx > 6 ? "fb-bg-orange-100" : "fb-bg-rose-100";
+ if (idx > 8) return "fb-bg-emerald-100";
+ if (idx > 6) return "fb-bg-orange-100";
+ return "fb-bg-rose-100";
};
return (
@@ -74,7 +76,9 @@ export const NPSQuestion = ({
}}>
- {isMediaAvailable && }
+ {isMediaAvailable ? (
+
+ ) : null}
setHoveredNumber(number)}
- onMouseLeave={() => setHoveredNumber(-1)}
+ onMouseOver={() => {
+ setHoveredNumber(number);
+ }}
+ onMouseLeave={() => {
+ setHoveredNumber(-1);
+ }}
onKeyDown={(e) => {
// Accessibility: if spacebar was pressed pass this down to the input
if (e.key === " ") {
@@ -113,11 +121,11 @@ export const NPSQuestion = ({
: "fb-h fb-leading-10",
hoveredNumber === number ? "fb-bg-accent-bg" : ""
)}>
- {question.isColorCodingEnabled && (
+ {question.isColorCodingEnabled ? (
- )}
+ ) : null}
handleClick(number)}
+ onClick={() => {
+ handleClick(number);
+ }}
required={question.required}
tabIndex={-1}
/>
@@ -164,4 +174,4 @@ export const NPSQuestion = ({
);
-};
+}
diff --git a/packages/surveys/src/components/questions/OpenTextQuestion.tsx b/packages/surveys/src/components/questions/open-text-question.tsx
similarity index 82%
rename from packages/surveys/src/components/questions/OpenTextQuestion.tsx
rename to packages/surveys/src/components/questions/open-text-question.tsx
index 2f8eb37519..4e811440d1 100644
--- a/packages/surveys/src/components/questions/OpenTextQuestion.tsx
+++ b/packages/surveys/src/components/questions/open-text-question.tsx
@@ -1,15 +1,14 @@
-import { BackButton } from "@/components/buttons/BackButton";
-import { SubmitButton } from "@/components/buttons/SubmitButton";
-import { Headline } from "@/components/general/Headline";
-import { QuestionMedia } from "@/components/general/QuestionMedia";
-import { Subheader } from "@/components/general/Subheader";
-import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
+import { BackButton } from "@/components/buttons/back-button";
+import { SubmitButton } from "@/components/buttons/submit-button";
+import { Headline } from "@/components/general/headline";
+import { QuestionMedia } from "@/components/general/question-media";
+import { Subheader } from "@/components/general/subheader";
+import { ScrollableContainer } from "@/components/wrappers/scrollable-container";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
-import { RefObject } from "preact";
+import { type RefObject } from "preact";
import { useEffect, useRef, useState } from "preact/hooks";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
-import { TResponseData } from "@formbricks/types/responses";
-import { TResponseTtc } from "@formbricks/types/responses";
+import { type TResponseData, type TResponseTtc } from "@formbricks/types/responses";
import type { TSurveyOpenTextQuestion, TSurveyQuestionId } from "@formbricks/types/surveys/types";
interface OpenTextQuestionProps {
@@ -28,7 +27,7 @@ interface OpenTextQuestionProps {
currentQuestionId: TSurveyQuestionId;
}
-export const OpenTextQuestion = ({
+export function OpenTextQuestion({
question,
value,
onChange,
@@ -41,7 +40,7 @@ export const OpenTextQuestion = ({
setTtc,
autoFocusEnabled,
currentQuestionId,
-}: OpenTextQuestionProps) => {
+}: OpenTextQuestionProps) {
const [startTime, setStartTime] = useState(performance.now());
const isMediaAvailable = question.imageUrl || question.videoUrl;
const isCurrent = question.id === currentQuestionId;
@@ -60,7 +59,7 @@ export const OpenTextQuestion = ({
};
const handleInputResize = (event: { target: any }) => {
- let maxHeight = 160; // 8 lines
+ const maxHeight = 160; // 8 lines
const textarea = event.target;
textarea.style.height = "auto";
const newHeight = Math.min(textarea.scrollHeight, maxHeight);
@@ -80,7 +79,9 @@ export const OpenTextQuestion = ({
className="fb-w-full">
- {isMediaAvailable && }
+ {isMediaAvailable ? (
+
+ ) : null}
}
- autoFocus={isCurrent && autoFocusEnabled}
+ autoFocus={isCurrent ? autoFocusEnabled : undefined}
tabIndex={isCurrent ? 0 : -1}
name={question.id}
id={question.id}
placeholder={getLocalizedValue(question.placeholder, languageCode)}
dir="auto"
- step={"any"}
+ step="any"
required={question.required}
- value={value ? (value as string) : ""}
+ value={value ? value : ""}
type={question.inputType}
- onInput={(e) => handleInputChange(e.currentTarget.value)}
+ onInput={(e) => {
+ handleInputChange(e.currentTarget.value);
+ }}
className="fb-border-border placeholder:fb-text-placeholder fb-text-subheading focus:fb-border-brand fb-bg-input-bg fb-rounded-custom fb-block fb-w-full fb-border fb-p-2 fb-shadow-sm focus:fb-outline-none focus:fb-ring-0 sm:fb-text-sm"
pattern={question.inputType === "phone" ? "[0-9+ ]+" : ".*"}
title={question.inputType === "phone" ? "Enter a valid phone number" : undefined}
@@ -113,7 +116,7 @@ export const OpenTextQuestion = ({
);
-};
+}
diff --git a/packages/surveys/src/components/questions/PictureSelectionQuestion.tsx b/packages/surveys/src/components/questions/picture-selection-question.tsx
similarity index 85%
rename from packages/surveys/src/components/questions/PictureSelectionQuestion.tsx
rename to packages/surveys/src/components/questions/picture-selection-question.tsx
index 67a6afd8b0..3403a59b43 100644
--- a/packages/surveys/src/components/questions/PictureSelectionQuestion.tsx
+++ b/packages/surveys/src/components/questions/picture-selection-question.tsx
@@ -1,14 +1,14 @@
-import { BackButton } from "@/components/buttons/BackButton";
-import { SubmitButton } from "@/components/buttons/SubmitButton";
-import { Headline } from "@/components/general/Headline";
-import { QuestionMedia } from "@/components/general/QuestionMedia";
-import { Subheader } from "@/components/general/Subheader";
-import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
+import { BackButton } from "@/components/buttons/back-button";
+import { SubmitButton } from "@/components/buttons/submit-button";
+import { Headline } from "@/components/general/headline";
+import { QuestionMedia } from "@/components/general/question-media";
+import { Subheader } from "@/components/general/subheader";
+import { ScrollableContainer } from "@/components/wrappers/scrollable-container";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn } from "@/lib/utils";
import { useEffect, useState } from "preact/hooks";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
-import { TResponseData, TResponseTtc } from "@formbricks/types/responses";
+import { type TResponseData, type TResponseTtc } from "@formbricks/types/responses";
import type { TSurveyPictureSelectionQuestion, TSurveyQuestionId } from "@formbricks/types/surveys/types";
interface PictureSelectionProps {
@@ -26,7 +26,7 @@ interface PictureSelectionProps {
currentQuestionId: TSurveyQuestionId;
}
-export const PictureSelectionQuestion = ({
+export function PictureSelectionQuestion({
question,
value,
onChange,
@@ -38,7 +38,7 @@ export const PictureSelectionQuestion = ({
ttc,
setTtc,
currentQuestionId,
-}: PictureSelectionProps) => {
+}: PictureSelectionProps) {
const [startTime, setStartTime] = useState(performance.now());
const isMediaAvailable = question.imageUrl || question.videoUrl;
const isCurrent = question.id === currentQuestionId;
@@ -53,7 +53,7 @@ export const PictureSelectionQuestion = ({
values = [item];
}
- return onChange({ [question.id]: values });
+ onChange({ [question.id]: values });
};
const removeItem = (item: string) => {
@@ -65,7 +65,7 @@ export const PictureSelectionQuestion = ({
values = [];
}
- return onChange({ [question.id]: values });
+ onChange({ [question.id]: values });
};
const handleChange = (id: string) => {
@@ -80,7 +80,7 @@ export const PictureSelectionQuestion = ({
if (!question.allowMulti && value.length > 1) {
onChange({ [question.id]: [] });
}
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to recompute when the allowMulti changes
}, [question.allowMulti]);
const questionChoices = question.choices;
@@ -97,7 +97,9 @@ export const PictureSelectionQuestion = ({
className="fb-w-full">
- {isMediaAvailable && }
+ {isMediaAvailable ? (
+
+ ) : null}
handleChange(choice.id)}
+ onClick={() => {
+ handleChange(choice.id);
+ }}
className={cn(
"fb-relative fb-w-full fb-cursor-pointer fb-overflow-hidden fb-border fb-rounded-custom focus:fb-outline-none fb-aspect-[4/3] fb-min-h-[7rem] fb-max-h-[50vh] focus:fb-border-brand focus:fb-border-4 group/image",
Array.isArray(value) && value.includes(choice.id)
@@ -143,7 +147,9 @@ export const PictureSelectionQuestion = ({
target="_blank"
title="Open in new tab"
rel="noreferrer"
- onClick={(e) => e.stopPropagation()}
+ onClick={(e) => {
+ e.stopPropagation();
+ }}
className="fb-absolute fb-bottom-2 fb-right-2 fb-flex fb-items-center fb-gap-2 fb-whitespace-nowrap fb-rounded-md fb-bg-slate-800 fb-bg-opacity-40 fb-p-1.5 fb-text-white fb-opacity-0 fb-backdrop-blur-lg fb-transition fb-duration-300 fb-ease-in-out hover:fb-bg-opacity-65 group-hover/image:fb-opacity-100">
);
-};
+}
diff --git a/packages/surveys/src/components/questions/RankingQuestion.tsx b/packages/surveys/src/components/questions/ranking-question.tsx
similarity index 87%
rename from packages/surveys/src/components/questions/RankingQuestion.tsx
rename to packages/surveys/src/components/questions/ranking-question.tsx
index 76e87fbf67..df7b2795ab 100644
--- a/packages/surveys/src/components/questions/RankingQuestion.tsx
+++ b/packages/surveys/src/components/questions/ranking-question.tsx
@@ -1,15 +1,15 @@
-import { BackButton } from "@/components/buttons/BackButton";
-import { SubmitButton } from "@/components/buttons/SubmitButton";
-import { Headline } from "@/components/general/Headline";
-import { QuestionMedia } from "@/components/general/QuestionMedia";
-import { Subheader } from "@/components/general/Subheader";
-import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
+import { BackButton } from "@/components/buttons/back-button";
+import { SubmitButton } from "@/components/buttons/submit-button";
+import { Headline } from "@/components/general/headline";
+import { QuestionMedia } from "@/components/general/question-media";
+import { Subheader } from "@/components/general/subheader";
+import { ScrollableContainer } from "@/components/wrappers/scrollable-container";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn, getShuffledChoicesIds } from "@/lib/utils";
import { useAutoAnimate } from "@formkit/auto-animate/react";
import { useCallback, useMemo, useState } from "preact/hooks";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
-import { TResponseData, TResponseTtc } from "@formbricks/types/responses";
+import { type TResponseData, type TResponseTtc } from "@formbricks/types/responses";
import type {
TSurveyQuestionChoice,
TSurveyQuestionId,
@@ -31,7 +31,7 @@ interface RankingQuestionProps {
currentQuestionId: TSurveyQuestionId;
}
-export const RankingQuestion = ({
+export function RankingQuestion({
question,
value,
onChange,
@@ -44,13 +44,14 @@ export const RankingQuestion = ({
setTtc,
autoFocusEnabled,
currentQuestionId,
-}: RankingQuestionProps) => {
+}: RankingQuestionProps) {
const [startTime, setStartTime] = useState(performance.now());
const isCurrent = question.id === currentQuestionId;
const shuffledChoicesIds = useMemo(() => {
if (question.shuffleOption) {
return getShuffledChoicesIds(question.choices, question.shuffleOption);
- } else return question.choices.map((choice) => choice.id);
+ }
+ return question.choices.map((choice) => choice.id);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [question.shuffleOption, question.choices.length]);
@@ -61,7 +62,7 @@ export const RankingQuestion = ({
useTtc(question.id, ttc, setTtc, startTime, setStartTime, isCurrent);
- const [localValue, setLocalValue] = useState(value || []);
+ const [localValue, setLocalValue] = useState(value ?? []);
const sortedItems = useMemo(() => {
return localValue
@@ -72,9 +73,8 @@ export const RankingQuestion = ({
const unsortedItems = useMemo(() => {
if (question.shuffleOption === "all" && sortedItems.length === 0) {
return shuffledChoicesIds.map((id) => question.choices.find((c) => c.id === id));
- } else {
- return question.choices.filter((c) => !localValue.includes(c.id));
}
+ return question.choices.filter((c) => !localValue.includes(c.id));
}, [question.choices, question.shuffleOption, localValue, sortedItems, shuffledChoicesIds]);
const handleItemClick = useCallback(
@@ -144,7 +144,9 @@ export const RankingQuestion = ({
);
-};
+}
diff --git a/packages/surveys/src/components/questions/RatingQuestion.tsx b/packages/surveys/src/components/questions/rating-question.tsx
similarity index 77%
rename from packages/surveys/src/components/questions/RatingQuestion.tsx
rename to packages/surveys/src/components/questions/rating-question.tsx
index fa4e16aa99..fd2a23c451 100644
--- a/packages/surveys/src/components/questions/RatingQuestion.tsx
+++ b/packages/surveys/src/components/questions/rating-question.tsx
@@ -1,14 +1,14 @@
-import { BackButton } from "@/components/buttons/BackButton";
-import { SubmitButton } from "@/components/buttons/SubmitButton";
-import { Headline } from "@/components/general/Headline";
-import { QuestionMedia } from "@/components/general/QuestionMedia";
-import { ScrollableContainer } from "@/components/wrappers/ScrollableContainer";
+import { BackButton } from "@/components/buttons/back-button";
+import { SubmitButton } from "@/components/buttons/submit-button";
+import { Headline } from "@/components/general/headline";
+import { QuestionMedia } from "@/components/general/question-media";
+import { ScrollableContainer } from "@/components/wrappers/scrollable-container";
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
import { cn } from "@/lib/utils";
import { useEffect, useState } from "preact/hooks";
import type { JSX } from "react";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
-import { TResponseData, TResponseTtc } from "@formbricks/types/responses";
+import { type TResponseData, type TResponseTtc } from "@formbricks/types/responses";
import type { TSurveyQuestionId, TSurveyRatingQuestion } from "@formbricks/types/surveys/types";
import {
ConfusedFace,
@@ -21,8 +21,8 @@ import {
SmilingFaceWithSmilingEyes,
TiredFace,
WearyFace,
-} from "../general/Smileys";
-import { Subheader } from "../general/Subheader";
+} from "../general/smileys";
+import { Subheader } from "../general/subheader";
interface RatingQuestionProps {
question: TSurveyRatingQuestion;
@@ -39,7 +39,7 @@ interface RatingQuestionProps {
currentQuestionId: TSurveyQuestionId;
}
-export const RatingQuestion = ({
+export function RatingQuestion({
question,
value,
onChange,
@@ -51,7 +51,7 @@ export const RatingQuestion = ({
ttc,
setTtc,
currentQuestionId,
-}: RatingQuestionProps) => {
+}: RatingQuestionProps) {
const [hoveredNumber, setHoveredNumber] = useState(0);
const [startTime, setStartTime] = useState(performance.now());
const isMediaAvailable = question.imageUrl || question.videoUrl;
@@ -72,18 +72,22 @@ export const RatingQuestion = ({
}, 250);
};
- const HiddenRadioInput = ({ number, id }: { number: number; id?: string }) => (
- handleSelect(number)}
- required={question.required}
- checked={value === number}
- />
- );
+ function HiddenRadioInput({ number, id }: { number: number; id?: string }) {
+ return (
+ {
+ handleSelect(number);
+ }}
+ required={question.required}
+ checked={value === number}
+ />
+ );
+ }
useEffect(() => {
setHoveredNumber(0);
@@ -98,11 +102,10 @@ export const RatingQuestion = ({
if (range - idx < 1) return "fb-bg-emerald-100";
if (range - idx < 2) return "fb-bg-orange-100";
return "fb-bg-rose-100";
- } else {
- if (range - idx < 2) return "fb-bg-emerald-100";
- if (range - idx < 3) return "fb-bg-orange-100";
- return "fb-bg-rose-100";
}
+ if (range - idx < 2) return "fb-bg-emerald-100";
+ if (range - idx < 3) return "fb-bg-orange-100";
+ return "fb-bg-rose-100";
};
return (
@@ -117,7 +120,9 @@ export const RatingQuestion = ({
className="fb-w-full">
- {isMediaAvailable && }
+ {isMediaAvailable ? (
+
+ ) : null}
i + 1).map((number, i, a) => (
setHoveredNumber(number)}
- onMouseLeave={() => setHoveredNumber(0)}
+ onMouseOver={() => {
+ setHoveredNumber(number);
+ }}
+ onMouseLeave={() => {
+ setHoveredNumber(0);
+ }}
className="fb-bg-survey-bg fb-flex-1 fb-text-center fb-text-sm">
{question.scale === "number" ? (
@@ -178,14 +187,18 @@ export const RatingQuestion = ({
}
}}
className={cn(
- number <= hoveredNumber || number <= (value as number)
+ number <= hoveredNumber || number <= value!
? "fb-text-amber-400"
: "fb-text-[#8696AC]",
hoveredNumber === number ? "fb-text-amber-400" : "",
"fb-relative fb-flex fb-max-h-16 fb-min-h-9 fb-cursor-pointer fb-justify-center focus:fb-outline-none"
)}
- onFocus={() => setHoveredNumber(number)}
- onBlur={() => setHoveredNumber(0)}>
+ onFocus={() => {
+ setHoveredNumber(number);
+ }}
+ onBlur={() => {
+ setHoveredNumber(0);
+ }}>
|