fix: add calendar button layout shift (#7930)

This commit is contained in:
Nafees Nazik
2023-04-02 10:34:48 +00:00
committed by GitHub
parent 469967b320
commit 81b2e37efd
3 changed files with 41 additions and 160 deletions
@@ -1,86 +0,0 @@
import React from "react";
import Select from "react-select";
import type { OptionProps } from "react-select";
import { InstallAppButton } from "@calcom/app-store/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import type { App } from "@calcom/types/App";
import { Button } from "@calcom/ui";
import { QueryCell } from "@lib/QueryCell";
interface AdditionalCalendarSelectorProps {
isLoading?: boolean;
}
const ImageOption = (optionProps: OptionProps<{ [key: string]: string; type: App["type"] }>) => {
const { data } = optionProps;
return (
<InstallAppButton
type={data.type}
render={(installProps) => {
return (
<Button {...installProps} className="w-full" color="minimal">
{/* eslint-disable @next/next/no-img-element */}
{data.image && (
<img className="float-left mr-3 inline h-5 w-5" src={data.image} alt={data.label} />
)}
<p>{data.label}</p>
</Button>
);
}}
/>
);
};
const AdditionalCalendarSelector = ({ isLoading }: AdditionalCalendarSelectorProps): JSX.Element | null => {
const { t } = useLocale();
const query = trpc.viewer.integrations.useQuery({ variant: "calendar", onlyInstalled: true });
return (
<QueryCell
query={query}
success={({ data }) => {
const options = data.items.map((item) => ({
label: item.name,
slug: item.slug,
image: item.logo,
type: item.type,
}));
return (
<Select
name="additionalCalendar"
placeholder={t("connect_additional_calendar")}
options={options}
styles={{
placeholder: (defaultStyles) => {
return {
...defaultStyles,
color: "#3E3E3E",
marginLeft: "3px",
};
},
control: (defaultStyles) => {
return {
...defaultStyles,
borderRadius: "2px",
"@media only screen and (min-width: 640px)": {
...(defaultStyles["@media only screen and (min-width: 640px)"] as object),
maxWidth: "320px",
},
};
},
}}
isSearchable={false}
className="mt-1 mb-2 block w-full min-w-0 flex-1 rounded-none rounded-r-sm border-gray-300 text-sm font-medium text-gray-700"
isLoading={isLoading}
components={{ Option: ImageOption }}
/>
);
}}
/>
);
};
export default AdditionalCalendarSelector;
@@ -1,10 +1,14 @@
import type { OptionProps } from "react-select";
import { InstallAppButton } from "@calcom/app-store/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import type { App } from "@calcom/types/App";
import { Button, Select } from "@calcom/ui";
import {
Button,
Dropdown,
DropdownMenuContent,
DropdownMenuTrigger,
DropdownMenuItem,
DropdownItem,
} from "@calcom/ui";
import { FiPlus } from "@calcom/ui/components/icon";
import { QueryCell } from "@lib/QueryCell";
@@ -13,31 +17,6 @@ interface AdditionalCalendarSelectorProps {
isLoading?: boolean;
}
const ImageOption = (optionProps: OptionProps<{ [key: string]: string; type: App["type"] }>) => {
const { t } = useLocale();
const { data } = optionProps;
return data.slug !== "add-new" ? (
<InstallAppButton
type={data.type}
render={(installProps) => {
return (
<Button {...installProps} className="flex w-full align-top" color="minimal">
{data.image && (
<img className="float-left mr-3 inline h-5 w-5" src={data.image} alt={data.label} />
)}
<p className="text-left">{`${t("add")} ${data.label}`}</p>
</Button>
);
}}
/>
) : (
<Button className="w-full" color="minimal" href="/apps/categories/calendar">
<FiPlus className="text-color mr-3 ml-1 h-4 w-4" />
<p>{t("install_new_calendar_app")}</p>
</Button>
);
};
const AdditionalCalendarSelector = ({ isLoading }: AdditionalCalendarSelectorProps): JSX.Element | null => {
const { t } = useLocale();
const query = trpc.viewer.integrations.useQuery({ variant: "calendar", onlyInstalled: true });
@@ -59,51 +38,39 @@ const AdditionalCalendarSelector = ({ isLoading }: AdditionalCalendarSelectorPro
type: "new_other",
});
return (
<Select
name="additionalCalendar"
placeholder={
<Button StartIcon={FiPlus} color="secondary">
<Dropdown modal={false}>
<DropdownMenuTrigger asChild>
<Button StartIcon={FiPlus} color="secondary" {...(isLoading && { loading: isLoading })}>
{t("add")}
</Button>
}
options={options}
isSearchable={false}
isLoading={isLoading}
components={{ Option: ImageOption }}
styles={{
menu: (defaultStyles) => ({
...defaultStyles,
"@media only screen and (max-width: 640px)": {
left: "0",
},
width: "max-content",
right: "0",
}),
indicatorSeparator: (defaultStyles) => ({
...defaultStyles,
display: "none",
}),
control: (defaultStyles) => ({
...defaultStyles,
padding: "0",
border: "0",
borderRadius: "6px",
minHeight: "auto",
}),
dropdownIndicator: (defaultStyles) => ({
...defaultStyles,
display: "none",
}),
valueContainer: (defaultStyles) => ({
...defaultStyles,
padding: "0",
}),
placeholder: (defaultStyles) => ({
...defaultStyles,
margin: "0",
}),
}}
/>
</DropdownMenuTrigger>
<DropdownMenuContent>
{options.map((data) => (
<DropdownMenuItem key={data.slug} className="focus:outline-none">
{data.slug === "add-new" ? (
<DropdownItem StartIcon={FiPlus} color="minimal" href="/apps/categories/calendar">
{t("install_new_calendar_app")}
</DropdownItem>
) : (
<InstallAppButton
type={data.type}
render={(installProps) => {
const props = { ...installProps } as any;
return (
<DropdownItem {...props} color="minimal" type="button">
<span className="flex items-center gap-x-2">
{data.image && <img className="h-5 w-5" src={data.image} alt={data.label} />}
{`${t("add")} ${data.label}`}
</span>
</DropdownItem>
);
}}
/>
)}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</Dropdown>
);
}}
/>
@@ -135,12 +135,12 @@ export const DropdownItem = (props: DropdownItemProps) => {
<ButtonOrLink
{...rest}
className={classNames(
"inline-flex w-full items-center px-3 py-2 text-gray-700 hover:text-gray-900 disabled:cursor-not-allowed",
"inline-flex w-full items-center gap-x-3 px-3 py-2 text-gray-700 hover:text-gray-900 disabled:cursor-not-allowed",
color === "destructive" ? "hover:bg-red-100 hover:text-red-700" : "hover:bg-gray-100"
)}>
<>
{StartIcon && <StartIcon className="h-4 w-4" />}
<div className="mx-3 text-sm font-medium leading-5">{children}</div>
<div className="text-sm font-medium leading-5">{children}</div>
{EndIcon && <EndIcon className="h-4 w-4" />}
</>
</ButtonOrLink>