Skip to content

Commit 3619347

Browse files
author
Fergus Bisset
committed
feat(ProductCard): strongly-typed enums for layout, image type, vector kinds/shadows, and button variant; export via main, component, and SSR barrels; docs updated
1 parent 06a1abb commit 3619347

File tree

11 files changed

+717
-544
lines changed

11 files changed

+717
-544
lines changed

dist/src/ssr.js

Lines changed: 426 additions & 421 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/src/ssr.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/ProductCard/ProductCard.client.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,24 @@ describe("ProductCard - Client Tests", () => {
132132
container.firstChild.className.includes("nhs-product-card--horizontal")).toBe(true);
133133
});
134134

135+
it("accepts 'landscape' alias for horizontal", () => {
136+
const { container } = render(
137+
<ProductCard title="Test" description="Test" layout="landscape" />
138+
);
139+
140+
expect(container.firstChild instanceof Element &&
141+
container.firstChild.className.includes("nhs-product-card--horizontal")).toBe(true);
142+
});
143+
144+
it("accepts 'portrait' alias for vertical", () => {
145+
const { container } = render(
146+
<ProductCard title="Test" description="Test" layout="portrait" />
147+
);
148+
149+
expect(container.firstChild instanceof Element &&
150+
container.firstChild.className.includes("nhs-product-card--vertical")).toBe(true);
151+
});
152+
135153
it("applies theme class", () => {
136154
const { container } = render(
137155
<ProductCard title="Test" description="Test" theme="aqua-green" />

src/components/ProductCard/ProductCard.server.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type {
55
VectorGraphicShape,
66
ProductCardTheme,
77
} from "./ProductCard.types";
8-
import { ProductCardThemeEnum } from "./ProductCard.types";
8+
import { ProductCardThemeEnum, VectorGraphicKindEnum, VectorGraphicShadowEnum } from "./ProductCard.types";
99
import "./ProductCard.scss";
1010

1111
// Re-export for convenience
@@ -49,7 +49,7 @@ function generateVectorShapes(
4949
): VectorGraphicShape[] {
5050
const rng = mulberry32(seed);
5151
const shapes: VectorGraphicShape[] = [];
52-
const kinds: VectorGraphicShape["kind"][] = ["rect", "hex", "circle"];
52+
const kinds: VectorGraphicShape["kind"][] = [VectorGraphicKindEnum.Rect, VectorGraphicKindEnum.Hex, VectorGraphicKindEnum.Circle];
5353

5454
// Get complementary gradients based on theme
5555
const themeIndex = DEFAULT_GRADIENTS.indexOf(theme);
@@ -124,7 +124,7 @@ function generateVectorShapes(
124124
const y = clamp(20 + rng() * 60, 10, 90);
125125

126126
const gradient = gradients[Math.floor(rng() * gradients.length)];
127-
const shadow = shapes.length < 2 ? "soft" : "none";
127+
const shadow = shapes.length < 2 ? VectorGraphicShadowEnum.Soft : VectorGraphicShadowEnum.None;
128128

129129
if (kind === "rect") {
130130
const width = 40 + rng() * 80; // 40-120px (same as PatternBanner)

src/components/ProductCard/ProductCard.ssr.test.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,22 @@ describe("ProductCard - SSR Tests", () => {
132132
expect(html).toContain('nhs-product-card--horizontal');
133133
});
134134

135+
it("accepts 'landscape' alias for horizontal in SSR", () => {
136+
const html = renderToString(
137+
<ProductCard title="Test" description="Test" layout="landscape" />
138+
);
139+
140+
expect(html).toContain('nhs-product-card--horizontal');
141+
});
142+
143+
it("accepts 'portrait' alias for vertical in SSR", () => {
144+
const html = renderToString(
145+
<ProductCard title="Test" description="Test" layout="portrait" />
146+
);
147+
148+
expect(html).toContain('nhs-product-card--vertical');
149+
});
150+
135151
it("applies theme class in SSR", () => {
136152
const html = renderToString(
137153
<ProductCard title="Test" description="Test" theme="aqua-green" />

src/components/ProductCard/ProductCard.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,13 @@ export const ProductCard: React.FC<ProductCardProps> = ({
525525
elevated = true,
526526
imageAspectRatio = 1.5,
527527
}) => {
528+
// Support semantic aliases: 'portrait' => 'vertical', 'landscape' => 'horizontal'
529+
const normalizedLayout = React.useMemo(() => {
530+
if (layout === "landscape") return "horizontal" as const;
531+
if (layout === "portrait") return "vertical" as const;
532+
return layout;
533+
}, [layout]);
534+
528535
// Generate or use provided shapes
529536
// Note: For SSR compatibility, always provide a seed if using graphic images
530537
// to avoid hydration mismatches from Date.now()
@@ -540,7 +547,7 @@ export const ProductCard: React.FC<ProductCardProps> = ({
540547

541548
const cardClasses = [
542549
"nhs-product-card",
543-
`nhs-product-card--${layout}`,
550+
`nhs-product-card--${normalizedLayout}`,
544551
`nhs-product-card--theme-${theme}`,
545552
elevated && "nhs-product-card--elevated",
546553
(onClick || href) && "nhs-product-card--clickable",

0 commit comments

Comments
 (0)