Skip to content

Commit

Permalink
cards
Browse files Browse the repository at this point in the history
  • Loading branch information
jake-figma committed Jun 14, 2024
1 parent 7ed86b6 commit 79671a8
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 53 deletions.
7 changes: 6 additions & 1 deletion figma.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@
"<FIGMA_URL_TEXT_CONTENT_HEADING>": "https://figma.com/design/J0KLPKXiONDRssXD1AX9Oi?node-id=2153-7834",
"<FIGMA_URL_TEXT_CONTENT_TITLE>": "https://figma.com/design/J0KLPKXiONDRssXD1AX9Oi?node-id=2153-7838",
"<FIGMA_URL_TEXT_AREA>": "https://figma.com/design/J0KLPKXiONDRssXD1AX9Oi?node-id=9762:1135",
"<FIGMA_URL_TEXT_AREA_FIELD>": "https://figma.com/design/J0KLPKXiONDRssXD1AX9Oi?node-id=9762-3088"
"<FIGMA_URL_TEXT_AREA_FIELD>": "https://figma.com/design/J0KLPKXiONDRssXD1AX9Oi?node-id=9762-3088",
"<FIGMA_URL_CARDS_PRODUCT_INFO_CARD>": "https://www.figma.com/design/J0KLPKXiONDRssXD1AX9Oi/SDS?node-id=7753-4465&m=dev",
"<FIGMA_URL_CARDS_PRICING_CARD>": "https://www.figma.com/design/J0KLPKXiONDRssXD1AX9Oi/SDS?node-id=7722-3736&t=zlze7QSzfpWykbLu-11",
"<FIGMA_URL_CARDS_TESTIMONIAL_CARD>": "https://www.figma.com/design/J0KLPKXiONDRssXD1AX9Oi/SDS?node-id=7717-3946&t=zlze7QSzfpWykbLu-11",
"<FIGMA_URL_CARDS_STATS_CARD>": "https://www.figma.com/design/J0KLPKXiONDRssXD1AX9Oi/SDS?node-id=2236-15082&t=zlze7QSzfpWykbLu-11",
"<FIGMA_URL_CARDS_REVIEW_CARD>": "https://www.figma.com/design/J0KLPKXiONDRssXD1AX9Oi/SDS?node-id=2236-16106&t=zlze7QSzfpWykbLu-11"
}
}
}
15 changes: 14 additions & 1 deletion src/compositions/Cards/Cards.figma.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { figma } from "@figma/code-connect";
import { Image, Text, TextHeading } from "ui";
import { Card } from "./Cards";
import {
Card,
PricingCard,
ProductInfoCard,
ReviewCard,
StatsCard,
TestimonialCard,
} from "./Cards";

