fix: Mobile height inconsistencies (#2540)

Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
Johannes
2024-04-26 18:04:03 +02:00
committed by GitHub
parent 460c046f0a
commit a6568ea539
38 changed files with 171 additions and 142 deletions

View File

@@ -28,7 +28,7 @@ const DemoPreview: React.FC<DemoPreviewProps> = ({ template }) => {
<div className="flex items-center justify-center rounded-xl border-2 border-slate-300 bg-slate-200 py-6 transition-transform duration-150 dark:border-slate-500 dark:bg-slate-700">
<div className="flex flex-col items-center justify-around">
<p className="my-3 text-sm text-slate-500 dark:text-slate-300">Preview</p>
<div className="">
<div>
{selectedTemplate && (
<PreviewSurvey
activeQuestionId={activeQuestionId}

View File

@@ -36,7 +36,7 @@ export const GitHubSponsorship: React.FC = () => {
</p>
</div>
<div className="flex items-center justify-end">
{/* <Image src={PHIcon} alt="Product Hunt Logo" width={80} className="" /> */}
{/* <Image src={PHIcon} alt="Product Hunt Logo" width={80} /> */}
</div>
</div>
</Link>

View File

@@ -7,7 +7,7 @@ export default function HeadingCentered() {
const router = useRouter();
return (
<div className="mx-auto grid grid-cols-1 content-center gap-10 pb-12 pt-24 md:grid-cols-2">
<div className="">
<div>
<p className="text-md text-brand-dark dark:text-brand-light font-semibold uppercase">
What are you waiting for?
</p>

View File

@@ -7,7 +7,7 @@ export default function HeadingCentered() {
const router = useRouter();
return (
<div className="mx-auto grid max-w-md grid-cols-1 content-center gap-10 px-4 py-12 sm:max-w-3xl sm:px-6 md:grid-cols-2 md:pb-36 md:pt-24 lg:max-w-6xl lg:px-8">
<div className="">
<div>
<p className="text-md text-brand-dark dark:text-brand-light mb-3 font-semibold uppercase">
What are you waiting for?
</p>

View File

@@ -13,7 +13,7 @@ export default function Layout({ title, description, children }: LayoutProps) {
<div className="mx-auto bg-gradient-to-br from-slate-800 via-slate-900 to-slate-900">
<MetaInformation title={title} description={description} />
<HeaderTribe />
<main className="">{children}</main>
<main>{children}</main>
<Footer />
</div>
);

View File

@@ -562,15 +562,15 @@ export default function FormTribeHackathon() {
<div className="max-w-8xl mt-8 grid grid-cols-3 gap-4 px-56">
<div className="px-8">
<p className="h-0 text-lg font-bold text-slate-300">+ Sticker Set</p>
<Image src={ArrowSticker} alt="rookie batch" className="" />
<Image src={ArrowSticker} alt="rookie batch" />
</div>
<div className="px-8">
<p className="h-0 text-lg font-bold text-slate-300">+ Hoodie</p>
<Image src={HoodieSticker} alt="rookie batch" className="" />
<Image src={HoodieSticker} alt="rookie batch" />
</div>
<div className="px-8">
<p className="h-0 text-lg font-bold text-slate-300">+ Handmade Gift</p>
<Image src={ArrowGift} alt="rookie batch" className="" />
<Image src={ArrowGift} alt="rookie batch" />
</div>
</div>
</div>
@@ -754,7 +754,7 @@ export default function FormTribeHackathon() {
</div>
{FAQ.map((question) => (
<div key={question.question} className="">
<div key={question.question}>
<div>
<h3 className="mt-6 text-lg font-bold text-slate-700">{question.question} </h3>
<p className="text-slate-600">{question.answer}</p>

View File

@@ -415,7 +415,7 @@ export default function LinkSurveyPage() {
headline="Try THE open source form builder 💪"
subheadline="Convinced that Formbricks is a good open source Typeform alternative? Try it now!"
/>
<div className="">
<div>
<HeadingCentered
heading="All form builder features"
teaser="Build open source forms like never before"
@@ -440,7 +440,7 @@ export default function LinkSurveyPage() {
imgAlt="Peer Richelsen, Co-Founder and CEO of Cal.com"
textSize="large"
/>
<div className="">
<div>
<HeadingCentered heading="All question types included" teaser="A complete open source form builder" />
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{allQuestionTypes.map((feature) => {

View File

@@ -266,7 +266,7 @@ export default function WebsiteSurveyPage() {
headline="All clear? Run your first website survey 👉"
subheadline="Targeted website surveys, all privacy-first. Run professional research without compromising data privacy."
/>
<div className="">
<div>
<HeadingCentered
heading={
<span>

View File

@@ -41,7 +41,7 @@ export default function AttributeSettingsTab({ attributeClass, setOpen }: Attrib
return (
<div>
<form className="space-y-4" onSubmit={handleSubmit(onSubmit)}>
<div className="">
<div>
<Label className="text-slate-600">Name</Label>
<Input
type="text"
@@ -51,7 +51,7 @@ export default function AttributeSettingsTab({ attributeClass, setOpen }: Attrib
})}
/>
</div>
<div className="">
<div>
<Label className="text-slate-600">Description</Label>
<Input
type="text"

View File

@@ -393,7 +393,7 @@ export default function Navigation({
<DropdownMenuSubTrigger>
<div>
<div className="flex items-center space-x-1">
<p className="">{truncate(product!.name, 20)}</p>
<p>{truncate(product!.name, 20)}</p>
{!widgetSetupCompleted && (
<TooltipProvider delayDuration={50}>
<Tooltip>

View File

@@ -96,7 +96,7 @@ export default function EditAPIKeys({
<div className="col-span-4 sm:col-span-2">Label</div>
<div className="col-span-4 hidden sm:col-span-5 sm:block">API Key</div>
<div className="col-span-4 sm:col-span-2">Created at</div>
<div className=""></div>
<div></div>
</div>
<div className="grid-cols-9">
{apiKeysLocal && apiKeysLocal.length === 0 ? (

View File

@@ -52,7 +52,7 @@ export default function EditAlerts({
<Tooltip>
<TooltipTrigger>
<div className="col-span-1 flex cursor-default items-center justify-center space-x-2">
<span className="">Every Response</span>
<span>Every Response</span>
<HelpCircleIcon className="h-4 w-4 flex-shrink-0 text-slate-500" />
</div>
</TooltipTrigger>

View File

@@ -124,7 +124,7 @@ export const ShareEmbedSurvey = ({ survey, open, setOpen, webAppUrl, user }: Sha
))}
</div>
<div className="col-span-4 h-full overflow-y-auto bg-slate-50 px-4 py-6 lg:col-span-3 lg:p-6">
<div className="">
<div>
{activeId === "email" ? (
<EmailTab surveyId={survey.id} email={email} />
) : activeId === "webpage" ? (

View File

@@ -107,7 +107,7 @@ export default function EmailTab({ surveyId, email }: EmailTabProps) {
<div className="h-3 w-3 rounded-full bg-amber-500"></div>
<div className="h-3 w-3 rounded-full bg-emerald-500"></div>
</div>
<div className="">
<div>
<div className="mb-2 border-b border-slate-200 pb-2 text-sm">To : {email || "user@mail.com"}</div>
<div className="border-b border-slate-200 pb-2 text-sm">
Subject : Formbricks Email Survey Preview

View File

@@ -61,7 +61,7 @@ export default function LinkTab({ survey, webAppUrl, surveyUrl, setSurveyUrl }:
))}
</div>
</div>
<div className="">
<div>
<p className="mb-2 pt-2 font-semibold text-slate-700">Survey link got too long? Shorten it!</p>
<div className="rounded-md border border-slate-200 bg-white">
<UrlShortenerForm webAppUrl={webAppUrl} />

View File

@@ -17,7 +17,7 @@ export default function WebpageTab({ surveyUrl }) {
return (
<div className="flex h-full grow flex-col">
<div className="flex justify-between">
<div className=""></div>
<div></div>
<Button
variant="darkCTA"
title="Embed survey in your website"

View File

@@ -156,14 +156,15 @@ export const MatrixQuestionForm = ({
</div>
))}
<Button
variant="minimal"
className="mt-2 space-x-2"
variant="secondary"
size="sm"
className="mt-3"
StartIcon={PlusIcon}
onClick={(e) => {
e.preventDefault();
handleAddLabel("row");
}}>
<PlusIcon className="h-4 w-4" />
<span>Add Row</span>
<span>Add row</span>
</Button>
</div>
</div>
@@ -195,14 +196,15 @@ export const MatrixQuestionForm = ({
</div>
))}
<Button
variant="minimal"
className="mt-2 space-x-2"
variant="secondary"
size="sm"
className="mt-3"
StartIcon={PlusIcon}
onClick={(e) => {
e.preventDefault();
handleAddLabel("column");
}}>
<PlusIcon className="h-4 w-4" />
<span>Add Column</span>
<span>Add column</span>
</Button>
</div>
</div>

View File

@@ -127,7 +127,7 @@ export default function RecontactOptionsCard({
id={option.name}
className="aria-checked:border-brand-dark mx-5 disabled:border-slate-400 aria-checked:border-2"
/>
<div className="">
<div>
<p className="font-semibold text-slate-700">{option.name}</p>
<p className="mt-2 text-xs font-normal text-slate-600">{option.description}</p>
@@ -188,7 +188,7 @@ export default function RecontactOptionsCard({
id="newDays"
className="aria-checked:border-brand-dark mx-4 disabled:border-slate-400 aria-checked:border-2"
/>
<div className="">
<div>
<p className="text-sm font-semibold text-slate-700">
Wait
<Input

View File

@@ -322,7 +322,7 @@ export default function WhenToSendCard({
<label
htmlFor="triggerDelay"
className="flex w-full cursor-pointer items-center rounded-lg border bg-slate-50 p-4">
<div className="">
<div>
<p className="text-sm font-semibold text-slate-700">
Wait
<Input

View File

@@ -52,7 +52,7 @@ export default function SetupInstructionsOnboarding({
))}
</nav>
</div>
<div className="">
<div>
{activeTab === "npm" ? (
<div className="prose prose-slate">
<CodeBlock customEditorClass="!bg-white border border-slate-200" language="sh">

View File

@@ -15,7 +15,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return (
<html lang="en">
{process.env.VERCEL === "1" && <SpeedInsights sampleRate={0.1} />}
<body className="flex h-screen flex-col">{children}</body>
<body className="flex h-dvh flex-col">{children}</body>
</html>
);
}

View File

@@ -118,9 +118,9 @@ export default function LinkSurvey({
setAutofocus(true);
}
// For safari on mobile devices, scroll is a bit off due to dynamic height of address bar, so on inital load, we scroll to the bottom
window.scrollTo({
top: document.body.scrollHeight,
});
// window.scrollTo({
// top: document.body.scrollHeight,
// });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
@@ -185,7 +185,7 @@ export default function LinkSurvey({
};
return (
<div className="flex h-screen items-end justify-center md:items-center">
<div className="flex max-h-dvh min-h-dvh items-end justify-center overflow-clip md:items-center">
{!determineStyling().isLogoHidden && product.logo?.url && <ClientLogo product={product} />}
<ContentWrapper className="w-full p-0 md:max-w-md">
{isPreview && (

View File

@@ -116,28 +116,25 @@ export const MediaBackground: React.FC<MediaBackgroundProps> = ({
<div
className={`${baseClasses} ${loadedClass} bg-cover bg-center`}
style={{ backgroundImage: `url(${background?.bg})`, filter: `${filterStyle}` }}></div>
<div className={`absolute bottom-6 z-10 h-12 w-full lg:bottom-0`}>
<div className="mx-auto max-w-full p-3 text-center text-xs text-slate-400 lg:text-right">
{authorDetailsForUnsplash.authorName && (
<div className="ml-auto w-max">
<span>Photo by </span>
<Link
href={authorDetailsForUnsplash.authorURL + "?utm_source=formbricks&utm_medium=referral"}
target="_blank"
className="hover:underline">
{authorDetailsForUnsplash.authorName}
</Link>
<span> on </span>
<Link
href="https://unsplash.com/?utm_source=formbricks&utm_medium=referral"
target="_blank"
className="hover:underline">
Unsplash
</Link>
</div>
)}
{authorDetailsForUnsplash.authorName && (
<div className="absolute bottom-4 right-6 z-10 ml-auto hidden w-max text-xs text-slate-400 md:block">
<span>Photo by </span>
<Link
href={authorDetailsForUnsplash.authorURL + "?utm_source=formbricks&utm_medium=referral"}
target="_blank"
className="hover:underline">
{authorDetailsForUnsplash.authorName}
</Link>
<span> on </span>
<Link
href="https://unsplash.com/?utm_source=formbricks&utm_medium=referral"
target="_blank"
className="hover:underline">
Unsplash
</Link>
</div>
</div>
)}
</>
);
case "upload":
@@ -178,7 +175,7 @@ export const MediaBackground: React.FC<MediaBackgroundProps> = ({
);
} else {
return (
<div className="flex min-h-screen flex-col items-center justify-center">
<div className="flex min-h-dvh flex-col items-center justify-center">
{renderBackground()}
<div className="relative w-full">{children}</div>
</div>

View File

@@ -1,3 +1,3 @@
export default async function SurveyLayout({ children }) {
return <div className="h-full">{children}</div>;
return <div className="h-dvh">{children}</div>;
}

View File

@@ -1,9 +1,29 @@
const monthNames = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
// Helper function to calculate difference in days between two dates
export const diffInDays = (date1: Date, date2: Date) => {
const diffTime = Math.abs(date2.getTime() - date1.getTime());
return Math.floor(diffTime / (1000 * 60 * 60 * 24));
};
// Helper function to get the month name
export const getMonthName = (monthIndex: number) => {
return monthNames[monthIndex];
};
export const formatDateWithOrdinal = (date: Date): string => {
const getOrdinalSuffix = (day: number) => {
const suffixes = ["th", "st", "nd", "rd"];
@@ -12,20 +32,6 @@ export const formatDateWithOrdinal = (date: Date): string => {
};
const dayOfWeekNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const monthNames = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
const dayOfWeek = dayOfWeekNames[date.getDay()];
const day = date.getDate();
@@ -35,6 +41,22 @@ export const formatDateWithOrdinal = (date: Date): string => {
return `${dayOfWeek}, ${monthNames[monthIndex]} ${day}${getOrdinalSuffix(day)}, ${year}`;
};
// Helper function to format the date with an ordinal suffix
export const getOrdinalDate = (date: number) => {
const j = date % 10,
k = date % 100;
if (j === 1 && k !== 11) {
return date + "st";
}
if (j === 2 && k !== 12) {
return date + "nd";
}
if (j === 3 && k !== 13) {
return date + "rd";
}
return date + "th";
};
export function isValidDateString(value: string) {
const regex = /^(?:\d{4}-\d{2}-\d{2}|\d{2}-\d{2}-\d{4})$/;

View File

@@ -49,7 +49,7 @@ export default function CalEmbed({ question, onSuccessfulBooking }: CalEmbedProp
}, [cal, question.calUserName]);
return (
<div className="relative mt-4 max-h-[33vh] overflow-auto">
<div className="relative mt-4 overflow-auto">
<div id="fb-cal-embed" className={cn("border-border rounded-lg border")} />
</div>
);

View File

@@ -209,7 +209,7 @@ export default function 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`}>
<div className="max-h-[30vh] overflow-auto">
<div>
{fileUrls &&
fileUrls?.map((file, index) => {
const fileName = getOriginalFileNameFromUrl(file);

View File

@@ -63,42 +63,44 @@ export const ConsentQuestion = ({
htmlString={getLocalizedValue(question.html, languageCode) || ""}
questionId={question.id}
/>
<label
tabIndex={1}
id={`${question.id}-label`}
onKeyDown={(e) => {
// Accessibility: if spacebar was pressed pass this down to the input
if (e.key === " ") {
e.preventDefault();
document.getElementById(question.id)?.click();
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 mt-4 flex w-full cursor-pointer items-center border p-4 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2">
<input
type="checkbox"
id={question.id}
name={question.id}
value={getLocalizedValue(question.label, languageCode)}
onChange={(e) => {
if (e.target instanceof HTMLInputElement && e.target.checked) {
onChange({ [question.id]: "accepted" });
} else {
onChange({ [question.id]: "dismissed" });
<div className="bg-survey-bg sticky -bottom-2 z-10 w-full px-1 py-1">
<label
tabIndex={1}
id={`${question.id}-label`}
onKeyDown={(e) => {
// Accessibility: if spacebar was pressed pass this down to the input
if (e.key === " ") {
e.preventDefault();
document.getElementById(question.id)?.click();
document.getElementById(`${question.id}-label`)?.focus();
}
}}
checked={value === "accepted"}
className="border-brand text-brand h-4 w-4 border focus:ring-0 focus:ring-offset-0"
aria-labelledby={`${question.id}-label`}
required={question.required}
/>
<span id={`${question.id}-label`} className="ml-3 font-medium">
{getLocalizedValue(question.label, languageCode)}
</span>
</label>
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">
<input
type="checkbox"
id={question.id}
name={question.id}
value={getLocalizedValue(question.label, languageCode)}
onChange={(e) => {
if (e.target instanceof HTMLInputElement && e.target.checked) {
onChange({ [question.id]: "accepted" });
} else {
onChange({ [question.id]: "dismissed" });
}
}}
checked={value === "accepted"}
className="border-brand text-brand h-4 w-4 border focus:ring-0 focus:ring-offset-0"
aria-labelledby={`${question.id}-label`}
required={question.required}
/>
<span id={`${question.id}-label`} className="ml-3 font-medium">
{getLocalizedValue(question.label, languageCode)}
</span>
</label>
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6 py-4">
{!isFirstQuestion && (
<BackButton

View File

@@ -112,10 +112,10 @@ export const DateQuestion = ({
<span>{errorMessage}</span>
</div>
<div
className={cn("mt-4", errorMessage && "rounded-lg border-2 border-red-500")}
className={cn("mt-4 w-full", errorMessage && "rounded-lg border-2 border-red-500")}
id="date-picker-root">
{loading && (
<div className="bg-survey-bg border-border text-placeholder relative flex h-12 w-full cursor-pointer appearance-none items-center justify-center rounded-lg border text-left text-base font-normal focus:outline-none focus:ring-2 focus:ring-neutral-900 focus:ring-offset-1">
<div className="bg-survey-bg border-border text-placeholder relative flex h-16 w-full cursor-pointer appearance-none items-center justify-center rounded-lg border text-left text-base font-normal focus:outline-none focus:ring-2 focus:ring-neutral-900 focus:ring-offset-1">
<span
className="h-6 w-6 animate-spin rounded-full border-b-2 border-neutral-900"
style={{ borderTopColor: "transparent" }}></span>

View File

@@ -104,7 +104,7 @@ export const MatrixQuestion = ({
subheader={getLocalizedValue(question.subheader, languageCode)}
questionId={question.id}
/>
<div className="overflow-x-auto">
<div className="overflow-x-auto py-4">
<table className="no-scrollbar min-w-full table-auto border-collapse text-sm">
<thead>
<tr>
@@ -154,7 +154,7 @@ export const MatrixQuestion = ({
</div>
</div>
</ScrollableContainer>
<div className="flex w-full justify-between px-6">
<div className="flex w-full justify-between px-6 py-4">
{!isFirstQuestion && (
<BackButton
backButtonLabel={getLocalizedValue(question.backButtonLabel, languageCode)}

View File

@@ -109,7 +109,7 @@ export const PictureSelectionQuestion = ({
<div className="mt-4">
<fieldset>
<legend className="sr-only">Options</legend>
<div className="rounded-m bg-survey-bg relative grid max-h-[33vh] grid-cols-2 gap-x-5 gap-y-4 overflow-y-auto">
<div className="bg-survey-bg relative grid grid-cols-2 gap-x-5 gap-y-4">
{questionChoices.map((choice, idx) => (
<label
key={choice.id}
@@ -128,7 +128,7 @@ export const PictureSelectionQuestion = ({
Array.isArray(value) && value.includes(choice.id)
? `border-brand text-brand z-10 border-4 shadow-xl`
: "",
"focus:border-brand group/image relative inline-block h-28 w-full cursor-pointer overflow-hidden rounded-xl border focus:border-4 focus:outline-none"
"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"
)}>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
@@ -170,7 +170,7 @@ 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 border",
"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" : ""
)}
required={question.required && value.length ? false : question.required}

View File

@@ -24,7 +24,7 @@ export const ScrollableContainer = ({ children }: ScrollableContainerProps) => {
const toggleOverflow = (hide: boolean) => {
if (timeoutRef.current) clearTimeout(timeoutRef.current);
if (hide) {
timeoutRef.current = setTimeout(() => setIsOverflowHidden(true), 1500);
timeoutRef.current = setTimeout(() => setIsOverflowHidden(true), 1000);
} else {
setIsOverflowHidden(false);
checkScroll();
@@ -55,10 +55,10 @@ export const ScrollableContainer = ({ children }: ScrollableContainerProps) => {
<div
ref={containerRef}
style={{
scrollbarGutter: "stable",
maxHeight: isSurveyPreview ? "41vh" : "60vh",
scrollbarGutter: "stable both-edges",
maxHeight: isSurveyPreview ? "40dvh" : "60dvh",
}}
className={`overflow-${isOverflowHidden ? "hidden" : "auto"} pb-1 pl-6 pr-4`}
className={`overflow-${isOverflowHidden ? "hidden" : "auto"} px-4 pb-1`}
onMouseEnter={() => toggleOverflow(false)}
onTouchStart={() => toggleOverflow(false)}
onTouchEnd={() => toggleOverflow(true)}

View File

@@ -1,6 +1,8 @@
import { useEffect, useMemo, useState } from "preact/hooks";
import DatePicker from "react-date-picker";
import { getMonthName, getOrdinalDate } from "@formbricks/lib/utils/datetime";
const CalendarIcon = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -72,23 +74,19 @@ export default function Question({ defaultDate, format }: { defaultDate?: Date;
const formattedDate = useMemo(() => {
if (!selectedDate) return "";
if (format === "M-d-y") {
return `${selectedDate?.getMonth() + 1}-${selectedDate?.getDate()}-${selectedDate?.getFullYear()}`;
}
const day = selectedDate.getDate();
const monthIndex = selectedDate.getMonth();
const year = selectedDate.getFullYear();
if (format === "d-M-y") {
return `${selectedDate?.getDate()}-${selectedDate?.getMonth() + 1}-${selectedDate?.getFullYear()}`;
}
return `${selectedDate?.getFullYear()}-${selectedDate?.getMonth() + 1}-${selectedDate?.getDate()}`;
}, [format, selectedDate]);
return `${getOrdinalDate(day)} of ${getMonthName(monthIndex)}, ${year}`;
}, [selectedDate]);
return (
<div className="relative h-40">
<div className="relative">
{!datePickerOpen && (
<div
onClick={() => setDatePickerOpen(true)}
className="bg-input-bg hover:bg-input-bg-selected border-border text-placeholder relative flex h-40 w-full cursor-pointer appearance-none items-center justify-center rounded-lg border text-left text-base font-normal focus:outline-none focus:ring-2 focus:ring-neutral-900 focus:ring-offset-1">
className="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 focus:outline-none focus:ring-2 focus:ring-neutral-900 focus:ring-offset-1">
<div className="flex items-center gap-2">
{selectedDate ? (
<div className="flex items-center gap-2">
@@ -119,10 +117,10 @@ export default function Question({ defaultDate, format }: { defaultDate?: Date;
monthPlaceholder="MM"
yearPlaceholder="YYYY"
format={format ?? "M-d-y"}
className={`dp-input-root rounded-custom ${!datePickerOpen ? "wrapper-hide" : ""}
className={`dp-input-root rounded-custom wrapper-hide ${!datePickerOpen ? "" : "h-[46dvh] sm:h-[34dvh]"}
${hideInvalid ? "hide-invalid" : ""}
`}
calendarClassName="calendar-root w-80 rounded-lg border border-[#e5e7eb] p-3 shadow-md h-40 overflow-auto"
calendarClassName="calendar-root !bg-input-bg border border-border rounded-custom p-3 h-[46dvh] sm:h-[33dvh] overflow-auto"
clearIcon={null}
onCalendarOpen={() => {
setDatePickerOpen(true);
@@ -136,14 +134,14 @@ export default function Question({ defaultDate, format }: { defaultDate?: Date;
calendarIcon={<CalendarIcon />}
tileClassName={({ date }) => {
const baseClass =
"hover:bg-slate-200 rounded-md h-9 p-0 mt-1 font-normal text-slate-900 aria-selected:opacity-100";
"hover:bg-input-bg-selected rounded-custom h-9 p-0 mt-1 font-normal text-heading aria-selected:opacity-100";
// today's date class
if (
date.getDate() === new Date().getDate() &&
date.getMonth() === new Date().getMonth() &&
date.getFullYear() === new Date().getFullYear()
) {
return `${baseClass} bg-slate-100`;
return `${baseClass} border border-input-border`;
}
// active date class
if (
@@ -151,7 +149,7 @@ export default function Question({ defaultDate, format }: { defaultDate?: Date;
date.getMonth() === selectedDate?.getMonth() &&
date.getFullYear() === selectedDate?.getFullYear()
) {
return `${baseClass} !bg-slate-900 !text-slate-100`;
return `${baseClass} !bg-accent-selected-bg !border-border-highlight !text-heading`;
}
return baseClass;
@@ -159,6 +157,7 @@ export default function Question({ defaultDate, format }: { defaultDate?: Date;
formatShortWeekday={(_, date) => {
return date.toLocaleDateString("en-US", { weekday: "short" }).slice(0, 2);
}}
navi
showNeighboringMonth={false}
showLeadingZeros={false}
/>

View File

@@ -50,12 +50,14 @@
.react-date-picker__calendar--open {
position: absolute !important;
top: 0 !important;
width: 100% !important;
}
.calendar-root {
position: absolute !important;
top: 0 !important;
background: var(--fb-survey-background-color) !important;
width: 100% !important;
}
.calendar-root [class$="navigation"] {

View File

@@ -11,8 +11,8 @@
/* Chrome, Edge, and Safari */
#fbjs *::-webkit-scrollbar {
width: 8px ;
background: transparent ;
width: 6px;
background: transparent;
}
#fbjs *::-webkit-scrollbar-track {
@@ -25,6 +25,12 @@
border-radius: 10px
}
/* Firefox */
#fbjs * {
scrollbar-width: thin;
scrollbar-color: var(--fb-brand-color) transparent;
}
/* this is for styling the HtmlBody component */
.fb-htmlbody {

View File

@@ -16,7 +16,7 @@ interface ClientLogoProps {
export const ClientLogo = ({ environmentId, product, previewSurvey = false }: ClientLogoProps) => {
return (
<div
className={cn(previewSurvey ? "" : "left-5 top-5 md:left-7 md:top-7", "group fixed z-0 rounded-lg")}
className={cn(previewSurvey ? "" : "left-3 top-3 md:left-7 md:top-7", "group fixed z-0 rounded-lg")}
style={{ backgroundColor: product.logo?.bgColor }}>
{previewSurvey && environmentId && (
<Link

View File

@@ -34,7 +34,6 @@ const CodeBlock: React.FC<CodeBlockProps> = ({
{showCopyToClipboard && (
<div className="absolute right-2 top-2 z-20 h-8 w-8 cursor-pointer rounded-md bg-slate-100 p-1.5 text-slate-600 hover:bg-slate-200">
<CopyIcon
className=""
onClick={() => {
const childText = children?.toString() || "";
navigator.clipboard.writeText(childText);

View File

@@ -203,11 +203,11 @@ export const FileInput: React.FC<FileInputProps> = ({
return (
<div className="w-full cursor-default">
<div className="">
<div>
{isVideoAllowed && (
<TabBar tabs={tabs} activeId={activeTab} setActiveId={setActiveTab} tabStyle="button" />
)}
<div className="">
<div>
{activeTab === "video" && (
<div className={cn(isVideoAllowed && "rounded-b-lg border-x border-b border-slate-200 p-4")}>
<VideoSettings