[CAL-1095] Embed modal (floating pop up button) - UI/layout/spacing issues (#8217)
* [CAL-1095] Embed modal (floating pop up button) - UI/layout/spacing issues * requested changes --------- Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: Keith Williams <keithwillcode@gmail.com>tweak/eslint-disable-exhaustive-deps^2
parent
5672a721d9
commit
4f466fd95d
|
@ -1,5 +1,6 @@
|
|||
import { Collapsible, CollapsibleContent } from "@radix-ui/react-collapsible";
|
||||
import classNames from "classnames";
|
||||
import type { TFunction } from "next-i18next";
|
||||
import type { NextRouter } from "next/router";
|
||||
import { useRouter } from "next/router";
|
||||
import type { MutableRefObject, RefObject } from "react";
|
||||
|
@ -21,11 +22,10 @@ import {
|
|||
TextArea,
|
||||
TextField,
|
||||
ColorPicker,
|
||||
Select,
|
||||
} from "@calcom/ui";
|
||||
import { Code, Trello, Sun, ArrowLeft } from "@calcom/ui/components/icon";
|
||||
|
||||
import Select from "@components/ui/form/Select";
|
||||
|
||||
type EmbedType = "inline" | "floating-popup" | "element-click";
|
||||
type EmbedFramework = "react" | "HTML";
|
||||
|
||||
|
@ -305,15 +305,12 @@ const getEmbedTypeSpecificString = ({
|
|||
return "";
|
||||
};
|
||||
|
||||
const embeds: {
|
||||
illustration: React.ReactElement;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
type: EmbedType;
|
||||
}[] = [
|
||||
const embeds = (t: TFunction) =>
|
||||
(() => {
|
||||
return [
|
||||
{
|
||||
title: "Inline Embed",
|
||||
subtitle: "Loads your event type directly inline with your other website content.",
|
||||
title: t("inline_embed"),
|
||||
subtitle: t("load_inline_content"),
|
||||
type: "inline",
|
||||
illustration: (
|
||||
<svg
|
||||
|
@ -385,8 +382,8 @@ const embeds: {
|
|||
),
|
||||
},
|
||||
{
|
||||
title: "Floating pop-up button",
|
||||
subtitle: "Adds a floating button on your site that launches Cal in a dialog.",
|
||||
title: t("floating_pop_up_button"),
|
||||
subtitle: t("floating_button_trigger_modal"),
|
||||
type: "floating-popup",
|
||||
illustration: (
|
||||
<svg
|
||||
|
@ -411,8 +408,8 @@ const embeds: {
|
|||
),
|
||||
},
|
||||
{
|
||||
title: "Pop up via element click",
|
||||
subtitle: "Open your Cal dialog when someone clicks an element.",
|
||||
title: t("pop_up_element_click"),
|
||||
subtitle: t("open_dialog_with_element_click"),
|
||||
type: "element-click",
|
||||
illustration: (
|
||||
<svg
|
||||
|
@ -488,7 +485,9 @@ const embeds: {
|
|||
</svg>
|
||||
),
|
||||
},
|
||||
];
|
||||
];
|
||||
})();
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
name: "HTML",
|
||||
|
@ -534,11 +533,7 @@ ${getEmbedTypeSpecificString({ embedFramework: "HTML", embedType, calLink, previ
|
|||
<!-- Cal ${embedType} embed code ends -->`
|
||||
}
|
||||
/>
|
||||
<p className="text-subtle hidden text-sm">
|
||||
{t(
|
||||
"Need help? See our guides for embedding Cal on Wix, Squarespace, or WordPress, check our common questions, or explore advanced embed options."
|
||||
)}
|
||||
</p>
|
||||
<p className="text-subtle hidden text-sm">{t("need_help_embedding")}</p>
|
||||
</>
|
||||
);
|
||||
}),
|
||||
|
@ -622,7 +617,7 @@ Cal("init", {origin:"${WEBAPP_URL}"});
|
|||
const ThemeSelectControl = ({ children, ...props }: ControlProps<{ value: Theme; label: string }, false>) => {
|
||||
return (
|
||||
<components.Control {...props}>
|
||||
<Sun className="text-subtle ml-2 h-4 w-4" />
|
||||
<Sun className="text-subtle mr-2 h-4 w-4" />
|
||||
{children}
|
||||
</components.Control>
|
||||
);
|
||||
|
@ -642,7 +637,7 @@ const ChooseEmbedTypesDialogContent = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="items-start space-y-2 md:flex md:space-y-0">
|
||||
{embeds.map((embed, index) => (
|
||||
{embeds(t).map((embed, index) => (
|
||||
<button
|
||||
className="hover:bg-subtle bg-muted w-full rounded-md border border-transparent p-6 text-left hover:rounded-md ltr:mr-4 ltr:last:mr-0 rtl:ml-4 rtl:last:ml-0 lg:w-1/3"
|
||||
key={index}
|
||||
|
@ -692,7 +687,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
});
|
||||
|
||||
const refOfEmbedCodesRefs = useRef(embedCodeRefs);
|
||||
const embed = embeds.find((embed) => embed.type === embedType);
|
||||
const embed = embeds(t).find((embed) => embed.type === embedType);
|
||||
|
||||
const [isEmbedCustomizationOpen, setIsEmbedCustomizationOpen] = useState(true);
|
||||
const [isBookingCustomizationOpen, setIsBookingCustomizationOpen] = useState(true);
|
||||
|
@ -806,11 +801,11 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
const FloatingPopupPositionOptions = [
|
||||
{
|
||||
value: "bottom-right",
|
||||
label: "Bottom Right",
|
||||
label: "Bottom right",
|
||||
},
|
||||
{
|
||||
value: "bottom-left",
|
||||
label: "Bottom Left",
|
||||
label: "Bottom left",
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -834,7 +829,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
</button>
|
||||
{embed.title}
|
||||
</h3>
|
||||
<h4 className="text-emphasis mb-6 text-sm font-normal">{embed.subtitle}</h4>
|
||||
<h4 className="text-subtle mb-6 text-sm font-normal">{embed.subtitle}</h4>
|
||||
<div className="flex flex-col">
|
||||
<div className={classNames("font-medium", embedType === "element-click" ? "hidden" : "")}>
|
||||
<Collapsible
|
||||
|
@ -844,7 +839,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
<div className={classNames(embedType === "inline" ? "block" : "hidden")}>
|
||||
{/*TODO: Add Auto/Fixed toggle from Figma */}
|
||||
<div className="text-default mb-[9px] text-sm">Window sizing</div>
|
||||
<div className="justify-left flex items-center !font-normal">
|
||||
<div className="justify-left mb-6 flex items-center !font-normal ">
|
||||
<div className="mr-[9px]">
|
||||
<TextField
|
||||
labelProps={{ className: "hidden" }}
|
||||
|
@ -892,10 +887,10 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
"mt-4 items-center justify-between",
|
||||
"items-center justify-between",
|
||||
embedType === "floating-popup" ? "text-emphasis" : "hidden"
|
||||
)}>
|
||||
<div className="mb-2 text-sm">Button Text</div>
|
||||
<div className="mb-2 text-sm">Button text</div>
|
||||
{/* Default Values should come from preview iframe */}
|
||||
<TextField
|
||||
labelProps={{ className: "hidden" }}
|
||||
|
@ -910,7 +905,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
};
|
||||
});
|
||||
}}
|
||||
defaultValue="Book my Cal"
|
||||
defaultValue={t("book_my_cal")}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
@ -935,14 +930,14 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
});
|
||||
}}
|
||||
/>
|
||||
<div className="text-default text-sm">Display Calendar Icon Button</div>
|
||||
<div className="text-default my-2 text-sm">Display calendar icon</div>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
"mt-4 items-center justify-between",
|
||||
embedType === "floating-popup" ? "text-emphasis" : "hidden"
|
||||
)}>
|
||||
<div className="mb-2">Position of Button</div>
|
||||
<div className="mb-2">Position of button</div>
|
||||
<Select
|
||||
onChange={(position) => {
|
||||
setPreviewState((previewState) => {
|
||||
|
@ -959,14 +954,12 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
options={FloatingPopupPositionOptions}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
"mt-4",
|
||||
embedType === "floating-popup" ? "text-emphasis" : "hidden"
|
||||
)}>
|
||||
<div>Button Color</div>
|
||||
<div className="w-full">
|
||||
<div className="mt-3 flex flex-col xl:flex-row xl:justify-between">
|
||||
<div className={classNames("mt-4", embedType === "floating-popup" ? "" : "hidden")}>
|
||||
<div className="whitespace-nowrap">Button color</div>
|
||||
<div className="mt-2 w-40 xl:mt-0 xl:w-full">
|
||||
<ColorPicker
|
||||
className="w-[130px]"
|
||||
popoverAlign="start"
|
||||
container={dialogContentRef?.current ?? undefined}
|
||||
defaultValue="#000000"
|
||||
|
@ -984,14 +977,11 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
"mt-4",
|
||||
embedType === "floating-popup" ? "text-emphasis" : "hidden"
|
||||
)}>
|
||||
<div>Text Color</div>
|
||||
<div className="w-full">
|
||||
<div className={classNames("mt-4", embedType === "floating-popup" ? "" : "hidden")}>
|
||||
<div className="whitespace-nowrap">Text color</div>
|
||||
<div className="mt-2 mb-6 w-40 xl:mt-0 xl:w-full">
|
||||
<ColorPicker
|
||||
className="w-[130px]"
|
||||
popoverAlign="start"
|
||||
container={dialogContentRef?.current ?? undefined}
|
||||
defaultValue="#000000"
|
||||
|
@ -1009,6 +999,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
</div>
|
||||
|
@ -1017,7 +1008,30 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
open={isBookingCustomizationOpen}
|
||||
onOpenChange={() => setIsBookingCustomizationOpen((val) => !val)}>
|
||||
<CollapsibleContent>
|
||||
<div className="mt-6 text-sm">
|
||||
<div className="text-sm">
|
||||
<Label className="mb-6">
|
||||
<div className="mb-2">Theme</div>
|
||||
<Select
|
||||
className="w-full"
|
||||
defaultValue={ThemeOptions[0]}
|
||||
components={{
|
||||
Control: ThemeSelectControl,
|
||||
IndicatorSeparator: () => null,
|
||||
}}
|
||||
onChange={(option) => {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
setPreviewState((previewState) => {
|
||||
return {
|
||||
...previewState,
|
||||
theme: option.value,
|
||||
};
|
||||
});
|
||||
}}
|
||||
options={ThemeOptions}
|
||||
/>
|
||||
</Label>
|
||||
<div className="mb-6 flex items-center justify-start space-x-2 rtl:space-x-reverse">
|
||||
<Switch
|
||||
checked={previewState.hideEventTypeDetails}
|
||||
|
@ -1056,29 +1070,6 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
|||
</div>
|
||||
</Label>
|
||||
))}
|
||||
<Label>
|
||||
<div className="mb-2">Theme</div>
|
||||
<Select
|
||||
className="w-full"
|
||||
defaultValue={ThemeOptions[0]}
|
||||
components={{
|
||||
Control: ThemeSelectControl,
|
||||
IndicatorSeparator: () => null,
|
||||
}}
|
||||
onChange={(option) => {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
setPreviewState((previewState) => {
|
||||
return {
|
||||
...previewState,
|
||||
theme: option.value,
|
||||
};
|
||||
});
|
||||
}}
|
||||
options={ThemeOptions}
|
||||
/>
|
||||
</Label>
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
|
|
|
@ -1800,5 +1800,13 @@
|
|||
"payment_app_commission": "Require payment ({{paymentFeePercentage}}% + {{fee, currency}} commission per transaction)",
|
||||
"email_invite_team": "{{email}} has been invited",
|
||||
"error_collecting_card": "Error collecting card",
|
||||
"image_size_limit_exceed": "Uploaded image shouldn't exceed 5mb size limit"
|
||||
"image_size_limit_exceed": "Uploaded image shouldn't exceed 5mb size limit",
|
||||
"inline_embed": "Inline Embed",
|
||||
"load_inline_content": "Loads your event type directly inline with your other website content.",
|
||||
"floating_pop_up_button": "Floating pop-up button",
|
||||
"floating_button_trigger_modal": "Puts a floating button on your site that triggers a modal with your event type.",
|
||||
"pop_up_element_click": "Pop up via element click",
|
||||
"open_dialog_with_element_click": "Open your Cal dialog when someone clicks an element.",
|
||||
"need_help_embedding": "Need help? See our guides for embedding Cal on Wix, Squarespace, or WordPress, check our common questions, or explore advanced embed options.",
|
||||
"book_my_cal": "Book my Cal"
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as Popover from "@radix-ui/react-popover";
|
|||
import { useState } from "react";
|
||||
import { HexColorInput, HexColorPicker } from "react-colorful";
|
||||
|
||||
import cx from "@calcom/lib/classNames";
|
||||
import { fallBackHex, isValidHexCode } from "@calcom/lib/getBrandColours";
|
||||
|
||||
export type ColorPickerProps = {
|
||||
|
@ -9,6 +10,7 @@ export type ColorPickerProps = {
|
|||
onChange: (text: string) => void;
|
||||
container?: HTMLElement;
|
||||
popoverAlign?: React.ComponentProps<typeof Popover.Content>["align"];
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const ColorPicker = (props: ColorPickerProps) => {
|
||||
|
@ -44,7 +46,10 @@ const ColorPicker = (props: ColorPickerProps) => {
|
|||
</Popover.Root>
|
||||
|
||||
<HexColorInput
|
||||
className="border-default text-default bg-default block h-full w-full border px-3 py-2 ltr:rounded-r-md rtl:rounded-l-md sm:text-sm"
|
||||
className={cx(
|
||||
"border-default text-default bg-default block h-full w-full border px-3 py-2 ltr:rounded-r-md rtl:rounded-l-md sm:text-sm",
|
||||
props.className
|
||||
)}
|
||||
color={color}
|
||||
onChange={(val) => {
|
||||
setColor(val);
|
||||
|
|
Loading…
Reference in New Issue