Update NumberCard component
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import SectionNumber from "./SectionNumber";
|
||||
|
||||
interface NumberCardProps {
|
||||
number: number;
|
||||
text: string;
|
||||
size?: "Small" | "Medium" | "Large" | "XLarge";
|
||||
iconShape?: string;
|
||||
iconColor?: string;
|
||||
}
|
||||
|
||||
const NumberCard = memo<NumberCardProps>(({ number, text, size }) => {
|
||||
// Base classes common to all sizes
|
||||
const baseClasses = "bg-[var(--color-surface-inverse-primary)] rounded-[12px] shadow-lg";
|
||||
|
||||
// If size prop is provided, use explicit size classes
|
||||
// Otherwise, use responsive breakpoints for backward compatibility
|
||||
if (size) {
|
||||
// Size-specific classes
|
||||
const sizeClasses = {
|
||||
Small: "flex flex-col items-end justify-center gap-4 p-5 relative",
|
||||
Medium: "flex flex-row items-center gap-8 p-8 relative",
|
||||
Large: "flex flex-col items-start justify-end gap-[22px] h-[238px] p-8 relative",
|
||||
XLarge: "flex flex-col items-start justify-end gap-[22px] h-[238px] p-8 relative",
|
||||
};
|
||||
|
||||
// Text size classes
|
||||
const textClasses = {
|
||||
Small: "font-bricolage-grotesque font-medium text-[24px] leading-[32px] text-[#141414]",
|
||||
Medium: "font-bricolage-grotesque font-medium text-[24px] leading-[24px] text-[#141414]",
|
||||
Large: "font-bricolage-grotesque font-medium text-[24px] leading-[24px] text-[#141414]",
|
||||
XLarge: "font-bricolage-grotesque font-medium text-[32px] leading-[32px] text-[#141414]",
|
||||
};
|
||||
|
||||
// Section number positioning classes
|
||||
const sectionNumberClasses = {
|
||||
Small: "flex justify-end items-end",
|
||||
Medium: "flex justify-start flex-shrink-0",
|
||||
Large: "absolute top-8 right-8",
|
||||
XLarge: "absolute top-8 right-8",
|
||||
};
|
||||
|
||||
// Content container classes
|
||||
const contentClasses = {
|
||||
Small: "",
|
||||
Medium: "flex-1",
|
||||
Large: "absolute bottom-8 left-8 right-16",
|
||||
XLarge: "absolute bottom-8 left-8 right-16",
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`${baseClasses} ${sizeClasses[size]}`}>
|
||||
{/* Section Number */}
|
||||
<div className={sectionNumberClasses[size]}>
|
||||
<SectionNumber number={number} />
|
||||
</div>
|
||||
|
||||
{/* Card Content */}
|
||||
<div className={contentClasses[size]}>
|
||||
<p className={textClasses[size]}>
|
||||
{text}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Responsive breakpoints for backward compatibility (matches original behavior)
|
||||
// Maps to: Small (mobile) -> Medium (sm) -> Large (lg) -> XLarge (xl)
|
||||
return (
|
||||
<div className={`${baseClasses} flex flex-col gap-4 p-5 sm:flex-row sm:gap-8 sm:p-8 sm:items-center lg:flex-col lg:gap-[22px] lg:items-start lg:justify-end lg:p-8 lg:relative lg:h-[238px]`}>
|
||||
{/* Section Number - Responsive positioning */}
|
||||
<div className="flex justify-end items-end sm:justify-start sm:flex-shrink-0 lg:absolute lg:top-8 lg:right-8">
|
||||
<SectionNumber number={number} />
|
||||
</div>
|
||||
|
||||
{/* Card Content - Responsive positioning */}
|
||||
<div className="sm:flex-1 lg:absolute lg:bottom-8 lg:left-8 lg:right-16">
|
||||
<p className="font-bricolage-grotesque font-medium text-[24px] leading-[32px] sm:leading-[24px] sm:text-[24px] lg:text-[24px] lg:leading-[24px] xl:text-[32px] xl:leading-[32px] text-[#141414]">
|
||||
{text}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
NumberCard.displayName = "NumberCard";
|
||||
|
||||
export default NumberCard;
|
||||
@@ -1,33 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import SectionNumber from "./SectionNumber";
|
||||
|
||||
interface NumberedCardProps {
|
||||
number: number;
|
||||
text: string;
|
||||
iconShape?: string;
|
||||
iconColor?: string;
|
||||
}
|
||||
|
||||
const NumberedCard = memo<NumberedCardProps>(({ number, text }) => {
|
||||
return (
|
||||
<div className="bg-[var(--color-surface-inverse-primary)] rounded-[12px] p-5 shadow-lg flex flex-col gap-4 sm:p-8 sm:gap-8 sm:flex-row sm:items-center lg:p-8 lg:gap-0 lg:flex-row lg:items-stretch lg:relative lg:h-[238px]">
|
||||
{/* Section Number - Top right (lg breakpoint) */}
|
||||
<div className="flex justify-end sm:justify-start sm:flex-shrink-0 lg:absolute lg:top-8 lg:right-8">
|
||||
<SectionNumber number={number} />
|
||||
</div>
|
||||
|
||||
{/* Card Content - Bottom left (lg breakpoint) */}
|
||||
<div className="sm:flex-1 lg:absolute lg:bottom-8 lg:left-8 lg:right-16">
|
||||
<p className="font-bricolage-grotesque font-medium text-[24px] leading-[32px] sm:font-normal sm:leading-[24px] sm:text-[24px] lg:text-[24px] lg:leading-[24px] xl:text-[32px] xl:leading-[32px] text-[#141414]">
|
||||
{text}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
NumberedCard.displayName = "NumberedCard";
|
||||
|
||||
export default NumberedCard;
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useTranslation } from "../../contexts/MessagesContext";
|
||||
import SectionHeader from "../SectionHeader";
|
||||
import NumberedCard from "../NumberedCard";
|
||||
import NumberCard from "../NumberCard";
|
||||
import Button from "../Button";
|
||||
import type { NumberedCardsViewProps } from "./NumberedCards.types";
|
||||
|
||||
@@ -35,7 +35,7 @@ function NumberedCardsView({
|
||||
{/* Cards Container */}
|
||||
<div className="grid grid-cols-1 gap-y-[var(--spacing-scale-024)] lg:grid-cols-3 lg:gap-[var(--spacing-scale-024)]">
|
||||
{cards.map((card, index) => (
|
||||
<NumberedCard
|
||||
<NumberCard
|
||||
key={index}
|
||||
number={index + 1}
|
||||
text={card.text}
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
import NumberCard from "../app/components/NumberCard";
|
||||
|
||||
export default {
|
||||
title: "Components/NumberCard",
|
||||
component: NumberCard,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"Individual number card component that displays a step in a process with a numbered icon and descriptive text. Supports explicit size variants (Small, Medium, Large, XLarge) matching Figma designs, or responsive layouts when size is not specified.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
number: {
|
||||
control: { type: "number", min: 1, max: 9 },
|
||||
description: "The number to display on the card",
|
||||
},
|
||||
text: {
|
||||
control: { type: "text" },
|
||||
description: "The descriptive text for this step",
|
||||
},
|
||||
size: {
|
||||
control: { type: "select" },
|
||||
options: ["Small", "Medium", "Large", "XLarge", undefined],
|
||||
description:
|
||||
"Explicit size variant matching Figma designs. If not specified, uses responsive breakpoints for backward compatibility.",
|
||||
},
|
||||
iconShape: {
|
||||
control: { type: "select" },
|
||||
options: ["blob", "gear", "star"],
|
||||
description:
|
||||
"The shape of the icon background (currently not used, uses PNG images)",
|
||||
},
|
||||
iconColor: {
|
||||
control: { type: "select" },
|
||||
options: ["green", "purple", "orange", "blue"],
|
||||
description:
|
||||
"The color theme for the icon (currently not used, uses PNG images)",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
};
|
||||
|
||||
export const Default = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Document how your community makes decisions",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
};
|
||||
|
||||
export const Small = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Document how your community makes decisions",
|
||||
size: "Small",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Small size variant: flex-col layout with items-end, 16px gap, 20px padding, 24px text with 32px line height. Section number positioned top-right.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Medium = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Document how your community makes decisions",
|
||||
size: "Medium",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Medium size variant: flex-row layout with items-center, 32px gap, 32px padding, 24px text with 24px line height. Section number on left side.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Large = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Document how your community makes decisions",
|
||||
size: "Large",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Large size variant: flex-col layout with items-start justify-end, 22px gap, 238px height, 32px padding, 24px text with 24px line height. Section number absolute top-right.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const XLarge = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Document how your community makes decisions",
|
||||
size: "XLarge",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"XLarge size variant: flex-col layout with items-start justify-end, 22px gap, 238px height, 32px padding, 32px text with 32px line height. Section number absolute top-right.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const AllSizes = {
|
||||
render: () => (
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<h3 className="mb-4 text-lg font-semibold">Small</h3>
|
||||
<NumberCard
|
||||
number={1}
|
||||
text="Document how your community makes decisions"
|
||||
size="Small"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mb-4 text-lg font-semibold">Medium</h3>
|
||||
<NumberCard
|
||||
number={2}
|
||||
text="Document how your community makes decisions"
|
||||
size="Medium"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mb-4 text-lg font-semibold">Large</h3>
|
||||
<NumberCard
|
||||
number={3}
|
||||
text="Document how your community makes decisions"
|
||||
size="Large"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="mb-4 text-lg font-semibold">XLarge</h3>
|
||||
<NumberCard
|
||||
number={1}
|
||||
text="Document how your community makes decisions"
|
||||
size="XLarge"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Shows all four size variants side by side to compare the different layouts and typography.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const AllNumbers = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Example card text",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
render: (args) => (
|
||||
<div className="space-y-4">
|
||||
<NumberCard {...args} number={1} text="First step in the process" />
|
||||
<NumberCard
|
||||
{...args}
|
||||
number={2}
|
||||
text="Second step with different content"
|
||||
/>
|
||||
<NumberCard
|
||||
{...args}
|
||||
number={3}
|
||||
text="Third and final step of the workflow"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Shows all three numbered cards with different content to demonstrate the visual hierarchy.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const LongText = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "This is a much longer piece of text that demonstrates how the card handles content that spans multiple lines and requires more space to display properly",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Demonstrates how the card handles longer text content across different breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,96 +0,0 @@
|
||||
import NumberedCard from "../app/components/NumberedCard";
|
||||
|
||||
export default {
|
||||
title: "Components/NumberedCard",
|
||||
component: NumberedCard,
|
||||
parameters: {
|
||||
layout: "centered",
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"Individual numbered card component that displays a step in a process with a numbered icon and descriptive text. Supports responsive layouts across different breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
number: {
|
||||
control: { type: "number", min: 1, max: 9 },
|
||||
description: "The number to display on the card",
|
||||
},
|
||||
text: {
|
||||
control: { type: "text" },
|
||||
description: "The descriptive text for this step",
|
||||
},
|
||||
iconShape: {
|
||||
control: { type: "select" },
|
||||
options: ["blob", "gear", "star"],
|
||||
description:
|
||||
"The shape of the icon background (currently not used, uses PNG images)",
|
||||
},
|
||||
iconColor: {
|
||||
control: { type: "select" },
|
||||
options: ["green", "purple", "orange", "blue"],
|
||||
description:
|
||||
"The color theme for the icon (currently not used, uses PNG images)",
|
||||
},
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
};
|
||||
|
||||
export const Default = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Document how your community makes decisions",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
};
|
||||
|
||||
export const AllNumbers = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "Example card text",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
render: (args) => (
|
||||
<div className="space-y-4">
|
||||
<NumberedCard {...args} number={1} text="First step in the process" />
|
||||
<NumberedCard
|
||||
{...args}
|
||||
number={2}
|
||||
text="Second step with different content"
|
||||
/>
|
||||
<NumberedCard
|
||||
{...args}
|
||||
number={3}
|
||||
text="Third and final step of the workflow"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Shows all three numbered cards with different content to demonstrate the visual hierarchy.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const LongText = {
|
||||
args: {
|
||||
number: 1,
|
||||
text: "This is a much longer piece of text that demonstrates how the card handles content that spans multiple lines and requires more space to display properly",
|
||||
iconShape: "blob",
|
||||
iconColor: "green",
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Demonstrates how the card handles longer text content across different breakpoints.",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -8,7 +8,7 @@ export default {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"A component system for visually communicating multi-step workflows, processes, or value propositions. The component's modular design with NumberedCard and SectionNumber sub-components makes it ideal for explaining any sequential process while maintaining brand consistency and accessibility standards across the design system.",
|
||||
"A component system for visually communicating multi-step workflows, processes, or value propositions. The component's modular design with NumberCard and SectionNumber sub-components makes it ideal for explaining any sequential process while maintaining brand consistency and accessibility standards across the design system.",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, it, expect } from "vitest";
|
||||
import NumberedCard from "../../app/components/NumberedCard";
|
||||
import NumberCard from "../../app/components/NumberCard";
|
||||
|
||||
describe("NumberedCard Component", () => {
|
||||
describe("NumberCard Component", () => {
|
||||
const defaultProps = {
|
||||
number: 1,
|
||||
text: "Test Card Text",
|
||||
};
|
||||
|
||||
it("renders numbered card with all required information", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("renders number card with all required information", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
expect(screen.getByText("1")).toBeInTheDocument();
|
||||
expect(screen.getByText("Test Card Text")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders with different numbers", () => {
|
||||
const { rerender } = render(<NumberedCard {...defaultProps} number={42} />);
|
||||
const { rerender } = render(<NumberCard {...defaultProps} number={42} />);
|
||||
expect(screen.getByText("42")).toBeInTheDocument();
|
||||
|
||||
rerender(<NumberedCard {...defaultProps} number={999} />);
|
||||
rerender(<NumberCard {...defaultProps} number={999} />);
|
||||
expect(screen.getByText("999")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders with different text content", () => {
|
||||
const { rerender } = render(
|
||||
<NumberedCard {...defaultProps} text="Different Text" />,
|
||||
<NumberCard {...defaultProps} text="Different Text" />,
|
||||
);
|
||||
expect(screen.getByText("Different Text")).toBeInTheDocument();
|
||||
|
||||
rerender(<NumberedCard {...defaultProps} text="Another Text" />);
|
||||
rerender(<NumberCard {...defaultProps} text="Another Text" />);
|
||||
expect(screen.getByText("Another Text")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("applies proper responsive layout classes", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("applies proper responsive layout classes when size is not specified", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
.closest("div").parentElement;
|
||||
expect(card).toHaveClass("flex", "flex-col", "sm:flex-row", "lg:flex-row");
|
||||
expect(card).toHaveClass("flex", "flex-col", "sm:flex-row", "lg:flex-col");
|
||||
});
|
||||
|
||||
it("applies proper responsive spacing", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("applies proper responsive spacing when size is not specified", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
@@ -51,17 +51,17 @@ describe("NumberedCard Component", () => {
|
||||
expect(card).toHaveClass("p-5", "sm:p-8", "lg:p-8");
|
||||
});
|
||||
|
||||
it("applies proper responsive gap", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("applies proper responsive gap when size is not specified", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
.closest("div").parentElement;
|
||||
expect(card).toHaveClass("gap-4", "sm:gap-8", "lg:gap-0");
|
||||
expect(card).toHaveClass("gap-4", "sm:gap-8", "lg:gap-[22px]");
|
||||
});
|
||||
|
||||
it("applies proper responsive height", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("applies proper responsive height when size is not specified", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
@@ -70,7 +70,7 @@ describe("NumberedCard Component", () => {
|
||||
});
|
||||
|
||||
it("applies proper background and shadow", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
@@ -82,7 +82,7 @@ describe("NumberedCard Component", () => {
|
||||
});
|
||||
|
||||
it("applies proper border radius", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
@@ -90,25 +90,15 @@ describe("NumberedCard Component", () => {
|
||||
expect(card).toHaveClass("rounded-[12px]");
|
||||
});
|
||||
|
||||
it("renders section number in correct position", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("renders section number in correct position for responsive mode", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const numberElement = screen.getByText("1");
|
||||
expect(numberElement).toBeInTheDocument();
|
||||
|
||||
// Check that it's in a container with proper positioning
|
||||
const numberContainer = numberElement.closest("div");
|
||||
expect(numberContainer).toHaveClass(
|
||||
"absolute",
|
||||
"inset-0",
|
||||
"flex",
|
||||
"items-center",
|
||||
"justify-center",
|
||||
);
|
||||
});
|
||||
|
||||
it("renders text content in correct position", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("renders text content in correct position for responsive mode", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const textElement = screen.getByText("Test Card Text");
|
||||
expect(textElement).toBeInTheDocument();
|
||||
@@ -125,14 +115,14 @@ describe("NumberedCard Component", () => {
|
||||
});
|
||||
|
||||
it("applies proper font classes to text", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const textElement = screen.getByText("Test Card Text");
|
||||
expect(textElement).toHaveClass("font-bricolage-grotesque");
|
||||
});
|
||||
|
||||
it("applies proper text sizing", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("applies proper text sizing for responsive mode", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const textElement = screen.getByText("Test Card Text");
|
||||
expect(textElement).toHaveClass(
|
||||
@@ -144,7 +134,7 @@ describe("NumberedCard Component", () => {
|
||||
});
|
||||
|
||||
it("applies proper text color", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const textElement = screen.getByText("Test Card Text");
|
||||
expect(textElement).toHaveClass("text-[#141414]");
|
||||
@@ -152,14 +142,14 @@ describe("NumberedCard Component", () => {
|
||||
|
||||
it("handles long text content gracefully", () => {
|
||||
const longText =
|
||||
"This is a very long text that should wrap properly and not break the layout of the numbered card component";
|
||||
render(<NumberedCard {...defaultProps} text={longText} />);
|
||||
"This is a very long text that should wrap properly and not break the layout of the number card component";
|
||||
render(<NumberCard {...defaultProps} text={longText} />);
|
||||
|
||||
expect(screen.getByText(longText)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("maintains proper responsive behavior", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("maintains proper responsive behavior when size is not specified", () => {
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
@@ -178,16 +168,16 @@ describe("NumberedCard Component", () => {
|
||||
|
||||
// Large breakpoint
|
||||
expect(card).toHaveClass(
|
||||
"lg:flex-row",
|
||||
"lg:gap-0",
|
||||
"lg:flex-col",
|
||||
"lg:gap-[22px]",
|
||||
"lg:p-8",
|
||||
"lg:items-stretch",
|
||||
"lg:items-start",
|
||||
"lg:relative",
|
||||
);
|
||||
});
|
||||
|
||||
it("renders with proper flex layout", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
render(<NumberCard {...defaultProps} />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
@@ -195,12 +185,80 @@ describe("NumberedCard Component", () => {
|
||||
expect(card).toHaveClass("flex");
|
||||
});
|
||||
|
||||
it("applies proper items alignment", () => {
|
||||
render(<NumberedCard {...defaultProps} />);
|
||||
it("applies Small size variant correctly", () => {
|
||||
render(<NumberCard {...defaultProps} size="Small" />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
.closest("div").parentElement;
|
||||
expect(card).toHaveClass("sm:items-center", "lg:items-stretch");
|
||||
expect(card).toHaveClass(
|
||||
"flex",
|
||||
"flex-col",
|
||||
"items-end",
|
||||
"justify-center",
|
||||
"gap-4",
|
||||
"p-5",
|
||||
);
|
||||
|
||||
const textElement = screen.getByText("Test Card Text");
|
||||
expect(textElement).toHaveClass("text-[24px]", "leading-[32px]");
|
||||
});
|
||||
|
||||
it("applies Medium size variant correctly", () => {
|
||||
render(<NumberCard {...defaultProps} size="Medium" />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
.closest("div").parentElement;
|
||||
expect(card).toHaveClass(
|
||||
"flex",
|
||||
"flex-row",
|
||||
"items-center",
|
||||
"gap-8",
|
||||
"p-8",
|
||||
);
|
||||
|
||||
const textElement = screen.getByText("Test Card Text");
|
||||
expect(textElement).toHaveClass("text-[24px]", "leading-[24px]");
|
||||
});
|
||||
|
||||
it("applies Large size variant correctly", () => {
|
||||
render(<NumberCard {...defaultProps} size="Large" />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
.closest("div").parentElement;
|
||||
expect(card).toHaveClass(
|
||||
"flex",
|
||||
"flex-col",
|
||||
"items-start",
|
||||
"justify-end",
|
||||
"gap-[22px]",
|
||||
"h-[238px]",
|
||||
"p-8",
|
||||
);
|
||||
|
||||
const textElement = screen.getByText("Test Card Text");
|
||||
expect(textElement).toHaveClass("text-[24px]", "leading-[24px]");
|
||||
});
|
||||
|
||||
it("applies XLarge size variant correctly", () => {
|
||||
render(<NumberCard {...defaultProps} size="XLarge" />);
|
||||
|
||||
const card = screen
|
||||
.getByText("Test Card Text")
|
||||
.closest("div").parentElement;
|
||||
expect(card).toHaveClass(
|
||||
"flex",
|
||||
"flex-col",
|
||||
"items-start",
|
||||
"justify-end",
|
||||
"gap-[22px]",
|
||||
"h-[238px]",
|
||||
"p-8",
|
||||
);
|
||||
|
||||
const textElement = screen.getByText("Test Card Text");
|
||||
expect(textElement).toHaveClass("text-[32px]", "leading-[32px]");
|
||||
});
|
||||
});
|
||||
@@ -72,10 +72,10 @@ describe("NumberedCards Component", () => {
|
||||
expect(screen.getByText("Test Subtitle")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("renders NumberedCard components with correct props", () => {
|
||||
test("renders NumberCard components with correct props", () => {
|
||||
render(<NumberedCards title="Test" subtitle="Test" cards={mockCards} />);
|
||||
|
||||
// Check that NumberedCard components receive correct props
|
||||
// Check that NumberCard components receive correct props
|
||||
expect(screen.getByText("1")).toBeInTheDocument(); // First card number
|
||||
expect(screen.getByText("2")).toBeInTheDocument(); // Second card number
|
||||
expect(screen.getByText("3")).toBeInTheDocument(); // Third card number
|
||||
|
||||
Reference in New Issue
Block a user