From f3e3084d15b57c4e57ea6b12d70d0aa94135fe10 Mon Sep 17 00:00:00 2001 From: Philip Levy Date: Tue, 21 Jul 2026 15:32:21 -0400 Subject: [PATCH 1/2] feat(CardLayout): add flex-col internals for vertical alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CardLayout now uses flex flex-col on the outer div and flex-1 flex flex-col on the inner content wrapper. This lets children use mt-auto to pin footer content to the bottom when cards stretch to equal height in a row. No new props required — just add mt-auto to your footer element. Added VerticalAlignment story demonstrating food-menu and pricing-card patterns. Closes #110 --- src/components/Card/Card.stories.tsx | 110 +++++++++++++++++++++++++++ src/components/Card/CardLayout.tsx | 5 +- 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/src/components/Card/Card.stories.tsx b/src/components/Card/Card.stories.tsx index 32c7768..d22af4f 100644 --- a/src/components/Card/Card.stories.tsx +++ b/src/components/Card/Card.stories.tsx @@ -1,5 +1,8 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { CardLayout } from "./CardLayout"; +import { HeadingField } from "../Heading/HeadingField"; +import { RichTextDisplayField } from "../RichText/RichTextDisplayField"; +import { ButtonWidget } from "../Button/ButtonWidget"; const meta = { title: "Components/Card", @@ -235,6 +238,113 @@ export const BorderAndShadow: Story = { }, }; +export const VerticalAlignment: Story = { + args: { children: null }, + parameters: { layout: "padded" }, + render: () => ( +
+
+

+ Cards use flex flex-col internally. + Put mt-auto on your footer element to pin it to the bottom when cards stretch to equal height. +

+
+ + {/* Food menu pattern */} +
+

Variable content, footer pinned to bottom

+
+ +
+ + +
+ $6.99 + +
+
+ + +
+ + +
+ $8.00 + +
+
+ + +
+ + +
+ $8.50 + +
+
+ + +
+ + +
+ $7.00 + +
+
+
+
+ + {/* Pricing pattern */} +
+

Variable feature list, button at bottom

+
+ + + +
    +
  • ✓ 5 projects
  • +
  • ✓ Basic analytics
  • +
+
+ +
+
+ + + + +
    +
  • ✓ Unlimited projects
  • +
  • ✓ Advanced analytics
  • +
  • ✓ Team collaboration
  • +
  • ✓ Priority support
  • +
  • ✓ Custom integrations
  • +
+
+ +
+
+ + + + +
    +
  • ✓ Everything in Pro
  • +
  • ✓ SSO & SAML
  • +
  • ✓ Dedicated support
  • +
+
+ +
+
+
+
+
+ ), +}; + export const CardStyles: Story = { args: { children: null }, render: () => ( diff --git a/src/components/Card/CardLayout.tsx b/src/components/Card/CardLayout.tsx index 0a6026f..f5e25cd 100644 --- a/src/components/Card/CardLayout.tsx +++ b/src/components/Card/CardLayout.tsx @@ -174,7 +174,8 @@ export const CardLayout: React.FC = ({ marginBelowMap[marginBelow], showBorder ? `border ${borderProps.className || ''}` : '', showShadow ? 'shadow-md' : '', - 'relative' + 'relative', + 'flex flex-col' ].filter(Boolean).join(' ') // Merge with optional className override @@ -202,7 +203,7 @@ export const CardLayout: React.FC = ({ aria-hidden="true" /> )} -
+
{children}
From 1dff4aa18f78852d7aaeb0380363b2c0350d6379 Mon Sep 17 00:00:00 2001 From: Philip Levy Date: Tue, 21 Jul 2026 16:18:08 -0400 Subject: [PATCH 2/2] Syntax and style tweaks on story --- src/components/Card/Card.stories.tsx | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/components/Card/Card.stories.tsx b/src/components/Card/Card.stories.tsx index d22af4f..cde35c9 100644 --- a/src/components/Card/Card.stories.tsx +++ b/src/components/Card/Card.stories.tsx @@ -2,6 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { CardLayout } from "./CardLayout"; import { HeadingField } from "../Heading/HeadingField"; import { RichTextDisplayField } from "../RichText/RichTextDisplayField"; +import { TextItem } from "../RichText/TextItem"; import { ButtonWidget } from "../Button/ButtonWidget"; const meta = { @@ -256,41 +257,41 @@ export const VerticalAlignment: Story = {
- - + + ]} marginBelow="NONE" className="[&>div]:leading-tight!" />
- $6.99 - + ]} marginBelow="NONE" /> +
- - + + ]} marginBelow="NONE" className="[&>div]:leading-tight!" />
$8.00 - +
- - + + ]} marginBelow="NONE" className="[&>div]:leading-tight!" />
$8.50 - +
- - + + ]} marginBelow="NONE" className="[&>div]:leading-tight!" />
$7.00 - +
@@ -301,7 +302,7 @@ export const VerticalAlignment: Story = {

Variable feature list, button at bottom

- +
  • ✓ 5 projects
  • @@ -313,7 +314,7 @@ export const VerticalAlignment: Story = { - +
    • ✓ Unlimited projects
    • @@ -328,7 +329,7 @@ export const VerticalAlignment: Story = { - +
      • ✓ Everything in Pro