diff --git a/app/components/cards/CardStack/CardStack.container.tsx b/app/components/cards/CardStack/CardStack.container.tsx index 50e251d..a7e5782 100644 --- a/app/components/cards/CardStack/CardStack.container.tsx +++ b/app/components/cards/CardStack/CardStack.container.tsx @@ -11,6 +11,8 @@ const DEFAULT_TOGGLE_LABEL = "See all communication approaches"; * Figma: "Utility / CardStack"; canonical code under `cards/`. * Selectable stack of cards with * an optional "see all"/"show less" expand toggle. + * Expanded default layout matches Flow — Expanded Card Stack (`20768:14820`): + * 281×142 CardSelection tiles in two columns. */ const CardStackContainer = memo( ({ diff --git a/app/components/cards/CardStack/CardStack.types.ts b/app/components/cards/CardStack/CardStack.types.ts index 00b7776..2fc4b8d 100644 --- a/app/components/cards/CardStack/CardStack.types.ts +++ b/app/components/cards/CardStack/CardStack.types.ts @@ -20,7 +20,7 @@ export interface CardStackProps { showLessLabel?: string; title?: string; description?: ReactNode; - /** "default" = compact grid/column + expanded grid; "singleStack" = always one column, expand shows more in same stack */ + /** "default" = compact grid/column + expanded 2-col 142px tiles; "singleStack" = always one column, expand shows more in same stack */ layout?: "default" | "singleStack"; /** * Max recommended cards in compact (non-expanded) mode. Default 5; Figma compact stack uses 3. diff --git a/app/components/cards/CardStack/CardStack.view.tsx b/app/components/cards/CardStack/CardStack.view.tsx index 2f7f6b8..485dd38 100644 --- a/app/components/cards/CardStack/CardStack.view.tsx +++ b/app/components/cards/CardStack/CardStack.view.tsx @@ -6,6 +6,10 @@ import type { HeaderLockupSizeValue } from "../../type/HeaderLockup/HeaderLockup import Selection from "../Selection"; import type { CardStackViewProps } from "./CardStack.types"; +/** Figma Card / CardSelection on Compact + Expanded Card Stack (`281×142`). */ +const FIGMA_CARD_SELECTION_TILE_CLASS = + "h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0"; + function CardStackHeaderLockup({ title, description, @@ -175,24 +179,46 @@ export function CardStackView({ /> {expanded ? ( -
- {cards.map((item) => ( - onCardSelect(item.id)} - /> - ))} - {addTile ? ( -
{addTile}
- ) : null} -
+ <> +
+ {cards.map((item) => ( + onCardSelect(item.id)} + /> + ))} + {addTile} +
+
+ {cards.map((item) => ( + onCardSelect(item.id)} + /> + ))} + {addTile ? ( +
+ {addTile} +
+ ) : null} +
+ ) : compactDesktopLayout === "pyramidFive" ? ( <>
@@ -230,7 +256,7 @@ export function CardStackView({ selected={isSelected(item.id)} orientation="horizontal" showInfoIcon={false} - className="h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0" + className={FIGMA_CARD_SELECTION_TILE_CLASS} onClick={() => onCardSelect(item.id)} /> ))} @@ -249,7 +275,7 @@ export function CardStackView({ selected={isSelected(item.id)} orientation="horizontal" showInfoIcon={false} - className="h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0" + className={FIGMA_CARD_SELECTION_TILE_CLASS} onClick={() => onCardSelect(item.id)} /> ))} @@ -268,7 +294,7 @@ export function CardStackView({ selected={isSelected(item.id)} orientation="horizontal" showInfoIcon={false} - className="h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0" + className={FIGMA_CARD_SELECTION_TILE_CLASS} onClick={() => onCardSelect(item.id)} /> ))} @@ -284,7 +310,7 @@ export function CardStackView({ selected={isSelected(item.id)} orientation="horizontal" showInfoIcon={false} - className="h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0" + className={FIGMA_CARD_SELECTION_TILE_CLASS} onClick={() => onCardSelect(item.id)} /> ))} @@ -299,7 +325,7 @@ export function CardStackView({ selected={isSelected(compactCards[4].id)} orientation="horizontal" showInfoIcon={false} - className="h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0" + className={FIGMA_CARD_SELECTION_TILE_CLASS} onClick={() => onCardSelect(compactCards[4].id)} />
@@ -346,7 +372,7 @@ export function CardStackView({ selected={isSelected(item.id)} orientation="horizontal" showInfoIcon={false} - className="h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0" + className={FIGMA_CARD_SELECTION_TILE_CLASS} onClick={() => onCardSelect(item.id)} /> ))} @@ -360,7 +386,7 @@ export function CardStackView({ selected={isSelected(compactCards[2].id)} orientation="horizontal" showInfoIcon={false} - className="h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0" + className={FIGMA_CARD_SELECTION_TILE_CLASS} onClick={() => onCardSelect(compactCards[2].id)} /> @@ -379,7 +405,7 @@ export function CardStackView({ selected={isSelected(item.id)} orientation="horizontal" showInfoIcon={false} - className="h-[142px] min-h-[142px] max-h-[142px] w-[281px] max-w-[281px] shrink-0" + className={FIGMA_CARD_SELECTION_TILE_CLASS} onClick={() => onCardSelect(item.id)} /> ))} diff --git a/app/components/cards/Selection/Selection.container.tsx b/app/components/cards/Selection/Selection.container.tsx index 10a2d7f..1825343 100644 --- a/app/components/cards/Selection/Selection.container.tsx +++ b/app/components/cards/Selection/Selection.container.tsx @@ -6,7 +6,7 @@ import type { SelectionProps } from "./Selection.types"; /** * Figma: "Card / CardSelection" — stacked tile e.g. `16775:28762` (recommended + label + supportText). - * `orientation="horizontal"` selects that vertical stack; `"vertical"` is label + optional info icon with tag on the right (CardStack expanded / single-column). + * `orientation="horizontal"` selects that vertical stack; `"vertical"` is label + optional info icon with tag on the right (CardStack `singleStack` / right-rail). */ const SelectionContainer = memo( ({ diff --git a/stories/cards/CardStack.stories.js b/stories/cards/CardStack.stories.js index 545d0be..2259f8f 100644 --- a/stories/cards/CardStack.stories.js +++ b/stories/cards/CardStack.stories.js @@ -97,7 +97,8 @@ export const Expanded = { parameters: { docs: { description: { - story: "Expanded list layout with vertical cards and Show less toggle.", + story: + "Expanded 2-column stack of 142px CardSelection tiles and Show less toggle.", }, }, }, diff --git a/tests/unit/CardStack.test.jsx b/tests/unit/CardStack.test.jsx index e09253a..4470b72 100644 --- a/tests/unit/CardStack.test.jsx +++ b/tests/unit/CardStack.test.jsx @@ -60,9 +60,23 @@ describe("CardStack Component", () => { test("renders all cards in expanded (list) mode", () => { render(); - expect(screen.getByText("Option A")).toBeInTheDocument(); - expect(screen.getByText("Option B")).toBeInTheDocument(); - expect(screen.getByText("Option C")).toBeInTheDocument(); + expect(screen.getAllByText("Option A").length).toBeGreaterThanOrEqual(1); + expect(screen.getAllByText("Option B").length).toBeGreaterThanOrEqual(1); + expect(screen.getAllByText("Option C").length).toBeGreaterThanOrEqual(1); + }); + + test("expanded tiles use the compact 142px CardSelection height", () => { + render(); + + const tiles = screen.getAllByRole("button", { + name: "Option A: Description A", + }); + expect(tiles.length).toBeGreaterThan(0); + for (const tile of tiles) { + expect(tile.className).toMatch(/142px/); + expect(tile).toHaveClass("flex-col"); + expect(tile).not.toHaveClass("flex-row"); + } }); test("shows See all toggle when hasMore is true", () => {