diff --git a/packages/ui/components/card/Card.tsx b/packages/ui/components/card/Card.tsx index b7c0dcdb2a..aee4afe54a 100644 --- a/packages/ui/components/card/Card.tsx +++ b/packages/ui/components/card/Card.tsx @@ -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, "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({
@@ -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} /> )}
{title} @@ -96,7 +164,7 @@ export function Card({ {description && (

+ className={classNames(cvaCardTypeByVariant({ variant, structure: "description" }), "pt-1")}> {description}

)}