diff --git a/src/components/card-icon/basic-card-media.tsx b/src/components/card-icon/basic-card-media.tsx index c037bfd..a7e8791 100644 --- a/src/components/card-icon/basic-card-media.tsx +++ b/src/components/card-icon/basic-card-media.tsx @@ -1,7 +1,7 @@ import { GradientIcon, type GradientIconType } from "../gradient-icon" -import type { CardSize } from "./types" +import type { ResponsiveCardSize } from "./types" import { getIconSizeClasses } from "./utils" -export function BasicCardMedia({ icon: Icon, size }: { icon: GradientIconType; size: CardSize }) { +export function BasicCardMedia({ icon: Icon, size }: { icon: GradientIconType; size: ResponsiveCardSize }) { return } diff --git a/src/components/card-icon/classes.ts b/src/components/card-icon/classes.ts new file mode 100644 index 0000000..871cced --- /dev/null +++ b/src/components/card-icon/classes.ts @@ -0,0 +1,36 @@ +import type { SizeClassMap } from "./types" + +export const ICON_SIZE_CLASSES: SizeClassMap = { + xs: "h-10 w-10", + sm: "h-14 w-14", + md: "h-32 w-32", + lg: "h-44 w-44", +} + +export const CARD_PADDING_WITHOUT_DESCRIPTION: SizeClassMap = { + xs: "p-3", + sm: "px-8 py-4", + md: "p-8", + lg: "p-8", +} + +export const CARD_PADDING_WITH_DESCRIPTION: SizeClassMap = { + xs: "p-8", + sm: "p-8", + md: "p-8", + lg: "p-8", +} + +export const CONTENT_GAP_CLASSES: SizeClassMap = { + xs: "gap-2", + sm: "gap-2", + md: "gap-6", + lg: "gap-6", +} + +export const TITLE_SIZE_CLASSES: SizeClassMap = { + xs: "typo-label-large", + sm: "typo-headline-medium", + md: "typo-headline-medium", + lg: "typo-headline-medium", +} diff --git a/src/components/card-icon/description-card-media.tsx b/src/components/card-icon/description-card-media.tsx index 668dcff..13899ac 100644 --- a/src/components/card-icon/description-card-media.tsx +++ b/src/components/card-icon/description-card-media.tsx @@ -1,9 +1,9 @@ import { cn } from "@/lib/utils" import { GradientIcon, type GradientIconType } from "../gradient-icon" -import type { CardSize } from "./types" +import type { ResponsiveCardSize } from "./types" import { getIconSizeClasses } from "./utils" -export function DescriptionCardMedia({ icon: Icon, size }: { icon: GradientIconType; size: CardSize }) { +export function DescriptionCardMedia({ icon: Icon, size }: { icon: GradientIconType; size: ResponsiveCardSize }) { return (
diff --git a/src/components/card-icon/index.tsx b/src/components/card-icon/index.tsx index f0c0a8d..577eec9 100644 --- a/src/components/card-icon/index.tsx +++ b/src/components/card-icon/index.tsx @@ -4,7 +4,7 @@ import { BasicCardMedia } from "./basic-card-media" import { DescriptionCardMedia } from "./description-card-media" import { CardHoverBackground } from "./hover-background" import type { CardIconProps } from "./types" -import { getCardPaddingClasses, getContentGapClasses } from "./utils" +import { getCardPaddingClasses, getContentGapClasses, getTitleSizeClasses } from "./utils" export function CardIcon(props: CardIconProps) { const { title, icon, size = "md", href, hoverEffect = false, className } = props @@ -46,7 +46,8 @@ export function CardIcon(props: CardIconProps) {

diff --git a/src/components/card-icon/types.ts b/src/components/card-icon/types.ts index 4f02808..25bca27 100644 --- a/src/components/card-icon/types.ts +++ b/src/components/card-icon/types.ts @@ -1,18 +1,28 @@ import type { GradientIconType } from "@/components/gradient-icon" -export type CardSize = "sm" | "md" | "lg" +export type CardSize = "xs" | "sm" | "md" | "lg" +export type CardBreakpoint = "base" | "sm" | "md" | "lg" + +export type SizeClassMap = Record + +export type ResponsiveCardSizeConfig = { + base: CardSize + sm?: CardSize + md?: CardSize + lg?: CardSize +} + +export type ResponsiveCardSize = CardSize | ResponsiveCardSizeConfig export type SharedCardProps = { title: string icon: GradientIconType - size?: CardSize + size?: ResponsiveCardSize href?: string hoverEffect?: boolean className?: string } -export type CardWithDescriptionProps = SharedCardProps & { - description: string +export type CardIconProps = SharedCardProps & { + description?: string } - -export type CardIconProps = SharedCardProps | CardWithDescriptionProps diff --git a/src/components/card-icon/utils.ts b/src/components/card-icon/utils.ts index b9f0a95..156adac 100644 --- a/src/components/card-icon/utils.ts +++ b/src/components/card-icon/utils.ts @@ -1,17 +1,63 @@ -import type { CardSize } from "./types" +import { + CARD_PADDING_WITH_DESCRIPTION, + CARD_PADDING_WITHOUT_DESCRIPTION, + CONTENT_GAP_CLASSES, + ICON_SIZE_CLASSES, + TITLE_SIZE_CLASSES, +} from "./classes" -export function getIconSizeClasses(size: CardSize) { - if (size === "sm") return "h-14 w-14" - if (size === "lg") return "h-44 w-44" - return "h-32 w-32" +import type { CardBreakpoint, ResponsiveCardSize, SizeClassMap } from "./types" + +const BREAKPOINTS: CardBreakpoint[] = ["base", "sm", "md", "lg"] + +const BREAKPOINT_PREFIX: Record = { + base: "", + sm: "sm:", + md: "md:", + lg: "lg:", +} + +function prefixClasses(prefix: string, value: string): string { + return value + .split(" ") + .filter(Boolean) + .map((token) => `${prefix}${token}`) + .join(" ") +} + +function resolveResponsiveClasses(size: ResponsiveCardSize, classesBySize: SizeClassMap): string { + if (typeof size === "string") { + return classesBySize[size] + } + + return BREAKPOINTS.map((breakpoint) => { + const currentSize = size[breakpoint] + + if (!currentSize) { + return "" + } + + return prefixClasses(BREAKPOINT_PREFIX[breakpoint], classesBySize[currentSize]) + }) + .filter(Boolean) + .join(" ") +} + +export function getIconSizeClasses(size: ResponsiveCardSize) { + return resolveResponsiveClasses(size, ICON_SIZE_CLASSES) +} + +export function getCardPaddingClasses(size: ResponsiveCardSize, hasDescription: boolean) { + return resolveResponsiveClasses( + size, + hasDescription ? CARD_PADDING_WITH_DESCRIPTION : CARD_PADDING_WITHOUT_DESCRIPTION + ) } -export function getCardPaddingClasses(size: CardSize, hasDescription: boolean) { - if (!hasDescription && size === "sm") return "px-8 py-4" - return "p-8" +export function getContentGapClasses(size: ResponsiveCardSize) { + return resolveResponsiveClasses(size, CONTENT_GAP_CLASSES) } -export function getContentGapClasses(size: CardSize) { - if (size === "sm") return "gap-2" - return "gap-6" +export function getTitleSizeClasses(size: ResponsiveCardSize) { + return resolveResponsiveClasses(size, TITLE_SIZE_CLASSES) } diff --git a/src/components/home/materials.tsx b/src/components/home/materials.tsx index 6d2bacb..ab02f1e 100644 --- a/src/components/home/materials.tsx +++ b/src/components/home/materials.tsx @@ -22,37 +22,42 @@ const featuredCards = [ ] as const const quickLinks = [ - { title: "Dispense", icon: FiBook, size: "sm", href: "#" }, - { title: "Esami", icon: FiFileText, size: "sm", href: "#" }, - { title: "Appunti", icon: FiClipboard, size: "sm", href: "#" }, + { title: "Dispense", icon: FiBook, size: { base: "xs", sm: "sm" }, href: "#" }, + { title: "Esami", icon: FiFileText, size: { base: "xs", sm: "sm" }, href: "#" }, + { title: "Appunti", icon: FiClipboard, size: { base: "xs", sm: "sm" }, href: "#" }, ] as const export function Materials() { return ( -
-
-
+
+
+
+ {/* TODO sotto sm usare le altre card fatte da Diubi */} {featuredCards.map((card) => ( ))}
-
+
{quickLinks.map((card) => ( ))}
-
-

+
+

Materials

-

+

Il piu grande archivio didattico creato dagli studenti per gli studenti del Politecnico di Milano. Cerca tra migliaia di appunti, dispense, temi d'esame e molto altro. Carica i tuoi file per far crescere la community e trova tutto cio che ti serve, organizzato per corso di studi.

+

+ Il più grande archivio didattico degli studenti del Politecnico. Trova appunti, dispense ed esami, oppure + carica i tuoi file per far crescere la community. +