mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-12 18:59:38 -06:00
fix: error message in rating Question (#6909)
Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com> Co-authored-by: Matti Nannt <matti@formbricks.com>
This commit is contained in:
@@ -294,28 +294,28 @@ export const BlockCard = ({
|
||||
open={!isBlockCollapsed}
|
||||
onOpenChange={() => setIsBlockCollapsed(!isBlockCollapsed)}
|
||||
className={cn(isBlockCollapsed ? "h-full" : "")}>
|
||||
<Collapsible.CollapsibleTrigger
|
||||
asChild
|
||||
className="block h-full w-full cursor-pointer hover:bg-slate-100">
|
||||
<div className="flex h-full items-center justify-between px-4 py-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<div>
|
||||
<h4 className="text-sm font-medium text-slate-700">{block.name}</h4>
|
||||
<p className="text-xs text-slate-500">
|
||||
{blockElementsCount} {blockElementsCountText}
|
||||
</p>
|
||||
<Collapsible.CollapsibleTrigger asChild>
|
||||
<div className="block h-full w-full cursor-pointer hover:bg-slate-100">
|
||||
<div className="flex h-full items-center justify-between px-4 py-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<div>
|
||||
<h4 className="text-sm font-medium text-slate-700">{block.name}</h4>
|
||||
<p className="text-xs text-slate-500">
|
||||
{blockElementsCount} {blockElementsCountText}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<BlockMenu
|
||||
isFirstBlock={blockIdx === 0}
|
||||
isLastBlock={blockIdx === totalBlocks - 1}
|
||||
isOnlyBlock={totalBlocks === 1}
|
||||
onDuplicate={() => duplicateBlock(block.id)}
|
||||
onDelete={() => deleteBlock(block.id)}
|
||||
onMoveUp={() => moveBlock(block.id, "up")}
|
||||
onMoveDown={() => moveBlock(block.id, "down")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<BlockMenu
|
||||
isFirstBlock={blockIdx === 0}
|
||||
isLastBlock={blockIdx === totalBlocks - 1}
|
||||
isOnlyBlock={totalBlocks === 1}
|
||||
onDuplicate={() => duplicateBlock(block.id)}
|
||||
onDelete={() => deleteBlock(block.id)}
|
||||
onMoveUp={() => moveBlock(block.id, "up")}
|
||||
onMoveDown={() => moveBlock(block.id, "down")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Collapsible.CollapsibleTrigger>
|
||||
|
||||
@@ -62,7 +62,7 @@ test.describe("Survey Create & Submit Response without logic", async () => {
|
||||
await expect(page.getByPlaceholder(surveys.createAndSubmit.openTextQuestion.placeholder)).toBeVisible();
|
||||
await page
|
||||
.getByPlaceholder(surveys.createAndSubmit.openTextQuestion.placeholder)
|
||||
.fill("This is my Open Text answer");
|
||||
.fill("Open Text answer");
|
||||
await page.locator("#questionCard-0").getByRole("button", { name: "Next" }).click();
|
||||
|
||||
// Single Select Question
|
||||
@@ -116,7 +116,7 @@ test.describe("Survey Create & Submit Response without logic", async () => {
|
||||
expect(await page.getByRole("group", { name: "Choices" }).locator("label").count()).toBe(5);
|
||||
await expect(page.locator("#questionCard-3").getByRole("button", { name: "Next" })).toBeVisible();
|
||||
await expect(page.locator("#questionCard-3").getByRole("button", { name: "Back" })).toBeVisible();
|
||||
await page.locator("path").nth(3).click();
|
||||
await page.getByRole("radio", { name: "Rate 3 out of" }).check();
|
||||
await page.locator("#questionCard-3").getByRole("button", { name: "Next" }).click();
|
||||
|
||||
// NPS Question
|
||||
@@ -212,11 +212,9 @@ test.describe("Survey Create & Submit Response without logic", async () => {
|
||||
// Address Question
|
||||
await expect(page.getByText(surveys.createAndSubmit.address.question)).toBeVisible();
|
||||
await expect(page.getByLabel(surveys.createAndSubmit.address.placeholder.addressLine1)).toBeVisible();
|
||||
await page
|
||||
.getByLabel(surveys.createAndSubmit.address.placeholder.addressLine1)
|
||||
.fill("This is my Address");
|
||||
await page.getByLabel(surveys.createAndSubmit.address.placeholder.addressLine1).fill("Address");
|
||||
await expect(page.getByLabel(surveys.createAndSubmit.address.placeholder.city)).toBeVisible();
|
||||
await page.getByLabel(surveys.createAndSubmit.address.placeholder.city).fill("This is my city");
|
||||
await page.getByLabel(surveys.createAndSubmit.address.placeholder.city).fill("city");
|
||||
await expect(page.getByLabel(surveys.createAndSubmit.address.placeholder.zip)).toBeVisible();
|
||||
await page.getByLabel(surveys.createAndSubmit.address.placeholder.zip).fill("12345");
|
||||
await page.locator("#questionCard-10").getByRole("button", { name: "Next" }).click();
|
||||
@@ -785,7 +783,7 @@ test.describe("Testing Survey with advanced logic", async () => {
|
||||
).toBeVisible();
|
||||
await page
|
||||
.getByPlaceholder(surveys.createWithLogicAndSubmit.openTextQuestion.placeholder)
|
||||
.fill("This is my Open Text answer");
|
||||
.fill("Open Text answer");
|
||||
await page.locator("#questionCard-0").getByRole("button", { name: "Next" }).click();
|
||||
|
||||
// Single Select Question
|
||||
@@ -858,10 +856,9 @@ test.describe("Testing Survey with advanced logic", async () => {
|
||||
await expect(
|
||||
page.locator("#questionCard-4").getByText(surveys.createWithLogicAndSubmit.ratingQuestion.highLabel)
|
||||
).toBeVisible();
|
||||
expect(await page.getByRole("group", { name: "Choices" }).locator("label").count()).toBe(5);
|
||||
await expect(page.locator("#questionCard-4").getByRole("button", { name: "Next" })).toBeVisible();
|
||||
await expect(page.locator("#questionCard-4").getByRole("button", { name: "Back" })).toBeVisible();
|
||||
await page.getByRole("group", { name: "Choices" }).locator("path").nth(3).click();
|
||||
await page.getByRole("radio", { name: "Rate 4 out of" }).check();
|
||||
await page.locator("#questionCard-4").getByRole("button", { name: "Next" }).click();
|
||||
|
||||
// NPS Question
|
||||
@@ -972,11 +969,9 @@ test.describe("Testing Survey with advanced logic", async () => {
|
||||
).toBeVisible();
|
||||
await page
|
||||
.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.addressLine1)
|
||||
.fill("This is my Address");
|
||||
.fill("Address");
|
||||
await expect(page.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.city)).toBeVisible();
|
||||
await page
|
||||
.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.city)
|
||||
.fill("This is my city");
|
||||
await page.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.city).fill("city");
|
||||
await expect(page.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.zip)).toBeVisible();
|
||||
await page.getByLabel(surveys.createWithLogicAndSubmit.address.placeholder.zip).fill("12345");
|
||||
await page.locator("#questionCard-13").getByRole("button", { name: "Finish" }).click();
|
||||
@@ -997,13 +992,26 @@ test.describe("Testing Survey with advanced logic", async () => {
|
||||
const updatedUrl = currentUrl.replace("summary?share=true", "responses");
|
||||
|
||||
await page.goto(updatedUrl);
|
||||
await page.waitForSelector("#response-table");
|
||||
await page.waitForSelector("table#response-table");
|
||||
|
||||
await expect(page.getByRole("cell", { name: "score" })).toBeVisible();
|
||||
|
||||
await page.waitForLoadState("networkidle");
|
||||
await page.waitForTimeout(5000);
|
||||
await expect(page.getByRole("cell", { name: "32", exact: true })).toBeVisible();
|
||||
|
||||
await page.pause();
|
||||
|
||||
// Look for any cell containing "32" or a score-related value
|
||||
const scoreCell = page.getByRole("cell").filter({ hasText: /^32/ });
|
||||
await expect(scoreCell).toBeVisible({
|
||||
timeout: 15000,
|
||||
});
|
||||
|
||||
// Look for the secret message in the table
|
||||
const secretCell = page.getByRole("cell").filter({ hasText: /This is a secret message for e2e tests/ });
|
||||
await expect(secretCell).toBeVisible({
|
||||
timeout: 15000,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -656,7 +656,7 @@ export const createSurveyWithLogic = async (page: Page, params: CreateSurveyWith
|
||||
await page.locator("#action-2-operator").click();
|
||||
await page.getByRole("option", { name: "Assign =" }).click();
|
||||
await page.locator("#action-2-value-input").click();
|
||||
await page.locator("#action-2-value-input").fill("1");
|
||||
await page.locator("#action-2-value-input").fill("This ");
|
||||
// Close Block 1 settings before moving to Block 2
|
||||
await page
|
||||
.locator("div")
|
||||
|
||||
@@ -106,51 +106,51 @@ export const surveys = {
|
||||
createAndSubmit: {
|
||||
welcomeCard: {
|
||||
headline: "Welcome to My Testing Survey Welcome Card!",
|
||||
description: "This is the description of my Welcome Card!",
|
||||
description: "the description of my Welcome Card!",
|
||||
},
|
||||
openTextQuestion: {
|
||||
question: "This is my Open Text Question",
|
||||
description: "This is my Open Text Description",
|
||||
placeholder: "This is my Placeholder",
|
||||
question: "Open Text Question",
|
||||
description: "Open Text Description",
|
||||
placeholder: "Placeholder",
|
||||
},
|
||||
singleSelectQuestion: {
|
||||
question: "This is my Single Select Question",
|
||||
description: "This is my Single Select Description",
|
||||
question: "Single Select Question",
|
||||
description: "Single Select Description",
|
||||
options: ["Option 1", "Option 2"],
|
||||
},
|
||||
multiSelectQuestion: {
|
||||
question: "This is my Multi Select Question",
|
||||
description: "This is Multi Select Description",
|
||||
question: "Multi Select Question",
|
||||
description: "Multi Select Description",
|
||||
options: ["Option 1", "Option 2", "Option 3"],
|
||||
},
|
||||
ratingQuestion: {
|
||||
question: "This is my Rating Question",
|
||||
description: "This is Rating Description",
|
||||
question: "Rating Question",
|
||||
description: "Rating Description",
|
||||
lowLabel: "My Lower Label",
|
||||
highLabel: "My Upper Label",
|
||||
},
|
||||
npsQuestion: {
|
||||
question: "This is my NPS Question",
|
||||
question: "NPS Question",
|
||||
lowLabel: "My Lower Label",
|
||||
highLabel: "My Upper Label",
|
||||
},
|
||||
ctaQuestion: {
|
||||
question: "This is my CTA Question",
|
||||
question: "CTA Question",
|
||||
buttonLabel: "My Button Label",
|
||||
},
|
||||
consentQuestion: {
|
||||
question: "This is my Consent Question",
|
||||
question: "Consent Question",
|
||||
checkboxLabel: "My Checkbox Label",
|
||||
},
|
||||
pictureSelectQuestion: {
|
||||
question: "This is my Picture Select Question",
|
||||
description: "This is Picture Select Description",
|
||||
question: "Picture Select Question",
|
||||
description: "Picture Select Description",
|
||||
},
|
||||
dateQuestion: {
|
||||
question: "This is my Date Question",
|
||||
question: "Date Question",
|
||||
},
|
||||
fileUploadQuestion: {
|
||||
question: "This is my File Upload Question",
|
||||
question: "File Upload Question",
|
||||
},
|
||||
matrix: {
|
||||
question: "How much do you love these flowers?",
|
||||
@@ -178,57 +178,57 @@ export const surveys = {
|
||||
createWithLogicAndSubmit: {
|
||||
welcomeCard: {
|
||||
headline: "Welcome to My Testing Survey Welcome Card!",
|
||||
description: "This is the description of my Welcome Card!",
|
||||
description: "the description of my Welcome Card!",
|
||||
},
|
||||
openTextQuestion: {
|
||||
question: "This is my Open Text Question",
|
||||
description: "This is my Open Text Description",
|
||||
placeholder: "This is my Placeholder",
|
||||
question: "Open Text Question",
|
||||
description: "Open Text Description",
|
||||
placeholder: "Placeholder",
|
||||
},
|
||||
singleSelectQuestion: {
|
||||
question: "This is my Single Select Question",
|
||||
description: "This is my Single Select Description",
|
||||
question: "Single Select Question",
|
||||
description: "Single Select Description",
|
||||
options: ["Option 1", "Option 2"],
|
||||
},
|
||||
multiSelectQuestion: {
|
||||
question: "This is my Multi Select Question",
|
||||
description: "This is Multi Select Description",
|
||||
question: "Multi Select Question",
|
||||
description: "Multi Select Description",
|
||||
options: ["Option 1", "Option 2", "Option 3"],
|
||||
},
|
||||
ratingQuestion: {
|
||||
question: "This is my Rating Question",
|
||||
description: "This is Rating Description",
|
||||
question: "Rating Question",
|
||||
description: "Rating Description",
|
||||
lowLabel: "My Lower Label",
|
||||
highLabel: "My Upper Label",
|
||||
},
|
||||
npsQuestion: {
|
||||
question: "This is my NPS Question",
|
||||
question: "NPS Question",
|
||||
lowLabel: "My Lower Label",
|
||||
highLabel: "My Upper Label",
|
||||
},
|
||||
ctaQuestion: {
|
||||
question: "This is my CTA Question",
|
||||
question: "CTA Question",
|
||||
buttonLabel: "My Button Label",
|
||||
},
|
||||
consentQuestion: {
|
||||
question: "This is my Consent Question",
|
||||
question: "Consent Question",
|
||||
checkboxLabel: "My Checkbox Label",
|
||||
},
|
||||
pictureSelectQuestion: {
|
||||
question: "This is my Picture Select Question",
|
||||
description: "This is Picture Select Description",
|
||||
question: "Picture Select Question",
|
||||
description: "Picture Select Description",
|
||||
},
|
||||
fileUploadQuestion: {
|
||||
question: "This is my File Upload Question",
|
||||
question: "File Upload Question",
|
||||
},
|
||||
date: {
|
||||
question: "This is my Date Question",
|
||||
question: "Date Question",
|
||||
},
|
||||
cal: {
|
||||
question: "This is my cal Question",
|
||||
question: "cal Question",
|
||||
},
|
||||
matrix: {
|
||||
question: "This is my Matrix Question",
|
||||
question: "Matrix Question",
|
||||
description: "0: Not at all, 3: Love it",
|
||||
rows: ["Roses", "Trees", "Ocean"],
|
||||
columns: ["0", "1", "2", "3"],
|
||||
@@ -242,7 +242,7 @@ export const surveys = {
|
||||
},
|
||||
},
|
||||
ranking: {
|
||||
question: "This is my Ranking Question",
|
||||
question: "Ranking Question",
|
||||
choices: ["Work", "Money", "Travel", "Family", "Friends"],
|
||||
},
|
||||
endingCard: {
|
||||
@@ -342,12 +342,12 @@ export const actions = {
|
||||
noCode: {
|
||||
click: {
|
||||
name: "Create Click Action (CSS Selector)",
|
||||
description: "This is my Create Action (click, CSS Selector)",
|
||||
description: "Create Action (click, CSS Selector)",
|
||||
selector: ".my-custom-class",
|
||||
},
|
||||
pageView: {
|
||||
name: "Create Page view Action (specific Page URL)",
|
||||
description: "This is my Create Action (Page view)",
|
||||
description: "Create Action (Page view)",
|
||||
matcher: {
|
||||
label: "Contains",
|
||||
value: "custom-url",
|
||||
@@ -355,16 +355,16 @@ export const actions = {
|
||||
},
|
||||
exitIntent: {
|
||||
name: "Create Exit Intent Action",
|
||||
description: "This is my Create Action (Exit Intent)",
|
||||
description: "Create Action (Exit Intent)",
|
||||
},
|
||||
fiftyPercentScroll: {
|
||||
name: "Create 50% Scroll Action",
|
||||
description: "This is my Create Action (50% Scroll)",
|
||||
description: "Create Action (50% Scroll)",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
name: "Create Action (Code)",
|
||||
description: "This is my Create Action (Code)",
|
||||
description: "Create Action (Code)",
|
||||
key: "Create Action (Code)",
|
||||
},
|
||||
},
|
||||
@@ -372,12 +372,12 @@ export const actions = {
|
||||
noCode: {
|
||||
click: {
|
||||
name: "Edit Click Action (CSS Selector)",
|
||||
description: "This is my Edit Action (click, CSS Selector)",
|
||||
description: "Edit Action (click, CSS Selector)",
|
||||
selector: ".my-custom-class-edited",
|
||||
},
|
||||
pageView: {
|
||||
name: "Edit Page view Action (specific Page URL)",
|
||||
description: "This is my Edit Action (Page view)",
|
||||
description: "Edit Action (Page view)",
|
||||
matcher: {
|
||||
label: "Starts with",
|
||||
value: "custom-url0-edited",
|
||||
@@ -386,26 +386,26 @@ export const actions = {
|
||||
},
|
||||
exitIntent: {
|
||||
name: "Edit Exit Intent Action",
|
||||
description: "This is my Edit Action (Exit Intent)",
|
||||
description: "Edit Action (Exit Intent)",
|
||||
},
|
||||
fiftyPercentScroll: {
|
||||
name: "Edit 50% Scroll Action",
|
||||
description: "This is my Edit Action (50% Scroll)",
|
||||
description: "Edit Action (50% Scroll)",
|
||||
},
|
||||
},
|
||||
code: {
|
||||
description: "This is my Edit Action (Code)",
|
||||
description: "Edit Action (Code)",
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
noCode: {
|
||||
name: "Delete click Action (CSS Selector)",
|
||||
description: "This is my Delete Action (CSS Selector)",
|
||||
description: "Delete Action (CSS Selector)",
|
||||
selector: ".my-custom-class-deleted",
|
||||
},
|
||||
code: {
|
||||
name: "Delete Action (Code)",
|
||||
description: "This is my Delete Action (Code)",
|
||||
description: "Delete Action (Code)",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -54,23 +54,6 @@ export function RatingElement({
|
||||
setTtc(updatedTtcObj);
|
||||
};
|
||||
|
||||
function HiddenRadioInput({ number, id }: { number: number; id?: string }) {
|
||||
return (
|
||||
<input
|
||||
type="radio"
|
||||
id={id}
|
||||
name="rating"
|
||||
value={number}
|
||||
className="fb-invisible fb-absolute fb-left-0 fb-h-full fb-w-full fb-cursor-pointer fb-opacity-0"
|
||||
onClick={() => {
|
||||
handleSelect(number);
|
||||
}}
|
||||
required={element.required}
|
||||
checked={value === number}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setHoveredNumber(0);
|
||||
}, [element.id, setHoveredNumber]);
|
||||
@@ -96,14 +79,6 @@ export function RatingElement({
|
||||
setTtc(updatedTtcObj);
|
||||
};
|
||||
|
||||
const handleKeyDown = (number: number) => (e: KeyboardEvent) => {
|
||||
const isActivationKey = e.key === " " || e.key === "Enter";
|
||||
if (isActivationKey) {
|
||||
e.preventDefault();
|
||||
handleSelect(number);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseOver = (number: number) => () => {
|
||||
setHoveredNumber(number);
|
||||
};
|
||||
@@ -159,6 +134,17 @@ export function RatingElement({
|
||||
);
|
||||
};
|
||||
|
||||
const getRatingInputId = (number: number) => `${element.id}-${number}`;
|
||||
|
||||
const handleKeyDown = (number: number) => (e: KeyboardEvent) => {
|
||||
if (e.key === " ") {
|
||||
e.preventDefault();
|
||||
const inputId = getRatingInputId(number);
|
||||
document.getElementById(inputId)?.click();
|
||||
document.getElementById(inputId)?.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const renderNumberScale = (number: number, totalLength: number) => {
|
||||
return (
|
||||
<label
|
||||
@@ -170,7 +156,19 @@ export function RatingElement({
|
||||
className={`fb-absolute fb-left-0 fb-top-0 fb-h-[6px] fb-w-full ${getRatingNumberOptionColor(element.range, number)}`}
|
||||
/>
|
||||
)}
|
||||
<HiddenRadioInput number={number} id={number.toString()} />
|
||||
<input
|
||||
type="radio"
|
||||
id={getRatingInputId(number)}
|
||||
name="rating"
|
||||
value={number}
|
||||
className="fb-absolute fb-left-0 fb-h-full fb-w-full fb-cursor-pointer fb-opacity-0"
|
||||
onClick={() => {
|
||||
handleSelect(number);
|
||||
}}
|
||||
required={element.required}
|
||||
checked={value === number}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
{number}
|
||||
</label>
|
||||
);
|
||||
@@ -179,12 +177,25 @@ export function RatingElement({
|
||||
const renderStarScale = (number: number) => {
|
||||
return (
|
||||
<label
|
||||
aria-label={`Rate ${number} out of ${element.range}`}
|
||||
tabIndex={0} // NOSONAR - needed for keyboard navigation through options
|
||||
onKeyDown={handleKeyDown(number)}
|
||||
className={getStarLabelClassName(number)}
|
||||
onFocus={handleFocus(number)}
|
||||
onBlur={handleBlur}>
|
||||
<HiddenRadioInput number={number} id={number.toString()} />
|
||||
<input
|
||||
type="radio"
|
||||
id={getRatingInputId(number)}
|
||||
name="rating"
|
||||
value={number}
|
||||
className="fb-absolute fb-left-0 fb-h-full fb-w-full fb-cursor-pointer fb-opacity-0"
|
||||
onClick={() => {
|
||||
handleSelect(number);
|
||||
}}
|
||||
required={element.required}
|
||||
checked={value === number}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<div className="fb-h-full fb-w-full fb-max-w-[74px] fb-object-contain">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path
|
||||
@@ -200,12 +211,25 @@ export function RatingElement({
|
||||
const renderSmileyScale = (number: number, idx: number) => {
|
||||
return (
|
||||
<label
|
||||
aria-label={`Rate ${number} out of ${element.range}`}
|
||||
tabIndex={0} // NOSONAR - needed for keyboard navigation through options
|
||||
className={getSmileyLabelClassName(number)}
|
||||
onKeyDown={handleKeyDown(number)}
|
||||
onFocus={handleFocus(number)}
|
||||
onBlur={handleBlur}>
|
||||
<HiddenRadioInput number={number} id={number.toString()} />
|
||||
<input
|
||||
type="radio"
|
||||
id={getRatingInputId(number)}
|
||||
name="rating"
|
||||
value={number}
|
||||
className="fb-absolute fb-left-0 fb-h-full fb-w-full fb-cursor-pointer fb-opacity-0"
|
||||
onClick={() => {
|
||||
handleSelect(number);
|
||||
}}
|
||||
required={element.required}
|
||||
checked={value === number}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<div className="fb-h-full fb-w-full fb-max-w-[74px] fb-object-contain">
|
||||
<RatingSmiley
|
||||
active={value === number || hoveredNumber === number}
|
||||
@@ -253,7 +277,7 @@ export function RatingElement({
|
||||
renderRatingOption(number, i, a.length)
|
||||
)}
|
||||
</div>
|
||||
<div className="fb-text-subheading fb-mt-4 fb-flex fb-justify-between fb-px-1.5 fb-text-xs fb-leading-6 fb-gap-8">
|
||||
<div className="fb-text-subheading fb-mt-8 fb-flex fb-justify-between fb-px-1.5 fb-text-xs fb-leading-6 fb-gap-8">
|
||||
<p className="fb-max-w-[50%]" dir="auto">
|
||||
{getLocalizedValue(element.lowerLabel, languageCode)}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user