refactor: Convert card to cva (#9651)

This commit is contained in:
Ayush Mainali
2023-06-20 19:54:08 +02:00
committed by GitHub
parent 16f24b4831
commit d2a12ea834
+98 -30
View File
@@ -1,4 +1,6 @@
// @TODO: turn this into a more generic component that has the same Props API as MUI https://mui.com/material-ui/react-card/
import type { VariantProps } from "class-variance-authority";
import { cva } from "class-variance-authority";
import Link from "next/link";
import type { ReactNode } from "react";
import React from "react";
@@ -8,10 +10,96 @@ import { ArrowRight } from "@calcom/ui/components/icon";
import { Button } from "../button";
export type BaseCardProps = {
const cvaCardTypeByVariant = cva("", {
// Variants won't have any style by default. Style will only be applied if the variants are combined.
// So, style is defined in compoundVariants.
variants: {
variant: {
basic: "",
ProfileCard: "",
SidebarCard: "",
},
structure: {
image: "",
card: "",
title: "",
description: "",
},
},
compoundVariants: [
// Style for Basic Variants types
{
variant: "basic",
structure: "image",
className: "w-10 h-auto",
},
{
variant: "basic",
structure: "card",
className: "p-5",
},
{
variant: "basic",
structure: "title",
className: "text-base mt-4",
},
{
variant: "basic",
structure: "description",
className: "text-sm leading-[18px] text-subtle font-normal",
},
// Style for ProfileCard Variant Types
{
variant: "ProfileCard",
structure: "image",
className: "w-9 h-auto rounded-full mb-4s",
},
{
variant: "ProfileCard",
structure: "card",
className: "w-80 p-4 hover:bg-subtle",
},
{
variant: "ProfileCard",
structure: "title",
className: "text-base",
},
{
variant: "ProfileCard",
structure: "description",
className: "text-sm leading-[18px] text-subtle font-normal",
},
// Style for SidebarCard Variant Types
{
variant: "SidebarCard",
structure: "image",
className: "w-9 h-auto rounded-full mb-4s",
},
{
variant: "SidebarCard",
structure: "card",
className: "w-full p-3 border border-subtle",
},
{
variant: "SidebarCard",
structure: "title",
className: "text-sm font-cal",
},
{
variant: "SidebarCard",
structure: "description",
className: "text-xs text-default line-clamp-2",
},
],
});
type CVACardType = Required<Pick<VariantProps<typeof cvaCardTypeByVariant>, "variant">>;
export interface BaseCardProps extends CVACardType {
image?: string;
icon?: ReactNode;
variant: keyof typeof cardTypeByVariant;
imageProps?: JSX.IntrinsicElements["img"];
title: string;
description: ReactNode;
@@ -27,30 +115,7 @@ export type BaseCardProps = {
};
mediaLink?: string;
thumbnailUrl?: string;
};
// @TODO: use CVA
const cardTypeByVariant = {
basic: {
image: "w-10 h-auto",
card: "p-5",
title: "text-base mt-4",
description: "text-sm leading-[18px] text-subtle font-normal",
},
ProfileCard: {
image: "w-9 h-auto rounded-full mb-4s",
card: "w-80 p-4 hover:bg-subtle",
title: "text-base",
description: "text-sm leading-[18px] text-subtle font-normal",
},
SidebarCard: {
image: "w-9 h-auto rounded-full mb-4s",
card: "w-full p-3 border border-subtle",
title: "text-sm font-cal",
description: "text-xs text-default line-clamp-2",
},
};
}
export function Card({
image,
@@ -70,7 +135,7 @@ export function Card({
<div
className={classNames(
containerProps?.className,
cardTypeByVariant[variant].card,
cvaCardTypeByVariant({ variant, structure: "card" }),
"bg-default border-subtle text-default flex flex-col justify-between rounded-md border"
)}
{...containerProps}>
@@ -81,14 +146,17 @@ export function Card({
src={image}
// Stops eslint complaining - not smart enough to realise it comes from ...imageProps
alt={imageProps?.alt}
className={classNames(imageProps?.className, cardTypeByVariant[variant].image)}
className={classNames(
imageProps?.className,
cvaCardTypeByVariant({ variant, structure: "image" })
)}
{...imageProps}
/>
)}
<h5
title={title}
className={classNames(
cardTypeByVariant[variant].title,
cvaCardTypeByVariant({ variant, structure: "title" }),
"line-clamp-1 text-emphasis font-bold leading-5"
)}>
{title}
@@ -96,7 +164,7 @@ export function Card({
{description && (
<p
title={description.toString()}
className={classNames(cardTypeByVariant[variant].description, "pt-1")}>
className={classNames(cvaCardTypeByVariant({ variant, structure: "description" }), "pt-1")}>
{description}
</p>
)}