fix: surveys package tailwind (#2827)

Co-authored-by: Piyush Gupta <piyushguptaa2z123@gmail.com>
This commit is contained in:
Anshuman Pandey
2024-07-02 12:14:15 +05:30
committed by GitHub
parent 58df9c6edb
commit 1f4b23b105
43 changed files with 341 additions and 288 deletions

View File

@@ -7,7 +7,7 @@
e.parentNode.insertBefore(t, e),
setTimeout(function () {
formbricks.init({
environmentId: "clxvg2bf40005m66n1mrqsi1d",
environmentId: "cly414cqm000cstwa5s8w0mg2",
userId: "RANDOM_USER_ID",
apiHost: "http://localhost:3000",
});

View File

@@ -37,13 +37,13 @@
},
"devDependencies": {
"@calcom/embed-snippet": "1.3.0",
"@formbricks/lib": "workspace:*",
"@formbricks/config-typescript": "workspace:*",
"@formbricks/eslint-config": "workspace:*",
"@formbricks/lib": "workspace:*",
"@formbricks/types": "workspace:*",
"@preact/preset-vite": "^2.8.2",
"autoprefixer": "^10.4.19",
"concurrently": "8.2.2",
"@formbricks/eslint-config": "workspace:*",
"isomorphic-dompurify": "^2.12.0",
"postcss": "^8.4.38",
"preact": "^10.22.0",

View File

@@ -13,7 +13,7 @@ export const BackButton = ({ onClick, backButtonLabel, tabIndex = 2 }: BackButto
tabIndex={tabIndex}
type={"button"}
className={cn(
"border-back-button-border text-heading focus:ring-focus rounded-custom flex items-center border px-3 py-3 text-base font-medium leading-4 shadow-sm hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-offset-2"
"fb-border-back-button-border fb-text-heading focus:fb-ring-focus fb-rounded-custom fb-flex fb-items-center fb-border fb-px-3 fb-py-3 fb-text-base fb-font-medium fb-leading-4 fb-shadow-sm hover:fb-opacity-90 focus:fb-outline-none focus:fb-ring-2 focus:fb-ring-offset-2"
)}
onClick={onClick}>
{backButtonLabel || "Back"}

View File

@@ -36,7 +36,7 @@ export const SubmitButton = ({
type={type}
tabIndex={tabIndex}
autoFocus={focus}
className="bg-brand border-submit-button-border text-on-brand focus:ring-focus rounded-custom flex items-center border px-3 py-3 text-base font-medium leading-4 shadow-sm hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-offset-2"
className="fb-bg-brand fb-border-submit-button-border fb-text-on-brand focus:fb-ring-focus fb-rounded-custom fb-flex fb-items-center fb-border fb-px-3 fb-py-3 fb-text-base fb-font-medium fb-leading-4 fb-shadow-sm hover:fb-opacity-90 focus:fb-outline-none focus:fb-ring-2 focus:fb-ring-offset-2"
onClick={onClick}
disabled={disabled}>
{buttonLabel || (isLastQuestion ? "Finish" : "Next")}

View File

@@ -4,10 +4,10 @@ interface AutoCloseProgressBarProps {
export const AutoCloseProgressBar = ({ autoCloseTimeout }: AutoCloseProgressBarProps) => {
return (
<div className="bg-accent-bg h-2 w-full overflow-hidden rounded-full">
<div className="fb-bg-accent-bg fb-h-2 fb-w-full fb-overflow-hidden fb-rounded-full">
<div
key={autoCloseTimeout}
className="bg-brand z-20 h-2 rounded-full"
className="fb-bg-brand fb-z-20 fb-h-2 fb-rounded-full"
style={{
animation: `shrink-width-to-zero ${autoCloseTimeout}s linear forwards`,
}}></div>

View File

@@ -48,8 +48,8 @@ export const CalEmbed = ({ question, onSuccessfulBooking }: CalEmbedProps) => {
}, [cal, question.calUserName]);
return (
<div className="relative mt-4 overflow-auto">
<div id="fb-cal-embed" className={cn("border-border rounded-lg border")} />
<div className="fb-relative fb-mt-4 fb-overflow-auto">
<div id="fb-cal-embed" className={cn("fb-border-border fb-rounded-lg fb-border")} />
</div>
);
};

View File

@@ -147,27 +147,29 @@ export const FileInput = ({
return (
<div
className={`items-left bg-input-bg hover:bg-input-bg-selected border-border relative mt-3 flex w-full flex-col justify-center rounded-lg border-2 border-dashed dark:border-slate-600 dark:bg-slate-700 dark:hover:border-slate-500 dark:hover:bg-slate-800`}>
className={`fb-items-left fb-bg-input-bg hover:fb-bg-input-bg-selected fb-border-border fb-relative fb-mt-3 fb-flex fb-w-full fb-flex-col fb-justify-center fb-rounded-lg fb-border-2 fb-border-dashed dark:fb-border-slate-600 dark:fb-bg-slate-700 dark:hover:fb-border-slate-500 dark:hover:fb-bg-slate-800`}>
<div>
{fileUrls?.map((file, index) => {
const fileName = getOriginalFileNameFromUrl(file);
return (
<div key={index} className="bg-input-bg-selected border-border relative m-2 rounded-md border">
<div className="absolute right-0 top-0 m-2">
<div className="bg-survey-bg flex h-5 w-5 cursor-pointer items-center justify-center rounded-md">
<div
key={index}
className="fb-bg-input-bg-selected fb-border-border fb-relative fb-m-2 fb-rounded-md fb-border">
<div className="fb-absolute fb-right-0 fb-top-0 fb-m-2">
<div className="fb-bg-survey-bg fb-flex fb-h-5 fb-w-5 fb-cursor-pointer fb-items-center fb-justify-center fb-rounded-md">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 26 26"
strokeWidth={1}
stroke="currentColor"
className="text-heading h-5"
className="fb-text-heading fb-h-5"
onClick={(e) => handleDeleteFile(index, e)}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 9l10 10m0-10L9 19" />
</svg>
</div>
</div>
<div className="flex flex-col items-center justify-center p-2">
<div className="fb-flex fb-flex-col fb-items-center fb-justify-center fb-p-2">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -178,11 +180,11 @@ export const FileInput = ({
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-heading h-6">
className="fb-text-heading fb-h-6">
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" />
<polyline points="14 2 14 8 20 8" />
</svg>
<p className="text-heading mt-1 w-full overflow-hidden overflow-ellipsis whitespace-nowrap px-2 text-center text-sm">
<p className="fb-text-heading fb-mt-1 fb-w-full fb-overflow-hidden fb-overflow-ellipsis fb-whitespace-nowrap fb-px-2 fb-text-center fb-text-sm">
{fileName}
</p>
</div>
@@ -193,8 +195,8 @@ export const FileInput = ({
<div>
{isUploading && (
<div className="inset-0 flex animate-pulse items-center justify-center rounded-lg py-4">
<label htmlFor={uniqueHtmlFor} className="text-subheading text-sm font-medium">
<div className="fb-inset-0 fb-flex fb-animate-pulse fb-items-center fb-justify-center fb-rounded-lg fb-py-4">
<label htmlFor={uniqueHtmlFor} className="fb-text-subheading fb-text-sm fb-font-medium">
Uploading...
</label>
</div>
@@ -203,7 +205,7 @@ export const FileInput = ({
<label htmlFor={uniqueHtmlFor} onDragOver={handleDragOver} onDrop={handleDrop}>
{showUploader && (
<div
className="focus:outline-brand flex flex-col items-center justify-center py-6 hover:cursor-pointer"
className="focus:fb-outline-brand fb-flex fb-flex-col fb-items-center fb-justify-center fb-py-6 hover:fb-cursor-pointer"
tabIndex={1}
onKeyDown={(e) => {
// Accessibility: if spacebar was pressed pass this down to the input
@@ -219,22 +221,22 @@ export const FileInput = ({
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="text-placeholder h-6">
className="fb-text-placeholder fb-h-6">
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"
/>
</svg>
<p className="text-placeholder mt-2 text-sm dark:text-slate-400">
<span className="font-medium">Click or drag to upload files.</span>
<p className="fb-text-placeholder fb-mt-2 fb-text-sm dark:fb-text-slate-400">
<span className="fb-font-medium">Click or drag to upload files.</span>
</p>
<input
type="file"
id={uniqueHtmlFor}
name={uniqueHtmlFor}
accept={allowedFileExtensions?.map((ext) => `.${ext}`).join(",")}
className="hidden"
className="fb-hidden"
onChange={(e) => {
const inputElement = e.target as HTMLInputElement;
if (inputElement.files) {

View File

@@ -4,11 +4,11 @@ export const FormbricksBranding = () => {
href="https://formbricks.com?utm_source=survey_branding"
target="_blank"
tabIndex={-1}
className="my-2 flex justify-center">
<p className="text-signature text-xs">
className="fb-my-2 fb-flex fb-justify-center">
<p className="fb-text-signature fb-text-xs">
Powered by{" "}
<b>
<span className="text-branding-text hover:text-signature">Formbricks</span>
<span className="fb-text-branding-text hover:fb-text-signature">Formbricks</span>
</b>
</p>
</a>

View File

@@ -12,14 +12,16 @@ export const Headline = ({
alignTextCenter = false,
}: HeadlineProps) => {
return (
<label htmlFor={questionId} className="text-heading mb-1.5 block text-base font-semibold leading-6">
<label
htmlFor={questionId}
className="fb-text-heading fb-mb-1.5 fb-block fb-text-base fb-font-semibold fb-leading-6">
<div
className={`flex items-center ${alignTextCenter ? "justify-center" : "justify-between"}`}
className={`fb-flex fb-items-center ${alignTextCenter ? "fb-justify-center" : "fb-justify-between"}`}
dir="auto">
{headline}
{!required && (
<span
className="text-heading mx-2 self-start text-sm font-normal leading-7 opacity-60"
className="fb-text-heading fb-mx-2 fb-self-start fb-text-sm fb-font-normal fb-leading-7 fb-opacity-60"
tabIndex={-1}>
Optional
</span>

View File

@@ -23,7 +23,7 @@ export const HtmlBody = ({ htmlString, questionId }: HtmlBodyProps) => {
return (
<label
htmlFor={questionId}
className={cn("fb-htmlbody break-words")} // styles are in global.css
className={cn("fb-htmlbody fb-break-words")} // styles are in global.css
dangerouslySetInnerHTML={{ __html: safeHtml }}
dir="auto"
/>

View File

@@ -37,20 +37,20 @@ export const LanguageSwitch = ({
useClickOutside(languageDropdownRef, () => setShowLanguageDropdown(false));
return (
<div class="z-[1001] flex w-fit items-center even:pr-1">
<div class="fb-z-[1001] fb-flex fb-w-fit fb-items-center even:fb-pr-1">
<button
title="Language switch"
type="button"
class="text-heading relative h-5 w-5 rounded-md hover:bg-black/5 focus:outline-none focus:ring-2 focus:ring-offset-2"
class="fb-text-heading fb-relative fb-h-5 fb-w-5 fb-rounded-md hover:fb-bg-black/5 focus:fb-outline-none focus:fb-ring-2 focus:fb-ring-offset-2"
onClick={toggleDropdown}
tabIndex={-1}
aria-haspopup="true"
aria-expanded={showLanguageDropdown}>
<GlobeIcon className="text-heading h-5 w-5 p-0.5" />
<GlobeIcon className="fb-text-heading fb-h-5 fb-w-5 fb-p-0.5" />
</button>
{showLanguageDropdown && (
<div
className="bg-brand text-on-brand absolute right-8 top-10 space-y-2 rounded-md p-2 text-xs"
className="fb-bg-brand fb-text-on-brand fb-absolute fb-right-8 fb-top-10 fb-space-y-2 fb-rounded-md fb-p-2 fb-text-xs"
ref={languageDropdownRef}>
{surveyLanguages.map((surveyLanguage) => {
if (!surveyLanguage.enabled) return;
@@ -58,7 +58,7 @@ export const LanguageSwitch = ({
<button
key={surveyLanguage.language.id}
type="button"
className="block w-full p-1.5 text-left hover:opacity-80"
className="fb-block fb-w-full fb-p-1.5 fb-text-left hover:fb-opacity-80"
onClick={() => changeLanguage(surveyLanguage.language.code)}>
{getLanguageLabel(surveyLanguage.language.code)}
</button>

View File

@@ -4,15 +4,21 @@ export const LoadingSpinner = ({ className }: { className?: string }) => {
return (
<div
data-testid="loading-spinner"
className={cn("flex h-full w-full items-center justify-center", className ?? "")}>
className={cn("fb-flex fb-h-full fb-w-full fb-items-center fb-justify-center", className ?? "")}>
<svg
className="m-2 h-6 w-6 animate-spin text-slate-700"
className="fb-m-2 fb-h-6 fb-w-6 fb-animate-spin fb-text-slate-700"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<circle
className="fb-opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"></circle>
<path
className="opacity-75"
className="fb-opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>

View File

@@ -1,8 +1,8 @@
export const Progress = ({ progress }: { progress: number }) => {
return (
<div className="bg-accent-bg h-2 w-full overflow-hidden rounded-full">
<div className="fb-bg-accent-bg fb-h-2 fb-w-full fb-overflow-hidden fb-rounded-full">
<div
className="transition-width bg-brand z-20 h-2 rounded-full duration-500"
className="fb-transition-width fb-bg-brand fb-z-20 fb-h-2 fb-rounded-full fb-duration-500"
style={{ width: `${Math.floor(progress * 100)}%` }}></div>
</div>
);

View File

@@ -31,29 +31,29 @@ export const QuestionMedia = ({ imgUrl, videoUrl, altText = "Image" }: QuestionM
const [isLoading, setIsLoading] = useState(true);
return (
<div className="group/image relative mb-4 block min-h-40 rounded-md">
<div className="fb-group/image fb-relative fb-mb-4 fb-block fb-min-h-40 fb-rounded-md">
{isLoading && (
<div className="absolute inset-auto flex h-full w-full animate-pulse items-center justify-center rounded-md bg-slate-200"></div>
<div className="fb-absolute fb-inset-auto fb-flex fb-h-full fb-w-full fb-animate-pulse fb-items-center fb-justify-center fb-rounded-md fb-bg-slate-200" />
)}
{imgUrl && (
<img
key={imgUrl}
src={imgUrl}
alt={altText}
className="rounded-custom"
className="fb-rounded-custom"
onLoad={() => {
setIsLoading(false);
}}
/>
)}
{videoUrlWithParams && (
<div className="relative">
<div className="rounded-custom bg-black">
<div className="fb-relative">
<div className="fb-rounded-custom fb-bg-black">
<iframe
src={videoUrlWithParams}
title="Question Video"
frameborder="0"
className="rounded-custom aspect-video w-full"
className="fb-rounded-custom fb-aspect-video fb-w-full"
onLoad={() => setIsLoading(false)}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"></iframe>
@@ -64,7 +64,7 @@ export const QuestionMedia = ({ imgUrl, videoUrl, altText = "Image" }: QuestionM
href={!!imgUrl ? imgUrl : parseVideoUrl(videoUrl ?? "")}
target="_blank"
rel="noreferrer"
className="absolute bottom-2 right-2 flex items-center gap-2 rounded-md bg-gray-800 bg-opacity-40 p-1.5 text-white opacity-0 backdrop-blur-lg transition duration-300 ease-in-out hover:bg-opacity-65 group-hover/image:opacity-100">
className="fb-absolute fb-bottom-2 fb-right-2 fb-flex fb-items-center fb-gap-2 fb-rounded-md fb-bg-gray-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">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"

View File

@@ -35,7 +35,7 @@ export const RedirectCountDown = ({ redirectUrl, isRedirectDisabled }: RedirectC
return (
<div>
<div className="bg-accent-bg text-subheading mt-10 rounded-md p-2 text-sm">
<div className="fb-bg-accent-bg fb-text-subheading fb-mt-10 fb-rounded-md fb-p-2 fb-text-sm">
<span>You&apos;re redirected in </span>
<span>{timeRemaining}</span>
</div>

View File

@@ -11,24 +11,24 @@ type ResponseErrorComponentProps = {
export const ResponseErrorComponent = ({ questions, responseData, onRetry }: ResponseErrorComponentProps) => {
return (
<div className={"flex flex-col bg-white p-4"}>
<span className={"mb-1.5 text-base font-bold leading-6 text-slate-900"}>
<div className={"fb-flex fb-flex-col fb-bg-white fb-p-4s"}>
<span className={"fb-mb-1.5 fb-text-base fb-font-bold fb-leading-6 fb-text-slate-900"}>
{"Your feedback is stuck :("}
</span>
<p className={"max-w-md text-sm font-normal leading-6 text-slate-600"}>
<p className={"fb-max-w-md fb-text-sm fb-font-normal fb-leading-6 fb-text-slate-600"}>
The servers cannot be reached at the moment.
<br />
Please retry now or try again later.
</p>
<div className={"mt-4 rounded-lg border border-slate-200 bg-slate-100 px-4 py-5"}>
<div className={"flex max-h-36 flex-1 flex-col space-y-3 overflow-y-scroll"}>
<div className={"fb-mt-4 fb-rounded-lg fb-border fb-border-slate-200 fb-bg-slate-100 fb-px-4 fb-py-5"}>
<div className={"fb-flex fb-max-h-36 fb-flex-1 fb-flex-col fb-space-y-3 fb-overflow-y-scroll"}>
{questions.map((question, index) => {
const response = responseData[question.id];
if (!response) return;
return (
<div className={"flex flex-col"}>
<span className={"text-sm leading-6 text-slate-900"}>{`Question ${index + 1}`}</span>
<span className={"mt-1 text-sm font-semibold leading-6 text-slate-900"}>
<div className={"fb-flex fb-flex-col"}>
<span className={"fb-text-sm fb-leading-6 fb-text-slate-900"}>{`Question ${index + 1}`}</span>
<span className={"fb-mt-1 fb-text-sm fb-font-semibold fb-leading-6 fb-text-slate-900"}>
{processResponseData(response)}
</span>
</div>
@@ -36,7 +36,7 @@ export const ResponseErrorComponent = ({ questions, responseData, onRetry }: Res
})}
</div>
</div>
<div className={"mt-4 flex flex-1 flex-row items-center justify-end space-x-2"}>
<div className={"fb-mt-4 fb-flex fb-flex-1 fb-flex-row fb-items-center fb-justify-end fb-space-x-2"}>
<SubmitButton tabIndex={2} buttonLabel="Retry" isLastQuestion={false} onClick={() => onRetry()} />
</div>
</div>

View File

@@ -7,7 +7,7 @@ export const Subheader = ({ subheader, questionId }: SubheaderProps) => {
return (
<p
htmlFor={questionId}
className="text-subheading block break-words text-sm font-normal leading-5"
className="fb-text-subheading fb-block fb-break-words fb-text-sm fb-font-normal fb-leading-5"
dir="auto">
{subheader}
</p>

View File

@@ -323,11 +323,11 @@ export const Survey = ({
<AutoCloseWrapper survey={survey} onClose={onClose} offset={offset}>
<div
className={cn(
"no-scrollbar md:rounded-custom rounded-t-custom bg-survey-bg flex h-full w-full flex-col justify-between overflow-hidden transition-all duration-1000 ease-in-out",
"fb-no-scrollbar md:fb-rounded-custom fb-rounded-t-custom fb-bg-survey-bg fb-flex fb-h-full fb-w-full fb-flex-col fb-justify-between fb-overflow-hidden fb-transition-all fb-duration-1000 fb-ease-in-out",
cardArrangement === "simple" ? "fb-survey-shadow" : "",
offset === 0 || cardArrangement === "simple" ? "opacity-100" : "opacity-0"
offset === 0 || cardArrangement === "simple" ? "fb-opacity-100" : "fb-opacity-0"
)}>
<div className="flex h-6 justify-end pr-2 pt-2">
<div className="fb-flex fb-h-6 fb-justify-end fb-pr-2 fb-pt-2">
{getShowLanguageSwitch(offset) && (
<LanguageSwitch
surveyLanguages={survey.languages}
@@ -338,10 +338,13 @@ export const Survey = ({
</div>
<div
ref={contentRef}
className={cn(loadingElement ? "animate-pulse opacity-60" : "", fullSizeCards ? "" : "my-auto")}>
className={cn(
loadingElement ? "fb-animate-pulse fb-opacity-60" : "",
fullSizeCards ? "" : "fb-my-auto"
)}>
{content()}
</div>
<div className="mx-6 mb-10 mt-2 space-y-3 md:mb-6 md:mt-6">
<div className="fb-mx-6 fb-mb-10 fb-mt-2 fb-space-y-3 md:fb-mb-6 md:fb-mt-6">
{isBrandingEnabled && <FormbricksBranding />}
{showProgressBar && <ProgressBar survey={survey} questionId={questionId} />}
</div>

View File

@@ -4,13 +4,13 @@ interface SurveyCloseButtonProps {
export const SurveyCloseButton = ({ onClose }: SurveyCloseButtonProps) => {
return (
<div class="z-[1001] flex w-fit items-center even:border-l even:pl-1">
<div class="fb-z-[1001] fb-flex fb-w-fit fb-items-center even:fb-border-l even:fb-pl-1">
<button
type="button"
onClick={onClose}
class="text-heading relative h-5 w-5 rounded-md hover:bg-black/5 focus:outline-none focus:ring-2 focus:ring-offset-2">
class="fb-text-heading fb-relative fb-h-5 fb-w-5 fb-rounded-md hover:fb-bg-black/5 focus:fb-outline-none focus:fb-ring-2 focus:fb-ring-offset-2">
<svg
class="h-5 w-5 p-0.5"
class="fb-h-5 fb-w-5 fb-p-0.5"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1"

View File

@@ -3,7 +3,7 @@ import { Survey } from "./Survey";
export const SurveyInline = (props: SurveyInlineProps) => {
return (
<div id="fbjs" className="formbricks-form h-full w-full">
<div id="fbjs" className="fb-formbricks-form fb-h-full fb-w-full">
<Survey {...props} />
</div>
);

View File

@@ -36,7 +36,7 @@ export const SurveyModal = ({
const highlightBorderColor = styling?.highlightBorderColor?.light || null;
return (
<div id="fbjs" className="formbricks-form">
<div id="fbjs" className="fb-formbricks-form">
<Modal
placement={placement}
clickOutside={clickOutside}

View File

@@ -39,21 +39,21 @@ export const ThankYouCard = ({
}: ThankYouCardProps) => {
const media = imageUrl || videoUrl ? <QuestionMedia imgUrl={imageUrl} videoUrl={videoUrl} /> : null;
const checkmark = (
<div className="text-brand flex flex-col items-center justify-center">
<div className="fb-text-brand fb-flex fb-flex-col fb-items-center fb-justify-center">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
class="h-24 w-24">
class="fb-h-24 fb-w-24">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<span className="bg-brand mb-[10px] inline-block h-1 w-16 rounded-[100%]"></span>
<span className="fb-bg-brand fb-mb-[10px] fb-inline-block fb-h-1 fb-w-16 fb-rounded-[100%]"></span>
</div>
);
@@ -83,7 +83,7 @@ export const ThankYouCard = ({
return (
<ScrollableContainer>
<div className="text-center">
<div className="fb-text-center">
{isResponseSendingFinished ? (
<>
{media || checkmark}
@@ -91,7 +91,7 @@ export const ThankYouCard = ({
<Subheader subheader={subheader} questionId="thankYouCard" />
<RedirectCountDown redirectUrl={redirectUrl} isRedirectDisabled={isRedirectDisabled} />
{buttonLabel && (
<div className="mt-6 flex w-full flex-col items-center justify-center space-y-4">
<div className="fb-mt-6 fb-flex fb-w-full fb-flex-col fb-items-center fb-justify-center fb-space-y-4">
<SubmitButton
buttonLabel={buttonLabel}
isLastQuestion={false}
@@ -103,10 +103,10 @@ export const ThankYouCard = ({
</>
) : (
<>
<div className="my-3">
<div className="fb-my-3">
<LoadingSpinner />
</div>
<h1 className="text-brand">Sending responses...</h1>
<h1 className="fb-text-brand">Sending responses...</h1>
</>
)}
</div>

View File

@@ -24,7 +24,7 @@ interface WelcomeCardProps {
const TimerIcon = () => {
return (
<div className="mr-1">
<div className="fb-mr-1">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
@@ -41,14 +41,14 @@ const TimerIcon = () => {
const UsersIcon = () => {
return (
<div className="mr-1">
<div className="fb-mr-1">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
class="h-4 w-4">
class="fb-h-4 fb-w-4">
<path
strokeLinecap="round"
strokeLinejoin="round"
@@ -132,7 +132,11 @@ export const WelcomeCard = ({
<ScrollableContainer>
<div>
{fileUrl && (
<img src={fileUrl} className="mb-8 max-h-96 w-1/3 rounded-lg object-contain" alt="Company Logo" />
<img
src={fileUrl}
className="fb-mb-8 fb-max-h-96 fb-w-1/3 fb-rounded-lg fb-object-contain"
alt="Company Logo"
/>
)}
<Headline
@@ -146,7 +150,7 @@ export const WelcomeCard = ({
</div>
</ScrollableContainer>
<div className="mx-6 mt-4 flex gap-4 py-4">
<div className="fb-mx-6 fb-mt-4 fb-flex fb-gap-4 fb-py-4">
<SubmitButton
buttonLabel={getLocalizedValue(buttonLabel, languageCode)}
isLastQuestion={false}
@@ -158,23 +162,23 @@ export const WelcomeCard = ({
</div>
{timeToFinish && !showResponseCount ? (
<div className="item-center text-subheading my-4 ml-6 flex">
<div className="fb-items-center fb-text-subheading fb-my-4 fb-ml-6 fb-flex">
<TimerIcon />
<p className="pt-1 text-xs">
<p className="fb-pt-1 fb-text-xs">
<span> Takes {calculateTimeToComplete()} </span>
</p>
</div>
) : showResponseCount && !timeToFinish && responseCount && responseCount > 3 ? (
<div className="item-center text-subheading my-4 ml-6 flex">
<div className="fb-items-center fb-text-subheading fb-my-4 fb-ml-6 fb-flex">
<UsersIcon />
<p className="pt-1 text-xs">
<p className="fb-pt-1 fb-text-xs">
<span>{`${responseCount} people responded`}</span>
</p>
</div>
) : timeToFinish && showResponseCount ? (
<div className="item-center text-subheading my-4 ml-6 flex">
<div className="fb-items-center fb-text-subheading fb-my-4 fb-ml-6 fb-flex">
<TimerIcon />
<p className="pt-1 text-xs">
<p className="fb-pt-1 fb-text-xs">
<span> Takes {calculateTimeToComplete()} </span>
<span>{responseCount && responseCount > 3 ? `${responseCount} people responded` : ""}</span>
</p>

View File

@@ -130,7 +130,7 @@ export const AddressQuestion = ({
);
return (
<form key={question.id} onSubmit={handleSubmit} className="w-full" ref={formRef}>
<form key={question.id} onSubmit={handleSubmit} className="fb-w-full" ref={formRef}>
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -143,7 +143,7 @@ export const AddressQuestion = ({
subheader={question.subheader ? getLocalizedValue(question.subheader, languageCode) : ""}
questionId={question.id}
/>
<div className="mt-4 space-y-2">
<div className="fb-mt-4 fb-space-y-2">
{inputConfig.map(({ name, placeholder, required }, index) => (
<input
ref={index === 0 ? addressTextRef : null}
@@ -158,13 +158,13 @@ export const AddressQuestion = ({
value={safeValue[index] || ""}
onInput={(e) => handleInputChange(e.currentTarget.value, index)}
autoFocus={autoFocusEnabled && index === 0}
className="border-border focus:border-brand placeholder:text-placeholder text-subheading bg-input-bg rounded-custom block w-full border p-2 shadow-sm sm:text-sm"
className="fb-border-border focus:fb-border-brand placeholder:fb-text-placeholder fb-text-subheading fb-bg-input-bg fb-rounded-custom fb-block fb-w-full fb-border fb-p-2 fb-shadow-sm sm:fb-text-sm"
/>
))}
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
tabIndex={8}

View File

@@ -57,7 +57,7 @@ export const CTAQuestion = ({
<HtmlBody htmlString={getLocalizedValue(question.html, languageCode)} questionId={question.id} />
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
backButtonLabel={getLocalizedValue(question.backButtonLabel, languageCode)}
@@ -69,7 +69,7 @@ export const CTAQuestion = ({
}}
/>
)}
<div className="flex w-full justify-end">
<div className="fb-flex fb-w-full fb-justify-end">
{!question.required && (
<button
dir="auto"
@@ -81,7 +81,7 @@ export const CTAQuestion = ({
onSubmit({ [question.id]: "dismissed" }, updatedTtcObj);
onChange({ [question.id]: "dismissed" });
}}
className="text-heading focus:ring-focus mr-4 flex items-center rounded-md px-3 py-3 text-base font-medium leading-4 hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-offset-2">
className="fb-text-heading focus:fb-ring-focus fb-mr-4 fb-flex fb-items-center fb-rounded-md fb-px-3 fb-py-3 fb-text-base fb-font-medium fb-leading-4 hover:fb-opacity-90 focus:fb-outline-none focus:fb-ring-2 focus:fb-ring-offset-2">
{getLocalizedValue(question.dismissButtonLabel, languageCode) || "Skip"}
</button>
)}

View File

@@ -68,7 +68,7 @@ export const CalQuestion = ({
onChange({ [question.id]: value });
onSubmit({ [question.id]: value }, updatedttc);
}}
className="w-full">
className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -82,12 +82,12 @@ export const CalQuestion = ({
questionId={question.id}
/>
<>
{errorMessage && <span className="text-red-500">{errorMessage}</span>}
{errorMessage && <span className="fb-text-red-500">{errorMessage}</span>}
<CalEmbed key={question.id} question={question} onSuccessfulBooking={onSuccessfulBooking} />
</>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
backButtonLabel={getLocalizedValue(question.backButtonLabel, languageCode)}

View File

@@ -64,7 +64,7 @@ export const ConsentQuestion = ({
htmlString={getLocalizedValue(question.html, languageCode) || ""}
questionId={question.id}
/>
<div className="bg-survey-bg sticky -bottom-2 z-10 w-full px-1 py-1">
<div className="fb-bg-survey-bg fb-sticky -fb-bottom-2 fb-z-10 fb-w-full fb-px-1 fb-py-1">
<label
dir="auto"
tabIndex={1}
@@ -77,7 +77,7 @@ export const ConsentQuestion = ({
document.getElementById(`${question.id}-label`)?.focus();
}
}}
className="border-border bg-input-bg text-heading hover:bg-input-bg-selected focus:bg-input-bg-selected focus:ring-brand rounded-custom relative z-10 my-2 flex w-full cursor-pointer items-center border p-4 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2">
className="fb-border-border fb-bg-input-bg fb-text-heading hover:fb-bg-input-bg-selected focus:fb-bg-input-bg-selected focus:fb-ring-brand fb-rounded-custom fb-relative fb-z-10 fb-my-2 fb-flex fb-w-full fb-cursor-pointer fb-items-center fb-border fb-p-4 fb-text-sm focus:fb-outline-none focus:fb-ring-2 focus:fb-ring-offset-2">
<input
type="checkbox"
id={question.id}
@@ -91,11 +91,11 @@ export const ConsentQuestion = ({
}
}}
checked={value === "accepted"}
className="border-brand text-brand h-4 w-4 border focus:ring-0 focus:ring-offset-0"
className="fb-border-brand fb-text-brand fb-h-4 fb-w-4 fb-border focus:fb-ring-0 focus:fb-ring-offset-0"
aria-labelledby={`${question.id}-label`}
required={question.required}
/>
<span id={`${question.id}-label`} className="ml-3 mr-3 font-medium">
<span id={`${question.id}-label`} className="fb-ml-3 fb-mr-3 fb-font-medium">
{getLocalizedValue(question.label, languageCode)}
</span>
</label>
@@ -103,7 +103,7 @@ export const ConsentQuestion = ({
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
tabIndex={3}

View File

@@ -139,7 +139,7 @@ export const DateQuestion = ({
setTtc(updatedTtcObj);
onSubmit({ [question.id]: value }, updatedTtcObj);
}}
className="w-full">
className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -152,13 +152,13 @@ export const DateQuestion = ({
subheader={question.subheader ? getLocalizedValue(question.subheader, languageCode) : ""}
questionId={question.id}
/>
<div className={"text-red-600"}>
<div className={"fb-text-red-600"}>
<span>{errorMessage}</span>
</div>
<div
className={cn("mt-4 w-full", errorMessage && "rounded-lg border-2 border-red-500")}
className={cn("fb-mt-4 fb-w-full", errorMessage && "fb-rounded-lg fb-border-2 fb-border-red-500")}
id="date-picker-root">
<div className="relative">
<div className="fb-relative">
{!datePickerOpen && (
<div
onClick={() => setDatePickerOpen(true)}
@@ -166,14 +166,14 @@ export const DateQuestion = ({
onKeyDown={(e) => {
if (e.key === " ") setDatePickerOpen(true);
}}
className="focus:outline-brand bg-input-bg hover:bg-input-bg-selected border-border text-heading rounded-custom relative flex h-[12dvh] w-full cursor-pointer appearance-none items-center justify-center border text-left text-base font-normal">
<div className="flex items-center gap-2">
className="focus:fb-outline-brand fb-bg-input-bg hover:fb-bg-input-bg-selected fb-border-border fb-text-heading fb-rounded-custom fb-relative fb-flex fb-h-[12dvh] fb-w-full fb-cursor-pointer fb-appearance-none fb-items-center fb-justify-center fb-border fb-text-left fb-text-base fb-font-normal">
<div className="fb-flex fb-items-center fb-gap-2">
{selectedDate ? (
<div className="flex items-center gap-2">
<div className="fb-flex fb-items-center fb-gap-2">
<CalendarCheckIcon /> <span>{formattedDate}</span>
</div>
) : (
<div className="flex items-center gap-2">
<div className="fb-flex fb-items-center fb-gap-2">
<CalendarIcon /> <span>Select a date</span>
</div>
)}
@@ -208,8 +208,8 @@ export const DateQuestion = ({
monthPlaceholder="MM"
yearPlaceholder="YYYY"
format={question.format ?? "M-d-y"}
className={`dp-input-root rounded-custom wrapper-hide ${!datePickerOpen ? "" : "h-[46dvh] sm:h-[34dvh]"} ${hideInvalid ? "hide-invalid" : ""} `}
calendarClassName="calendar-root !bg-input-bg border border-border rounded-custom p-3 h-[46dvh] sm:h-[33dvh] overflow-auto"
className={`dp-input-root fb-rounded-custom wrapper-hide ${!datePickerOpen ? "" : "fb-h-[46dvh] sm:fb-h-[34dvh]"} ${hideInvalid ? "hide-invalid" : ""} `}
calendarClassName="calendar-root !fb-bg-input-bg fb-border fb-border-border fb-rounded-custom fb-p-3 fb-h-[46dvh] sm:fb-h-[33dvh] fb-overflow-auto"
clearIcon={null}
onCalendarOpen={() => {
setDatePickerOpen(true);
@@ -223,14 +223,14 @@ export const DateQuestion = ({
calendarIcon={<CalendarIcon />}
tileClassName={({ date }: { date: Date }) => {
const baseClass =
"hover:bg-input-bg-selected rounded-custom h-9 p-0 mt-1 font-normal text-heading aria-selected:opacity-100 focus:ring-2 focus:bg-slate-200";
"hover:fb-bg-input-bg-selected fb-rounded-custom fb-h-9 fb-p-0 fb-mt-1 fb-font-normal fb-text-heading aria-selected:fb-opacity-100 focus:fb-ring-2 focus:fb-bg-slate-200";
// today's date class
if (
date.getDate() === new Date().getDate() &&
date.getMonth() === new Date().getMonth() &&
date.getFullYear() === new Date().getFullYear()
) {
return `${baseClass} !bg-brand !border-border-highlight !text-heading focus:ring-2 focus:bg-slate-200`;
return `${baseClass} !fb-bg-brand !fb-border-border-highlight !fb-text-heading focus:fb-ring-2 focus:fb-bg-slate-200`;
}
// active date class
if (
@@ -238,7 +238,7 @@ export const DateQuestion = ({
date.getMonth() === selectedDate?.getMonth() &&
date.getFullYear() === selectedDate?.getFullYear()
) {
return `${baseClass} !bg-brand !border-border-highlight !text-heading`;
return `${baseClass} !fb-bg-brand !fb-border-border-highlight !fb-text-heading`;
}
return baseClass;
@@ -253,7 +253,7 @@ export const DateQuestion = ({
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
<div>
{!isFirstQuestion && (
<BackButton

View File

@@ -69,7 +69,7 @@ export const FileUploadQuestion = ({
}
}
}}
className="w-full">
className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -102,7 +102,7 @@ export const FileUploadQuestion = ({
/>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
backButtonLabel={getLocalizedValue(question.backButtonLabel, languageCode)}

View File

@@ -84,7 +84,10 @@ export const MatrixQuestion = ({
const columnsHeaders = useMemo(
() =>
question.columns.map((column, index) => (
<th key={index} className="text-heading max-w-40 break-words px-4 py-2 font-normal" dir="auto">
<th
key={index}
className="fb-text-heading fb-max-w-40 fb-break-words fb-px-4 fb-py-2 fb-font-normal"
dir="auto">
{getLocalizedValue(column, languageCode)}
</th>
)),
@@ -92,7 +95,7 @@ export const MatrixQuestion = ({
);
return (
<form key={question.id} onSubmit={handleSubmit} className="w-full">
<form key={question.id} onSubmit={handleSubmit} className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -105,11 +108,11 @@ export const MatrixQuestion = ({
subheader={getLocalizedValue(question.subheader, languageCode)}
questionId={question.id}
/>
<div className="overflow-x-auto py-4">
<table className="no-scrollbar min-w-full table-auto border-collapse text-sm">
<div className="fb-overflow-x-auto fb-py-4">
<table className="fb-no-scrollbar fb-min-w-full fb-table-auto fb-border-collapse fb-text-sm">
<thead>
<tr>
<th className="px-4 py-2"></th>
<th className="fb-px-4 fb-py-2"></th>
{columnsHeaders}
</tr>
</thead>
@@ -117,14 +120,16 @@ export const MatrixQuestion = ({
{question.rows.map((row, rowIndex) => (
// Table rows
<tr className={`${rowIndex % 2 === 0 ? "bg-input-bg" : ""}`}>
<td className="text-heading rounded-l-custom max-w-40 break-words px-4 py-2" dir="auto">
<td
className="fb-text-heading fb-rounded-l-custom fb-max-w-40 fb-break-words fb-px-4 fb-py-2"
dir="auto">
{getLocalizedValue(row, languageCode)}
</td>
{question.columns.map((column, columnIndex) => (
<td
key={columnIndex}
tabIndex={0}
className={`outline-brand px-4 py-2 text-gray-800 ${columnIndex === question.columns.length - 1 ? "rounded-r-custom" : ""}`}
className={`fb-outline-brand fb-px-4 fb-py-2 fb-text-gray-800 ${columnIndex === question.columns.length - 1 ? "fb-rounded-r-custom" : ""}`}
onClick={() =>
handleSelect(
getLocalizedValue(column, languageCode),
@@ -141,7 +146,7 @@ export const MatrixQuestion = ({
}
}}
dir="auto">
<div className="flex items-center justify-center p-2">
<div className="fb-flex fb-items-center fb-justify-center fb-p-2">
{/* radio input */}
<input
dir="auto"
@@ -156,7 +161,7 @@ export const MatrixQuestion = ({
getLocalizedValue(column, languageCode)
: false
}
className="border-brand text-brand h-5 w-5 border focus:ring-0 focus:ring-offset-0"
className="fb-border-brand fb-text-brand fb-h-5 fb-w-5 fb-border focus:fb-ring-0 focus:fb-ring-offset-0"
/>
</div>
</td>
@@ -168,7 +173,7 @@ export const MatrixQuestion = ({
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
backButtonLabel={getLocalizedValue(question.backButtonLabel, languageCode)}

View File

@@ -143,7 +143,7 @@ export const MultipleChoiceMultiQuestion = ({
setTtc(updatedTtcObj);
onSubmit({ [question.id]: value }, updatedTtcObj);
}}
className="w-full">
className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -156,10 +156,10 @@ export const MultipleChoiceMultiQuestion = ({
subheader={question.subheader ? getLocalizedValue(question.subheader, languageCode) : ""}
questionId={question.id}
/>
<div className="mt-4">
<div className="fb-mt-4">
<fieldset>
<legend className="sr-only">Options</legend>
<div className="bg-survey-bg relative space-y-2" ref={choicesContainerRef}>
<legend className="fb-sr-only">Options</legend>
<div className="fb-bg-survey-bg fb-relative fb-space-y-2" ref={choicesContainerRef}>
{questionChoices.map((choice, idx) => {
if (!choice || choice.id === "other") return;
return (
@@ -168,9 +168,9 @@ export const MultipleChoiceMultiQuestion = ({
tabIndex={idx + 1}
className={cn(
value.includes(getLocalizedValue(choice.label, languageCode))
? "border-border bg-input-selected-bg z-10"
: "border-border",
"text-heading bg-input-bg focus-within:border-brand hover:bg-input-bg-selected focus:bg-input-bg-selected rounded-custom relative flex cursor-pointer flex-col border p-4 focus:outline-none"
? "fb-border-brand fb-bg-input-bg-selected fb-z-10"
: "fb-border-border",
"fb-text-heading fb-bg-input-bg focus-within:fb-border-brand hover:fb-bg-input-bg-selected focus:fb-bg-input-bg-selected fb-rounded-custom fb-relative fb-flex fb-cursor-pointer fb-flex-col fb-border fb-p-4 focus:fb-outline-none"
)}
onKeyDown={(e) => {
// Accessibility: if spacebar was pressed pass this down to the input
@@ -181,14 +181,14 @@ export const MultipleChoiceMultiQuestion = ({
}
}}
autoFocus={idx === 0 && autoFocusEnabled}>
<span className="flex items-center text-sm" dir="auto">
<span className="fb-flex fb-items-center fb-text-sm" dir="auto">
<input
type="checkbox"
id={choice.id}
name={question.id}
tabIndex={-1}
value={getLocalizedValue(choice.label, languageCode)}
className="border-brand text-brand h-4 w-4 border focus:ring-0 focus:ring-offset-0"
className="fb-border-brand fb-text-brand fb-h-4 fb-w-4 fb-border focus:fb-ring-0 focus:fb-ring-offset-0"
aria-labelledby={`${choice.id}-label`}
onChange={(e) => {
if ((e.target as HTMLInputElement)?.checked) {
@@ -207,7 +207,7 @@ export const MultipleChoiceMultiQuestion = ({
: question.required
}
/>
<span id={`${choice.id}-label`} className="ml-3 mr-3 grow font-medium">
<span id={`${choice.id}-label`} className="fb-ml-3 fb-mr-3 fb-grow fb-font-medium">
{getLocalizedValue(choice.label, languageCode)}
</span>
</span>
@@ -219,9 +219,9 @@ export const MultipleChoiceMultiQuestion = ({
tabIndex={questionChoices.length + 1}
className={cn(
value.includes(getLocalizedValue(otherOption.label, languageCode))
? "border-border bg-input-selected-bg z-10"
: "border-border",
"text-heading focus-within:border-brand bg-input-bg focus-within:bg-input-bg-selected hover:bg-input-bg-selected rounded-custom relative flex cursor-pointer flex-col border p-4 focus:outline-none"
? "fb-border-brand fb-bg-input-bg-selected fb-z-10"
: "fb-border-border",
"fb-text-heading focus-within:fb-border-brand fb-bg-input-bg focus-within:fb-bg-input-bg-selected hover:fb-bg-input-bg-selected fb-rounded-custom fb-relative fb-flex fb-cursor-pointer fb-flex-col fb-border fb-p-4 focus:fb-outline-none"
)}
onKeyDown={(e) => {
// Accessibility: if spacebar was pressed pass this down to the input
@@ -231,14 +231,14 @@ export const MultipleChoiceMultiQuestion = ({
document.getElementById(otherOption.id)?.focus();
}
}}>
<span className="flex items-center text-sm" dir="auto">
<span className="fb-flex fb-items-center fb-text-sm" dir="auto">
<input
type="checkbox"
tabIndex={-1}
id={otherOption.id}
name={question.id}
value={getLocalizedValue(otherOption.label, languageCode)}
className="border-brand text-brand h-4 w-4 border focus:ring-0 focus:ring-offset-0"
className="fb-border-brand fb-text-brand fb-h-4 fb-w-4 fb-border focus:fb-ring-0 focus:fb-ring-offset-0"
aria-labelledby={`${otherOption.id}-label`}
onChange={() => {
setOtherSelected(!otherSelected);
@@ -250,7 +250,7 @@ export const MultipleChoiceMultiQuestion = ({
}}
checked={otherSelected}
/>
<span id={`${otherOption.id}-label`} className="ml-3 mr-3 grow font-medium">
<span id={`${otherOption.id}-label`} className="fb-ml-3 fb-mr-3 fb-grow fb-font-medium">
{getLocalizedValue(otherOption.label, languageCode)}
</span>
</span>
@@ -266,7 +266,7 @@ export const MultipleChoiceMultiQuestion = ({
setOtherValue(e.currentTarget.value);
addItem(e.currentTarget.value);
}}
className="placeholder:text-placeholder border-border bg-survey-bg text-heading focus:ring-focus rounded-custom mt-3 flex h-10 w-full border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
className="placeholder:fb-text-placeholder fb-border-border fb-bg-survey-bg fb-text-heading focus:fb-ring-focus fb-rounded-custom fb-mt-3 fb-flex fb-h-10 fb-w-full fb-border fb-px-3 fb-py-2 fb-text-sm focus:fb-outline-none focus:fb-ring-2 focus:fb-ring-offset-2 disabled:fb-cursor-not-allowed disabled:fb-opacity-50"
placeholder={
getLocalizedValue(question.otherOptionPlaceholder, languageCode) ?? "Please specify"
}
@@ -282,7 +282,7 @@ export const MultipleChoiceMultiQuestion = ({
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
tabIndex={questionChoices.length + 3}

View File

@@ -106,7 +106,7 @@ export const MultipleChoiceSingleQuestion = ({
setTtc(updatedTtcObj);
onSubmit({ [question.id]: value ?? "" }, updatedTtcObj);
}}
className="w-full">
className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -119,11 +119,14 @@ export const MultipleChoiceSingleQuestion = ({
subheader={question.subheader ? getLocalizedValue(question.subheader, languageCode) : ""}
questionId={question.id}
/>
<div className="mt-4">
<div className="fb-mt-4">
<fieldset>
<legend className="sr-only">Options</legend>
<legend className="fb-sr-only">Options</legend>
<div className="bg-survey-bg relative space-y-2" role="radiogroup" ref={choicesContainerRef}>
<div
className="fb-bg-survey-bg fb-relative fb-space-y-2"
role="radiogroup"
ref={choicesContainerRef}>
{questionChoices.map((choice, idx) => {
if (!choice || choice.id === "other") return;
return (
@@ -133,9 +136,9 @@ export const MultipleChoiceSingleQuestion = ({
key={choice.id}
className={cn(
value === getLocalizedValue(choice.label, languageCode)
? "border-brand z-10"
: "border-border",
"text-heading bg-input-bg focus-within:border-brand focus-within:bg-input-bg-selected hover:bg-input-bg-selected rounded-custom relative flex cursor-pointer flex-col border p-4 focus:outline-none"
? "fb-border-brand fb-bg-input-bg-selected fb-z-10"
: "fb-border-border",
"fb-text-heading fb-bg-input-bg focus-within:fb-border-brand focus-within:fb-bg-input-bg-selected hover:fb-bg-input-bg-selected fb-rounded-custom fb-relative fb-flex fb-cursor-pointer fb-flex-col fb-border fb-p-4 focus:fb-outline-none"
)}
onKeyDown={(e) => {
// Accessibility: if spacebar was pressed pass this down to the input
@@ -146,7 +149,7 @@ export const MultipleChoiceSingleQuestion = ({
}
}}
autoFocus={idx === 0 && autoFocusEnabled}>
<span className="flex items-center text-sm">
<span className="fb-flex fb-items-center fb-text-sm">
<input
tabIndex={-1}
type="radio"
@@ -154,7 +157,7 @@ export const MultipleChoiceSingleQuestion = ({
name={question.id}
value={getLocalizedValue(choice.label, languageCode)}
dir="auto"
className="border-brand text-brand h-4 w-4 border focus:ring-0 focus:ring-offset-0"
className="fb-border-brand fb-text-brand fb-h-4 fb-w-4 fb-border focus:fb-ring-0 focus:fb-ring-offset-0"
aria-labelledby={`${choice.id}-label`}
onChange={() => {
setOtherSelected(false);
@@ -163,7 +166,7 @@ export const MultipleChoiceSingleQuestion = ({
checked={value === getLocalizedValue(choice.label, languageCode)}
required={question.required && idx === 0}
/>
<span id={`${choice.id}-label`} className="ml-3 mr-3 grow font-medium">
<span id={`${choice.id}-label`} className="fb-ml-3 fb-mr-3 fb-grow fb-font-medium">
{getLocalizedValue(choice.label, languageCode)}
</span>
</span>
@@ -176,9 +179,9 @@ export const MultipleChoiceSingleQuestion = ({
tabIndex={questionChoices.length + 1}
className={cn(
value === getLocalizedValue(otherOption.label, languageCode)
? "border-border bg-input-bg-selected z-10"
: "border-border",
"text-heading focus-within:border-brand bg-input-bg focus-within:bg-input-bg-selected hover:bg-input-bg-selected rounded-custom relative flex cursor-pointer flex-col border p-4 focus:outline-none"
? "fb-border-brand fb-bg-input-bg-selected fb-z-10"
: "fb-border-border",
"fb-text-heading focus-within:fb-border-brand fb-bg-input-bg focus-within:fb-bg-input-bg-selected hover:fb-bg-input-bg-selected fb-rounded-custom fb-relative fb-flex fb-cursor-pointer fb-flex-col fb-border fb-p-4 focus:fb-outline-none"
)}
onKeyDown={(e) => {
// Accessibility: if spacebar was pressed pass this down to the input
@@ -188,7 +191,7 @@ export const MultipleChoiceSingleQuestion = ({
document.getElementById(otherOption.id)?.focus();
}
}}>
<span className="flex items-center text-sm">
<span className="fb-flex fb-items-center fb-text-sm">
<input
dir="auto"
type="radio"
@@ -196,7 +199,7 @@ export const MultipleChoiceSingleQuestion = ({
tabIndex={-1}
name={question.id}
value={getLocalizedValue(otherOption.label, languageCode)}
className="border-brand text-brand h-4 w-4 border focus:ring-0 focus:ring-offset-0"
className="fb-border-brand fb-text-brand fb-h-4 fb-w-4 fb-border focus:fb-ring-0 focus:fb-ring-offset-0"
aria-labelledby={`${otherOption.id}-label`}
onChange={() => {
setOtherSelected(!otherSelected);
@@ -204,7 +207,10 @@ export const MultipleChoiceSingleQuestion = ({
}}
checked={otherSelected}
/>
<span id={`${otherOption.id}-label`} className="ml-3 mr-3 grow font-medium" dir="auto">
<span
id={`${otherOption.id}-label`}
className="fb-ml-3 fb-mr-3 fb-grow fb-font-medium"
dir="auto">
{getLocalizedValue(otherOption.label, languageCode)}
</span>
</span>
@@ -219,7 +225,7 @@ export const MultipleChoiceSingleQuestion = ({
onChange={(e) => {
onChange({ [question.id]: e.currentTarget.value });
}}
className="placeholder:text-placeholder border-border bg-survey-bg text-heading focus:ring-focus rounded-custom mt-3 flex h-10 w-full border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
className="placeholder:fb-text-placeholder fb-border-border fb-bg-survey-bg fb-text-heading focus:fb-ring-focus fb-rounded-custom fb-mt-3 fb-flex fb-h-10 fb-w-full fb-border fb-px-3 fb-py-2 fb-text-sm focus:fb-outline-none focus:fb-ring-2 focus:fb-ring-offset-2 disabled:fb-cursor-not-allowed disabled:fb-opacity-50"
placeholder={
getLocalizedValue(question.otherOptionPlaceholder, languageCode) ?? "Please specify"
}
@@ -234,7 +240,7 @@ export const MultipleChoiceSingleQuestion = ({
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
backButtonLabel={getLocalizedValue(question.backButtonLabel, languageCode)}

View File

@@ -60,7 +60,7 @@ export const NPSQuestion = ({
};
const getNPSOptionColor = (idx: number) => {
return idx > 8 ? "bg-emerald-100" : idx > 6 ? "bg-orange-100" : "bg-rose-100";
return idx > 8 ? "fb-bg-emerald-100" : idx > 6 ? "fb-bg-orange-100" : "fb-bg-rose-100";
};
return (
@@ -84,10 +84,10 @@ export const NPSQuestion = ({
subheader={question.subheader ? getLocalizedValue(question.subheader, languageCode) : ""}
questionId={question.id}
/>
<div className="my-4">
<div className="fb-my-4">
<fieldset>
<legend className="sr-only">Options</legend>
<div className="flex">
<legend className="fb-sr-only">Options</legend>
<div className="fb-flex">
{Array.from({ length: 11 }, (_, i) => i).map((number, idx) => {
return (
<label
@@ -105,14 +105,16 @@ export const NPSQuestion = ({
}}
className={cn(
value === number
? "border-border-highlight bg-accent-selected-bg z-10 border"
: "border-border",
"text-heading first:rounded-l-custom last:rounded-r-custom focus:border-brand relative flex flex-1 cursor-pointer items-center justify-center overflow-hidden border-b border-l border-t text-center text-sm leading-10 last:border-r focus:border-2 focus:outline-none",
question.isColorCodingEnabled ? "h-[46px]" : "h-10",
hoveredNumber === number ? "bg-accent-bg" : ""
? "fb-border-border-highlight fb-bg-accent-selected-bg fb-z-10 fb-border"
: "fb-border-border",
"fb-text-heading first:fb-rounded-l-custom last:fb-rounded-r-custom focus:fb-border-brand fb-relative fb-h-10 fb-flex-1 fb-cursor-pointer fb-overflow-hidden fb-border-b fb-border-l fb-border-t fb-text-center fb-text-sm fb-leading-10 last:fb-border-r focus:fb-border-2 focus:fb-outline-none",
question.isColorCodingEnabled ? "fb-h-[46px]" : "fb-h-10",
hoveredNumber === number ? "fb-bg-accent-bg" : ""
)}>
{question.isColorCodingEnabled && (
<div className={`absolute left-0 top-0 h-[6px] w-full ${getNPSOptionColor(idx)}`} />
<div
className={`fb-absolute fb-left-0 fb-top-0 fb-h-[6px] fb-w-full ${getNPSOptionColor(idx)}`}
/>
)}
<input
type="radio"
@@ -120,7 +122,7 @@ export const NPSQuestion = ({
name="nps"
value={number}
checked={value === number}
className="absolute left-0 h-full w-full cursor-pointer opacity-0"
className="fb-absolute fb-left-0 fb-h-full fb-w-full fb-cursor-pointer fb-opacity-0"
onClick={() => handleClick(number)}
required={question.required}
/>
@@ -129,7 +131,7 @@ export const NPSQuestion = ({
);
})}
</div>
<div className="text-subheading mt-2 flex justify-between px-1.5 text-xs leading-6">
<div className="fb-text-subheading fb-mt-2 fb-flex fb-justify-between fb-px-1.5 fb-text-xs fb-leading-6">
<p dir="auto">{getLocalizedValue(question.lowerLabel, languageCode)}</p>
<p dir="auto">{getLocalizedValue(question.upperLabel, languageCode)}</p>
</div>
@@ -137,7 +139,7 @@ export const NPSQuestion = ({
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
tabIndex={isLastQuestion ? 12 : 13}

View File

@@ -78,7 +78,7 @@ export const OpenTextQuestion = ({
setTtc(updatedttc);
onSubmit({ [question.id]: value }, updatedttc);
}}
className="w-full">
className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -91,7 +91,7 @@ export const OpenTextQuestion = ({
subheader={question.subheader ? getLocalizedValue(question.subheader, languageCode) : ""}
questionId={question.id}
/>
<div className="mt-4">
<div className="fb-mt-4">
{question.longAnswer === false ? (
<input
ref={openTextRef}
@@ -106,7 +106,7 @@ export const OpenTextQuestion = ({
type={question.inputType}
onInput={(e) => handleInputChange(e.currentTarget.value)}
autoFocus={autoFocusEnabled}
className="border-border placeholder:text-placeholder text-subheading focus:border-brand bg-input-bg rounded-custom block w-full border p-2 shadow-sm focus:outline-none focus:ring-0 sm:text-sm"
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}
/>
@@ -128,7 +128,7 @@ export const OpenTextQuestion = ({
handleInputResize(e);
}}
autoFocus={autoFocusEnabled}
className="border-border placeholder:text-placeholder bg-input-bg text-subheading focus:border-brand rounded-custom block w-full border p-2 shadow-sm focus:ring-0 sm:text-sm"
className="fb-border-border placeholder:fb-text-placeholder fb-bg-input-bg fb-text-subheading focus:fb-border-brand fb-rounded-custom fb-block fb-w-full fb-border fb-p-2 fb-shadow-sm focus:fb-ring-0 sm:fb-text-sm"
pattern={question.inputType === "phone" ? "[+][0-9 ]+" : ".*"}
title={question.inputType === "phone" ? "Please enter a valid phone number" : undefined}
/>
@@ -136,7 +136,7 @@ export const OpenTextQuestion = ({
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
backButtonLabel={getLocalizedValue(question.backButtonLabel, languageCode)}

View File

@@ -94,7 +94,7 @@ export const PictureSelectionQuestion = ({
setTtc(updatedTtcObj);
onSubmit({ [question.id]: value }, updatedTtcObj);
}}
className="w-full">
className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -107,10 +107,10 @@ export const PictureSelectionQuestion = ({
subheader={question.subheader ? getLocalizedValue(question.subheader, languageCode) : ""}
questionId={question.id}
/>
<div className="mt-4">
<div className="fb-mt-4">
<fieldset>
<legend className="sr-only">Options</legend>
<div className="bg-survey-bg relative grid grid-cols-2 gap-x-5 gap-y-4">
<legend className="fb-sr-only">Options</legend>
<div className="fb-bg-survey-bg fb-relative fb-grid fb-grid-cols-2 fb-gap-x-5 fb-gap-y-4">
{questionChoices.map((choice, idx) => (
<label
key={choice.id}
@@ -127,15 +127,15 @@ export const PictureSelectionQuestion = ({
onClick={() => handleChange(choice.id)}
className={cn(
Array.isArray(value) && value.includes(choice.id)
? `border-brand text-brand z-10 border-4 shadow-xl`
? `fb-border-brand fb-text-brand fb-z-10 fb-border-4 fb-shadow-xl`
: "",
"focus:border-brand group/image rounded-custom relative inline-block h-28 w-full cursor-pointer overflow-hidden border focus:border-4 focus:outline-none"
"focus:fb-border-brand fb-rounded-custom fb-relative fb-inline-block fb-h-28 fb-w-full fb-cursor-pointer fb-overflow-hidden fb-border focus:fb-border-4 focus:fb-outline-none"
)}>
<img
src={choice.imageUrl}
id={choice.id}
alt={choice.imageUrl.split("/").pop()}
className="h-full w-full object-cover"
className="fb-h-full fb-w-full fb-object-cover"
/>
<a
tabIndex={-1}
@@ -144,7 +144,7 @@ export const PictureSelectionQuestion = ({
title="Open in new tab"
rel="noreferrer"
onClick={(e) => e.stopPropagation()}
className="absolute bottom-2 right-2 flex items-center gap-2 whitespace-nowrap rounded-md bg-gray-800 bg-opacity-40 p-1.5 text-white opacity-0 backdrop-blur-lg transition duration-300 ease-in-out hover:bg-opacity-65 group-hover/image:opacity-100">
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-gray-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">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
@@ -170,8 +170,8 @@ export const PictureSelectionQuestion = ({
tabIndex={-1}
checked={value.includes(choice.id)}
className={cn(
"border-border rounded-custom pointer-events-none absolute right-2 top-2 z-20 h-5 w-5 border",
value.includes(choice.id) ? "border-brand text-brand" : ""
"fb-border-border fb-rounded-custom fb-pointer-events-none fb-absolute fb-right-2 fb-top-2 fb-z-20 fb-h-5 fb-w-5 fb-border",
value.includes(choice.id) ? "fb-border-brand fb-text-brand" : ""
)}
required={question.required && value.length ? false : question.required}
/>
@@ -183,8 +183,8 @@ export const PictureSelectionQuestion = ({
tabIndex={-1}
checked={value.includes(choice.id)}
className={cn(
"border-border pointer-events-none absolute right-2 top-2 z-20 h-5 w-5 rounded-full border",
value.includes(choice.id) ? "border-brand text-brand" : ""
"fb-border-border fb-pointer-events-none fb-absolute fb-right-2 fb-top-2 fb-z-20 fb-h-5 fb-w-5 fb-rounded-full fb-border",
value.includes(choice.id) ? "fb-border-brand fb-text-brand" : ""
)}
required={question.required && value.length ? false : question.required}
/>
@@ -196,7 +196,7 @@ export const PictureSelectionQuestion = ({
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
tabIndex={questionChoices.length + 3}

View File

@@ -77,7 +77,7 @@ export const RatingQuestion = ({
id={id}
name="rating"
value={number}
className="invisible absolute left-0 h-full w-full cursor-pointer opacity-0"
className="fb-invisible fb-absolute fb-left-0 fb-h-full fb-w-full fb-cursor-pointer fb-opacity-0"
onClick={() => handleSelect(number)}
required={question.required}
checked={value === number}
@@ -90,17 +90,17 @@ export const RatingQuestion = ({
const getRatingNumberOptionColor = (range: number, idx: number) => {
if (range > 5) {
if (range - idx < 2) return "bg-emerald-100";
if (range - idx < 4) return "bg-orange-100";
return "bg-rose-100";
if (range - idx < 2) return "fb-bg-emerald-100";
if (range - idx < 4) return "fb-bg-orange-100";
return "fb-bg-rose-100";
} else if (range < 5) {
if (range - idx < 1) return "bg-emerald-100";
if (range - idx < 2) return "bg-orange-100";
return "bg-rose-100";
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 "bg-emerald-100";
if (range - idx < 3) return "bg-orange-100";
return "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";
}
};
@@ -113,7 +113,7 @@ export const RatingQuestion = ({
setTtc(updatedTtcObj);
onSubmit({ [question.id]: value ?? "" }, updatedTtcObj);
}}
className="w-full">
className="fb-w-full">
<ScrollableContainer>
<div>
{isMediaAvailable && <QuestionMedia imgUrl={question.imageUrl} videoUrl={question.videoUrl} />}
@@ -126,16 +126,16 @@ export const RatingQuestion = ({
subheader={question.subheader ? getLocalizedValue(question.subheader, languageCode) : ""}
questionId={question.id}
/>
<div className="mb-4 mt-6 flex items-center justify-center">
<fieldset className="w-full">
<legend className="sr-only">Choices</legend>
<div className="flex w-full">
<div className="fb-mb-4 fb-mt-6 fb-flex fb-items-center fb-justify-center">
<fieldset className="fb-w-full">
<legend className="fb-sr-only">Choices</legend>
<div className="fb-flex fb-w-full">
{Array.from({ length: question.range }, (_, i) => i + 1).map((number, i, a) => (
<span
key={number}
onMouseOver={() => setHoveredNumber(number)}
onMouseLeave={() => setHoveredNumber(0)}
className="bg-survey-bg flex-1 text-center text-sm">
className="fb-bg-survey-bg fb-flex-1 fb-text-center fb-text-sm">
{question.scale === "number" ? (
<label
tabIndex={i + 1}
@@ -149,17 +149,17 @@ export const RatingQuestion = ({
}}
className={cn(
value === number
? "bg-accent-selected-bg border-border-highlight z-10 border"
: "border-border",
a.length === number ? "rounded-r-custom border-r" : "",
number === 1 ? "rounded-l-custom" : "",
hoveredNumber === number ? "bg-accent-bg" : "",
question.isColorCodingEnabled ? "min-h-[47px]" : "min-h-[41px]",
"text-heading focus:border-brand relative flex w-full cursor-pointer items-center justify-center overflow-hidden border-b border-l border-t focus:border-2 focus:outline-none"
? "fb-bg-accent-selected-bg fb-border-border-highlight fb-z-10 fb-border"
: "fb-border-border",
a.length === number ? "fb-rounded-r-custom fb-border-r" : "",
number === 1 ? "fb-rounded-l-custom" : "",
hoveredNumber === number ? "fb-bg-accent-bg" : "",
question.isColorCodingEnabled ? "fb-min-h-[47px]" : "fb-min-h-[41px]",
"fb-text-heading focus:fb-border-brand fb-relative fb-flex fb-w-full fb-cursor-pointer fb-items-center fb-justify-center fb-overflow-hidden fb-border-b fb-border-l fb-border-t focus:fb-border-2 focus:fb-outline-none"
)}>
{question.isColorCodingEnabled && (
<div
className={`absolute left-0 top-0 h-[6px] w-full ${getRatingNumberOptionColor(question.range, number)}`}
className={`fb-absolute fb-left-0 fb-top-0 fb-h-[6px] fb-w-full ${getRatingNumberOptionColor(question.range, number)}`}
/>
)}
<HiddenRadioInput number={number} id={number.toString()} />
@@ -178,15 +178,15 @@ export const RatingQuestion = ({
}}
className={cn(
number <= hoveredNumber || number <= (value as number)
? "text-amber-400"
: "text-[#8696AC]",
hoveredNumber === number ? "text-amber-400" : "",
"relative flex max-h-16 min-h-9 cursor-pointer justify-center focus:outline-none"
? "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)}>
<HiddenRadioInput number={number} id={number.toString()} />
<div className="h-full w-full max-w-[74px] object-contain">
<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
fillRule="evenodd"
@@ -198,10 +198,10 @@ export const RatingQuestion = ({
) : (
<label
className={cn(
"relative flex max-h-16 min-h-9 w-full cursor-pointer justify-center",
"fb-relative fb-flex fb-max-h-16 fb-min-h-9 fb-w-full fb-cursor-pointer fb-justify-center",
value === number || hoveredNumber === number
? "stroke-rating-selected text-rating-selected"
: "stroke-heading text-heading focus:border-accent-bg focus:border-2 focus:outline-none"
? "fb-stroke-rating-selected fb-text-rating-selected"
: "fb-stroke-heading fb-text-heading focus:fb-border-accent-bg focus:fb-border-2 focus:fb-outline-none"
)}
tabIndex={i + 1}
onKeyDown={(e) => {
@@ -215,7 +215,7 @@ export const RatingQuestion = ({
onFocus={() => setHoveredNumber(number)}
onBlur={() => setHoveredNumber(0)}>
<HiddenRadioInput number={number} id={number.toString()} />
<div className={cn("h-full w-full max-w-[74px] object-contain")}>
<div className={cn("fb-h-full fb-w-full fb-max-w-[74px] fb-object-contain")}>
<RatingSmiley
active={value === number || hoveredNumber === number}
idx={i}
@@ -228,11 +228,11 @@ export const RatingQuestion = ({
</span>
))}
</div>
<div className="text-subheading mt-4 flex justify-between px-1.5 text-xs leading-6">
<p className="w-1/2 text-left" dir="auto">
<div className="fb-text-subheading fb-mt-4 fb-flex fb-justify-between fb-px-1.5 fb-text-xs fb-leading-6">
<p className="fb-w-1/2 fb-text-left" dir="auto">
{getLocalizedValue(question.lowerLabel, languageCode)}
</p>
<p className="w-1/2 text-right" dir="auto">
<p className="fb-w-1/2 fb-text-right" dir="auto">
{getLocalizedValue(question.upperLabel, languageCode)}
</p>
</div>
@@ -240,7 +240,7 @@ export const RatingQuestion = ({
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
<div className="fb-flex fb-w-full fb-justify-between fb-px-6 fb-py-4">
{!isFirstQuestion && (
<BackButton
tabIndex={!question.required || value ? question.range + 2 : question.range + 1}
@@ -274,39 +274,39 @@ interface RatingSmileyProps {
const getSmileyColor = (range: number, idx: number) => {
if (range > 5) {
if (range - idx < 3) return "fill-emerald-100";
if (range - idx < 5) return "fill-orange-100";
return "fill-rose-100";
if (range - idx < 3) return "fb-fill-emerald-100";
if (range - idx < 5) return "fb-fill-orange-100";
return "fb-fill-rose-100";
} else if (range < 5) {
if (range - idx < 2) return "fill-emerald-100";
if (range - idx < 3) return "fill-orange-100";
return "fill-rose-100";
if (range - idx < 2) return "fb-fill-emerald-100";
if (range - idx < 3) return "fb-fill-orange-100";
return "fb-fill-rose-100";
} else {
if (range - idx < 3) return "fill-emerald-100";
if (range - idx < 4) return "fill-orange-100";
return "fill-rose-100";
if (range - idx < 3) return "fb-fill-emerald-100";
if (range - idx < 4) return "fb-fill-orange-100";
return "fb-fill-rose-100";
}
};
const getActiveSmileyColor = (range: number, idx: number) => {
if (range > 5) {
if (range - idx < 3) return "fill-emerald-300";
if (range - idx < 5) return "fill-orange-300";
return "fill-rose-300";
if (range - idx < 3) return "fb-fill-emerald-300";
if (range - idx < 5) return "fb-fill-orange-300";
return "fb-fill-rose-300";
} else if (range < 5) {
if (range - idx < 2) return "fill-emerald-300";
if (range - idx < 3) return "fill-orange-300";
return "fill-rose-300";
if (range - idx < 2) return "fb-fill-emerald-300";
if (range - idx < 3) return "fb-fill-orange-300";
return "fb-fill-rose-300";
} else {
if (range - idx < 3) return "fill-emerald-300";
if (range - idx < 4) return "fill-orange-300";
return "fill-rose-300";
if (range - idx < 3) return "fb-fill-emerald-300";
if (range - idx < 4) return "fb-fill-orange-300";
return "fb-fill-rose-300";
}
};
const getSmiley = (iconIdx: number, idx: number, range: number, active: boolean, addColors: boolean) => {
const activeColor = addColors ? getActiveSmileyColor(range, idx) : "fill-rating-fill";
const inactiveColor = addColors ? getSmileyColor(range, idx) : "fill-none";
const activeColor = addColors ? getActiveSmileyColor(range, idx) : "fb-fill-rating-fill";
const inactiveColor = addColors ? getSmileyColor(range, idx) : "fb-fill-none";
const icons = [
<TiredFace className={active ? activeColor : inactiveColor} />,

View File

@@ -44,11 +44,11 @@ export const AutoCloseWrapper = ({ survey, onClose, children, offset }: AutoClos
}, [survey.autoClose]);
return (
<div className="h-full w-full">
<div className="fb-h-full fb-w-full">
{survey.autoClose && showAutoCloseProgressBar && (
<AutoCloseProgressBar autoCloseTimeout={survey.autoClose} />
)}
<div onClick={stopCountdown} onMouseOver={stopCountdown} className="h-full w-full">
<div onClick={stopCountdown} onMouseOver={stopCountdown} className="fb-h-full fb-w-full">
{children}
</div>
</div>

View File

@@ -45,17 +45,17 @@ export const Modal = ({ children, isOpen, placement, clickOutside, darkOverlay,
const getPlacementStyle = (placement: TPlacement) => {
switch (placement) {
case "bottomRight":
return "sm:bottom-3 sm:right-3";
return "sm:fb-bottom-3 sm:fb-right-3";
case "topRight":
return "sm:top-3 sm:right-3 sm:bottom-3";
return "sm:fb-top-3 sm:fb-right-3 sm:fb-bottom-3";
case "topLeft":
return "sm:top-3 sm:left-3 sm:bottom-3";
return "sm:fb-top-3 sm:fb-left-3 sm:fb-bottom-3";
case "bottomLeft":
return "sm:bottom-3 sm:left-3";
return "sm:fb-bottom-3 sm:fb-left-3";
case "center":
return "sm:top-1/2 sm:left-1/2 sm:transform sm:-translate-x-1/2 sm:-translate-y-1/2";
return "sm:fb-top-1/2 sm:fb-left-1/2 sm:fb-transform sm:-fb-translate-x-1/2 sm:-fb-translate-y-1/2";
default:
return "sm:bottom-3 sm:right-3";
return "sm:fb-bottom-3 sm:fb-right-3";
}
};
@@ -65,24 +65,24 @@ export const Modal = ({ children, isOpen, placement, clickOutside, darkOverlay,
<div
aria-live="assertive"
className={cn(
isCenter ? "pointer-events-auto" : "pointer-events-none",
"z-999999 fixed inset-0 flex items-end"
isCenter ? "fb-pointer-events-auto" : "fb-pointer-events-none",
"fb-z-999999 fb-fixed fb-inset-0 fb-flex fb-items-end"
)}>
<div
className={cn(
"relative h-full w-full",
"fb-relative fb-h-full fb-w-full",
isCenter
? darkOverlay
? "bg-gray-700/80"
: "bg-white/50"
: "bg-none transition-all duration-500 ease-in-out"
? "fb-bg-gray-700/80"
: "fb-bg-white/50"
: "fb-bg-none fb-transition-all fb-duration-500 fb-ease-in-out"
)}>
<div
ref={modalRef}
className={cn(
getPlacementStyle(placement),
show ? "opacity-100" : "opacity-0",
"rounded-custom pointer-events-auto absolute bottom-0 h-fit w-full overflow-visible bg-white shadow-lg transition-all duration-500 ease-in-out sm:m-4 sm:max-w-sm"
show ? "fb-opacity-100" : "fb-opacity-0",
"fb-rounded-custom fb-pointer-events-auto fb-absolute fb-bottom-0 fb-h-fit fb-w-full fb-overflow-visible fb-bg-white fb-shadow-lg fb-transition-all fb-duration-500 fb-ease-in-out sm:fb-m-4 sm:fb-max-w-sm"
)}>
<div>{children}</div>
</div>

View File

@@ -49,9 +49,9 @@ export const ScrollableContainer = ({ children }: ScrollableContainerProps) => {
}, [children]);
return (
<div className="relative">
<div className="fb-relative">
{!isAtTop && (
<div className="from-survey-bg absolute left-0 right-2 top-0 z-10 h-4 bg-gradient-to-b to-transparent"></div>
<div className="fb-from-survey-bg fb-absolute fb-left-0 fb-right-2 fb-top-0 fb-z-10 fb-h-4 fb-bg-gradient-to-b fb-to-transparent"></div>
)}
<div
ref={containerRef}
@@ -59,13 +59,16 @@ export const ScrollableContainer = ({ children }: ScrollableContainerProps) => {
scrollbarGutter: "stable both-edges",
maxHeight: isSurveyPreview ? "40dvh" : "60dvh",
}}
className={cn("overflow-auto px-4 pb-1", isOverflowHidden ? "no-scrollbar" : "bg-survey-bg")}
className={cn(
"fb-overflow-auto fb-px-4 fb-pb-1",
isOverflowHidden ? "fb-no-scrollbar" : "fb-bg-survey-bg"
)}
onMouseEnter={() => toggleOverflow(false)}
onMouseLeave={() => toggleOverflow(true)}>
{children}
</div>
{!isAtBottom && (
<div className="from-survey-bg absolute -bottom-2 left-0 right-2 h-8 bg-gradient-to-t to-transparent"></div>
<div className="fb-from-survey-bg fb-absolute -fb-bottom-2 fb-left-0 fb-right-2 fb-h-8 fb-bg-gradient-to-t fb-to-transparent"></div>
)}
</div>
);

View File

@@ -155,7 +155,7 @@ export const StackedCardsContainer = ({
return (
<div
className="relative flex h-full items-end justify-center md:items-center"
className="fb-relative fb-flex fb-h-full fb-items-end fb-justify-center md:fb-items-center"
onMouseEnter={() => {
setHovered(true);
}}
@@ -197,7 +197,7 @@ export const StackedCardsContainer = ({
...straightCardArrangementStyles(offset),
...getBottomStyles(),
}}
className="pointer rounded-custom bg-survey-bg absolute inset-x-0 backdrop-blur-md transition-all ease-in-out">
className="fb-pointer fb-rounded-custom fb-bg-survey-bg fb-absolute fb-inset-x-0 fb-backdrop-blur-md fb-transition-all fb-ease-in-out">
{getCardContent(questionIdxTemp, offset)}
</div>
);

View File

@@ -32,7 +32,7 @@
/* this is for styling the HtmlBody component */
.fb-htmlbody {
@apply block text-sm font-normal leading-6;
@apply fb-block fb-text-sm fb-font-normal fb-leading-6;
/* need to use !important because in packages/ui/components/editor/stylesEditorFrontend.css the color is defined for some classes */
color: var(--fb-subheading-color) !important;
}
@@ -106,7 +106,7 @@ p.fb-editor-paragraph {
}
}
.no-scrollbar {
.fb-no-scrollbar {
-ms-overflow-style: none !important; /* Internet Explorer 10+ */
scrollbar-width: thin !important; /* Firefox */
scrollbar-color: transparent transparent !important; /* Firefox */

View File

@@ -1,6 +1,7 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
important: "#fbjs",
prefix: "fb-",
darkMode: "class",
corePlugins: {
preflight: false,

41
pnpm-lock.yaml generated
View File

@@ -7543,6 +7543,11 @@ packages:
engines: {node: '>=16 || 14 >=14.18'}
hasBin: true
glob@10.4.2:
resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==}
engines: {node: '>=16 || 14 >=14.18'}
hasBin: true
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Glob versions prior to v9 are no longer supported
@@ -9265,6 +9270,9 @@ packages:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
package-json-from-dist@1.0.0:
resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
pako@0.2.9:
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
@@ -11875,8 +11883,8 @@ snapshots:
'@aws-crypto/sha1-browser': 5.2.0
'@aws-crypto/sha256-browser': 5.2.0
'@aws-crypto/sha256-js': 5.2.0
'@aws-sdk/client-sso-oidc': 3.600.0(aws-crt@1.21.3)
'@aws-sdk/client-sts': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/client-sso-oidc': 3.600.0(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/client-sts': 3.600.0(aws-crt@1.21.3)
'@aws-sdk/core': 3.598.0
'@aws-sdk/credential-provider-node': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/middleware-bucket-endpoint': 3.598.0
@@ -11933,11 +11941,11 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3)':
'@aws-sdk/client-sso-oidc@3.600.0(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)':
dependencies:
'@aws-crypto/sha256-browser': 5.2.0
'@aws-crypto/sha256-js': 5.2.0
'@aws-sdk/client-sts': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/client-sts': 3.600.0(aws-crt@1.21.3)
'@aws-sdk/core': 3.598.0
'@aws-sdk/credential-provider-node': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/middleware-host-header': 3.598.0
@@ -11976,6 +11984,7 @@ snapshots:
'@smithy/util-utf8': 3.0.0
tslib: 2.6.3
transitivePeerDependencies:
- '@aws-sdk/client-sts'
- aws-crt
'@aws-sdk/client-sso@3.598.0(aws-crt@1.21.3)':
@@ -12021,11 +12030,11 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@aws-sdk/client-sts@3.600.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)':
'@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3)':
dependencies:
'@aws-crypto/sha256-browser': 5.2.0
'@aws-crypto/sha256-js': 5.2.0
'@aws-sdk/client-sso-oidc': 3.600.0(aws-crt@1.21.3)
'@aws-sdk/client-sso-oidc': 3.600.0(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/core': 3.598.0
'@aws-sdk/credential-provider-node': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/middleware-host-header': 3.598.0
@@ -12064,7 +12073,6 @@ snapshots:
'@smithy/util-utf8': 3.0.0
tslib: 2.6.3
transitivePeerDependencies:
- '@aws-sdk/client-sso-oidc'
- aws-crt
'@aws-sdk/core@3.598.0':
@@ -12098,7 +12106,7 @@ snapshots:
'@aws-sdk/credential-provider-ini@3.598.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)':
dependencies:
'@aws-sdk/client-sts': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/client-sts': 3.600.0(aws-crt@1.21.3)
'@aws-sdk/credential-provider-env': 3.598.0
'@aws-sdk/credential-provider-http': 3.598.0
'@aws-sdk/credential-provider-process': 3.598.0
@@ -12156,7 +12164,7 @@ snapshots:
'@aws-sdk/credential-provider-web-identity@3.598.0(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))':
dependencies:
'@aws-sdk/client-sts': 3.600.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/client-sts': 3.600.0(aws-crt@1.21.3)
'@aws-sdk/types': 3.598.0
'@smithy/property-provider': 3.1.1
'@smithy/types': 3.1.0
@@ -12297,7 +12305,7 @@ snapshots:
'@aws-sdk/token-providers@3.598.0(@aws-sdk/client-sso-oidc@3.600.0(aws-crt@1.21.3))':
dependencies:
'@aws-sdk/client-sso-oidc': 3.600.0(aws-crt@1.21.3)
'@aws-sdk/client-sso-oidc': 3.600.0(@aws-sdk/client-sts@3.600.0(aws-crt@1.21.3))(aws-crt@1.21.3)
'@aws-sdk/types': 3.598.0
'@smithy/property-provider': 3.1.1
'@smithy/shared-ini-file-loader': 3.1.1
@@ -20541,6 +20549,15 @@ snapshots:
minipass: 7.1.2
path-scurry: 1.11.1
glob@10.4.2:
dependencies:
foreground-child: 3.2.1
jackspeak: 3.4.0
minimatch: 9.0.4
minipass: 7.1.2
package-json-from-dist: 1.0.0
path-scurry: 1.11.1
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
@@ -22720,6 +22737,8 @@ snapshots:
p-try@2.2.0: {}
package-json-from-dist@1.0.0: {}
pako@0.2.9: {}
papaparse@5.4.1: {}
@@ -24312,7 +24331,7 @@ snapshots:
dependencies:
'@jridgewell/gen-mapping': 0.3.5
commander: 4.1.1
glob: 10.4.1
glob: 10.4.2
lines-and-columns: 1.2.4
mz: 2.7.0
pirates: 4.0.6