diff --git a/packages/odyssey-react-mui/src/Card.tsx b/packages/odyssey-react-mui/src/Card.tsx
index f223b23e0..cf272b257 100644
--- a/packages/odyssey-react-mui/src/Card.tsx
+++ b/packages/odyssey-react-mui/src/Card.tsx
@@ -36,15 +36,18 @@ import {
useOdysseyDesignTokens,
} from "./OdysseyDesignTokensContext.js";
import { Heading5, Paragraph, Support } from "./Typography.js";
-import { Box } from "./Box.js";
export const CARD_IMAGE_HEIGHT = "64px";
+export const CARD_IMAGE_HEIGHT_COMPACT = "48px";
+
+export const cardVariantValues = ["tile", "stack", "compact"] as const;
export type CardProps = {
description?: string;
image?: ReactElement;
overline?: string;
title?: string;
+ variant?: (typeof cardVariantValues)[number];
} & (
| {
onClick: MouseEventHandler;
@@ -60,31 +63,68 @@ export type CardProps = {
const ImageContainer = styled("div", {
shouldForwardProp: (prop) =>
- prop !== "odysseyDesignTokens" && prop !== "hasMenuButtonChildren",
+ prop !== "odysseyDesignTokens" &&
+ prop !== "hasMenuButtonChildren" &&
+ prop !== "variant",
})<{
odysseyDesignTokens: DesignTokens;
hasMenuButtonChildren: boolean;
-}>(({ odysseyDesignTokens, hasMenuButtonChildren }) => ({
+ variant: (typeof cardVariantValues)[number];
+}>(({ odysseyDesignTokens, hasMenuButtonChildren, variant }) => ({
display: "flex",
alignItems: "flex-start",
- maxHeight: CARD_IMAGE_HEIGHT,
- height: CARD_IMAGE_HEIGHT,
- marginBlockEnd: odysseyDesignTokens.Spacing5,
- paddingRight: hasMenuButtonChildren ? odysseyDesignTokens.Spacing5 : 0,
+ height: variant === "compact" ? CARD_IMAGE_HEIGHT_COMPACT : CARD_IMAGE_HEIGHT,
+ maxHeight:
+ variant === "compact" ? CARD_IMAGE_HEIGHT_COMPACT : CARD_IMAGE_HEIGHT,
+ marginBlockEnd: variant === "tile" ? odysseyDesignTokens.Spacing5 : 0,
+ paddingRight:
+ hasMenuButtonChildren || ["stack", "compact"].includes(variant)
+ ? odysseyDesignTokens.Spacing5
+ : 0,
}));
const MenuButtonContainer = styled("div", {
shouldForwardProp: (prop) => prop !== "odysseyDesignTokens",
-})<{ odysseyDesignTokens: DesignTokens }>(({ odysseyDesignTokens }) => ({
+})<{
+ odysseyDesignTokens: DesignTokens;
+ variant: (typeof cardVariantValues)[number];
+}>(({ odysseyDesignTokens, variant }) => ({
position: "absolute",
right: odysseyDesignTokens.Spacing3,
- top: odysseyDesignTokens.Spacing3,
+ top:
+ variant === "compact"
+ ? odysseyDesignTokens.Spacing4
+ : odysseyDesignTokens.Spacing3,
+ height: variant === "compact" ? CARD_IMAGE_HEIGHT_COMPACT : "auto",
+ display: "flex",
+ alignItems: "center",
}));
const CardContentContainer = styled("div")(() => ({
display: "flex",
}));
+const CardImageAndContentContainer = styled("div", {
+ shouldForwardProp: (prop) => prop !== "variant",
+})<{ variant: (typeof cardVariantValues)[number] }>(({ variant }) => ({
+ display: "flex",
+ flexDirection: variant === "tile" ? "column" : "row",
+}));
+
+const CardContent = styled("div", {
+ shouldForwardProp: (prop) => prop !== "odysseyDesignTokens",
+})<{
+ odysseyDesignTokens: DesignTokens;
+ variant: (typeof cardVariantValues)[number];
+}>(({ odysseyDesignTokens, variant }) => ({
+ "& > .MuiTypography-h5:not(:last-child)": {
+ marginBlockEnd: `${variant === "compact" ? odysseyDesignTokens.Spacing1 : odysseyDesignTokens.Spacing3} !important`,
+ },
+ "& > *:last-child": {
+ marginBlockEnd: 0,
+ },
+}));
+
const buttonProviderValue = { isFullWidth: true };
const Card = ({
@@ -95,36 +135,43 @@ const Card = ({
onClick,
overline,
title,
+ variant = "tile",
}: CardProps) => {
const odysseyDesignTokens = useOdysseyDesignTokens();
const cardContent = useMemo(
() => (
-
+
{image && (
{image}
)}
- {overline && {overline}}
- {title && {title}}
- {description && (
- {description}
- )}
-
- {button && (
-
-
- {button}
-
-
- )}
-
+
+ {overline && {overline}}
+ {title && {title}}
+ {description && (
+ {description}
+ )}
+
+ {button && (
+
+
+ {button}
+
+
+ )}
+
+
),
[
@@ -135,11 +182,12 @@ const Card = ({
overline,
title,
odysseyDesignTokens,
+ variant,
],
);
return (
-
+
{onClick ? (
{cardContent}
) : (
@@ -147,7 +195,10 @@ const Card = ({
)}
{menuButtonChildren && (
-
+
}
ariaLabel="Card menu"
diff --git a/packages/odyssey-storybook/src/components/odyssey-mui/Card/Card.stories.tsx b/packages/odyssey-storybook/src/components/odyssey-mui/Card/Card.stories.tsx
index 6aab655a9..bec55a2b9 100644
--- a/packages/odyssey-storybook/src/components/odyssey-mui/Card/Card.stories.tsx
+++ b/packages/odyssey-storybook/src/components/odyssey-mui/Card/Card.stories.tsx
@@ -196,3 +196,47 @@ export const ButtonWithoutImage: Story = {
),
};
+
+export const TileVariant: Story = {
+ render: (args) => {
+ return (
+
+ }
+ variant="tile"
+ />
+
+ );
+ },
+};
+
+export const StackVariant: Story = {
+ render: (args) => {
+ return (
+ }
+ variant="stack"
+ />
+ );
+ },
+};
+
+export const CompactVariant: Story = {
+ render: (args) => {
+ return (
+ }
+ variant="compact"
+ />
+ );
+ },
+};