figma.connect(Card, "<FIGMA_URL_CARD>", {
props: {
Expand Down Expand Up @@ -28,3 +35,9 @@ figma.connect(Card, "<FIGMA_URL_CARD>", {
</Card>
),
});

figma.connect(ProductInfoCard, "<FIGMA_URL_CARDS_PRODUCT_INFO_CARD>");
figma.connect(PricingCard, "<FIGMA_URL_CARDS_PRICING_CARD>");
figma.connect(TestimonialCard, "<FIGMA_URL_CARDS_TESTIMONIAL_CARD>");
figma.connect(StatsCard, "<FIGMA_URL_CARDS_STATS_CARD>");
figma.connect(ReviewCard, "<FIGMA_URL_CARDS_REVIEW_CARD>");
146 changes: 121 additions & 25 deletions src/compositions/Cards/Cards.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import clsx from "clsx";
import { useMediaQuery } from "hooks";
import { ComponentPropsWithoutRef } from "react";
import { IconStar } from "icons";
import { Flex } from "layout";
import { ComponentPropsWithoutRef, ReactNode } from "react";
import {
Avatar,
AvatarBlock,
Expand All @@ -11,12 +13,18 @@ import {
TextHeading,
TextList,
TextListItem,
TextSmall,
TextStrong,
TextTitlePage,
} from "ui";
import { AnchorOrButton, AnchorOrButtonProps } from "utils";
import "./cards.css";

export type CardProps = ComponentPropsWithoutRef<"div"> & {
/**
* The alignment of the card content.
*/
align?: "start" | "center" | "end";
/**
* The initial direction of the card.
* All cards become vertical on mobile.
Expand Down Expand Up @@ -46,6 +54,7 @@ export type CardProps = ComponentPropsWithoutRef<"div"> & {
* The basic card generic component that can be used to create vanity card components.
*/
export function Card({
align = "start",
children,
className,
direction = "vertical",
Expand All @@ -58,6 +67,7 @@ export function Card({
const classNames = clsx(
className,
"card",
`card-align-${align}`,
`card-direction-${isMobile ? "vertical" : direction}`,
`card-variant-${variant}`,
);
Expand Down Expand Up @@ -108,19 +118,23 @@ export function PricingCard({
}: PricingCardProps) {
return (
<Card {...props} direction="vertical" variant="stroke">
<TextHeading>{heading}</TextHeading>
<TextTitlePage>
${price}
<Text elementType="span"> / per month</Text>
</TextTitlePage>
<Flex direction="column" gap="200">
<TextHeading>{heading}</TextHeading>
<TextTitlePage>
${price}
<Text elementType="span"> / per month</Text>
</TextTitlePage>
</Flex>
<TextList>
{items.map((item) => (
<TextListItem key={item}>{item}</TextListItem>
))}
</TextList>
<ButtonGroup align="justify">
<Button onPress={onAction}>{action}</Button>
</ButtonGroup>
<Flex alignPrimary="stretch">
<ButtonGroup align="justify">
<Button onPress={onAction}>{action}</Button>
</ButtonGroup>
</Flex>
</Card>
);
}
Expand All @@ -135,13 +149,9 @@ export type ProductInfoCardProps = Pick<CardProps, "asset"> & {
*/
price: number;
/**
* The text labeling the action button
*/
action: string;
/**
* The action for the button
* The description of the product
*/
onAction: () => void;
description: string;
};

/**
Expand All @@ -151,19 +161,105 @@ export function ProductInfoCard({
asset,
heading,
price,
action,
onAction,
description,
...props
}: ProductInfoCardProps) {
return (
<Card {...props} direction="horizontal" variant="stroke" asset={asset}>
<TextHeading>{heading}</TextHeading>
<TextTitlePage>${price}</TextTitlePage>
<ButtonGroup align="start">
<Button variant="neutral" onPress={onAction}>
{action}
</Button>
</ButtonGroup>
<Card {...props} direction="vertical" variant="stroke" asset={asset}>
<Flex direction="column" gap="200">
<Text>{heading}</Text>
<TextStrong>${price}</TextStrong>
<TextSmall>{description}</TextSmall>
</Flex>
</Card>
);
}

export type ReviewCardProps = {
/**
* The number of stars (1-5)
*/
stars: number;
/**
* The title of the review
*/
title: string;
/**
* The review
*/
body: string;
/**
* The name of the reviewer
*/
name: string;
/**
* The date of the review
*/
date: string;
/**
* The avatar src
*/
src?: AvatarProps["src"];
};

/**
* A card demonstrating a statistic or metric
*/
export function ReviewCard({
stars,
title,
body,
name,
date,
src,

...props
}: ReviewCardProps) {
return (
<Card {...props} direction="vertical" variant="stroke">
<Flex gap="100">{new Array(stars).fill(<IconStar />)}</Flex>
<Flex direction="column" gap="100">
<TextHeading>{title}</TextHeading>
<TextSmall>{body}</TextSmall>
</Flex>
<AvatarBlock title={name} description={date}>
<Avatar size="large" src={src} initials={name.charAt(0)} />
</AvatarBlock>
</Card>
);
}

export type StatsCardProps = {
/**
* The icon
*/
icon?: ReactNode;
/**
* The stat
*/
stat: string;
/**
* The description
*/
description: string;
};

/**
* A card demonstrating a statistic or metric
*/
export function StatsCard({
icon,
stat,
description,
...props
}: StatsCardProps) {
return (
<Card {...props} direction="vertical" variant="stroke" align="center">
{icon}
<Flex direction="column" alignSecondary="center" gap="100">
<TextHeading>{stat}</TextHeading>
{description && <TextSmall>{description}</TextSmall>}
</Flex>
</Card>
);
}
Expand Down
23 changes: 14 additions & 9 deletions src/compositions/Cards/cards.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,25 @@
}
}

&.card-align-start {
--content-align: start;
}
&.card-align-center {
--content-align: center;
}
&.card-align-end {
--content-align: end;
}

.card-content {
align-items: var(--content-align, start);
display: flex;
flex-direction: column;
gap: var(--sds-size-space-200);
gap: var(--sds-size-space-600);
grid-area: content;

.text-body-base {
color: var(--sds-color-text-default-secondary);
}

.button-group {
margin-top: var(--sds-size-space-400);
position: relative;
z-index: 2;
> * {
width: 100%;
}
}
}
Expand Down
12 changes: 3 additions & 9 deletions src/layout/Flex/Flex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ export type FlexProps = ComponentPropsWithoutRef<"div"> & {
alignPrimary?: "start" | "end" | "center" | "stretch" | "space-between";
alignSecondary?: "start" | "end" | "center" | "stretch" | "space-between";
direction?: "row" | "row-reverse" | "column" | "column-reverse";
gap?:
| "100" // xs
| "200" // sm
| "300" // md
| "400" // lg
| "600" // xl
| "800"; // xxl;
gap?: "100" | "200" | "300" | "400" | "600" | "800";
type?: "quarter" | "third" | "half" | "auto";
container?: boolean;
wrap?: boolean;
Expand Down Expand Up @@ -52,9 +46,9 @@ export function Flex({
);
}

type FlextItemSize = "full" | "major" | "minor" | "half";
type FlexItemSize = "full" | "major" | "minor" | "half";
export type FlexItemProps = ComponentPropsWithoutRef<"div"> & {
size?: FlextItemSize;
size?: FlexItemSize;
};
export function FlexItem({ className, children, size }: FlexItemProps) {
const classNames = clsx(
Expand Down
2 changes: 1 addition & 1 deletion src/layout/Flex/flex.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

&.flex-direction-column,
&.flex-direction-column-reverse {
> * {
&.flex-align-secondary-stretch > * {
width: 100%;
}
}
Expand Down
Loading

0 comments on commit 79671a8

Please sign in to comment.