Skip to content

styling: cards #1182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export const LendTableFooter = () => (
paddingInline: Spacing.lg,
paddingBlockStart: Spacing.lg,
paddingBlockEnd: Spacing.sm,
backgroundColor: (t) => t.design.Layer[1].Fill,
}}
>
<Grid container spacing={Spacing.lg} rowGap={Spacing.md}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { shortenAddress } from '@ui-kit/utils'
const { Spacing } = SizesAndSpaces

const AdvancedDetails = () => (
<Card sx={{ backgroundColor: (t) => t.design.Layer[1].Fill, boxShadow: 'none' }}>
<Card>
<CardHeader
size="small"
title={t`Advanced Details`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,7 @@ const Statistics = ({ isChartExpanded, toggleChartExpanded, hideExpandChart }: S
: MaxWidth.section,
}}
>
<Card
sx={{
backgroundColor: (t) => t.design.Layer[1].Fill,
boxShadow: 'none',
}}
elevation={0}
>
<Card elevation={0}>
<CardHeader title="Statistics" />
<Box sx={{ padding: Spacing.md, marginBottom: smallView ? Spacing.xl : 0 }}>
<StatsStack />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,7 @@ const UserPosition = ({ chartExpanded = false }: { chartExpanded?: boolean }) =>
: undefined

return (
<Card
sx={{
width: '100%',
maxWidth: chartExpanded ? '100%' : MaxWidth.section,
backgroundColor: (t) => t.design.Layer[1].Fill,
boxShadow: 'none',
}}
>
<Card sx={{ width: '100%', maxWidth: chartExpanded ? '100%' : MaxWidth.section }}>
<CardHeader title={t`Position Details`} />
<Stack padding={Spacing.md} gap={Spacing.md}>
<Grid
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="./mui-card-header.d.ts" />
import type { Components, TypographyVariantsOptions } from '@mui/material/styles'
import { handleBreakpoints } from '@ui-kit/themes/basic-theme'
import { DesignSystem } from '@ui-kit/themes/design'
import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces'

Expand All @@ -11,9 +12,14 @@ export const defineMuiCardHeader = (
): Components['MuiCardHeader'] => ({
styleOverrides: {
root: {
padding: `${Spacing.lg.desktop} ${Spacing.md.desktop} ${Spacing.sm.desktop}`,
...handleBreakpoints({
paddingBlockStart: Spacing.lg,
paddingBlockEnd: Spacing.sm,
paddingInline: Spacing.md,
}),
borderBottom: `1px solid ${design.Layer[3].Outline}`,
minHeight: `calc(${ButtonSize.lg} + 1px)`, // 1px to account for border
'& .MuiCardHeader-avatar': handleBreakpoints({ marginRight: Spacing.md }),
variants: [
{
props: { size: 'small' },
Expand Down
4 changes: 4 additions & 0 deletions packages/curve-ui-kit/src/themes/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { defineMuiCardHeader } from './card-header'
import { defineMuiCheckbox } from './checkbox'
import { defineMuiChip } from './chip'
import { defineMuiAlert, defineMuiAlertTitle } from './mui-alert'
import { defineMuiCard } from './mui-card'
import { defineMuiCardContent } from './mui-card-content'
import { defineMuiMenuItem } from './mui-menu-item'
import { defineMuiSelect } from './mui-select'
import { defineMuiSwitch } from './mui-switch'
Expand All @@ -34,6 +36,8 @@ export const createComponents = (
disableRipple: true,
},
},
MuiCard: defineMuiCard(design),
MuiCardContent: defineMuiCardContent(),
MuiCardHeader: defineMuiCardHeader(design, typography),
MuiCardActions: {
styleOverrides: {
Expand Down
14 changes: 14 additions & 0 deletions packages/curve-ui-kit/src/themes/components/mui-card-content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Components } from '@mui/material/styles'
import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces'
import { handleBreakpoints } from '../basic-theme'

const { Spacing } = SizesAndSpaces

export const defineMuiCardContent = (): Components['MuiCardContent'] => ({
styleOverrides: {
root: {
...handleBreakpoints({ padding: Spacing.md }),
'&:last-child': handleBreakpoints({ padding: Spacing.md }),
},
},
})
11 changes: 11 additions & 0 deletions packages/curve-ui-kit/src/themes/components/mui-card.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Components } from '@mui/material/styles'
import { DesignSystem } from '@ui-kit/themes/design'

export const defineMuiCard = (design: DesignSystem): Components['MuiCard'] => ({
styleOverrides: {
root: {
backgroundColor: design.Layer[1].Fill,
boxShadow: 'none',
},
},
})
124 changes: 124 additions & 0 deletions packages/curve-ui-kit/src/themes/stories/Card.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import Avatar from '@mui/material/Avatar'
import Button from '@mui/material/Button'
import Card from '@mui/material/Card'
import type { CardProps } from '@mui/material/Card'
import CardActions from '@mui/material/CardActions'
import CardContent from '@mui/material/CardContent'
import CardHeader from '@mui/material/CardHeader'
import CardMedia from '@mui/material/CardMedia'
import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
import type { Meta, StoryObj } from '@storybook/react'
import { TokenPair } from '@ui-kit/shared/ui/TokenPair'
import { SizesAndSpaces } from '../design/1_sizes_spaces'

const { Spacing } = SizesAndSpaces

const CardStory = (props: CardProps) => (
<Card sx={{ maxWidth: '20rem' }} {...props}>
<CardHeader
avatar={<Avatar sx={{ bgcolor: 'primary.main' }}>L</Avatar>}
title="Llama Card"
subheader="September 14, 2024"
/>

<CardMedia
component="img"
height="200"
image="https://images.unsplash.com/photo-1511885663737-eea53f6d6187"
alt="Llama image"
/>

<CardContent>
<Typography variant="bodySRegular" color="textSecondary">
This impressive llama is a perfect example of the species. Llamas are domesticated South American camelids.
</Typography>
</CardContent>

<CardActions disableSpacing>
<Stack direction="row" gap={Spacing.xs} flexGrow={1}>
<Button fullWidth>Share</Button>
<Button fullWidth color="secondary">
Learn More
</Button>
</Stack>
</CardActions>
</Card>
)

const CardStorySimple = (props: CardProps) => (
<Card sx={{ maxWidth: '20rem' }} {...props}>
<CardHeader title="Simple card" />

<CardContent>
<Typography variant="bodySRegular" color="textSecondary">
A simple card with just content. Perfect for displaying basic information about llamas and their habitat.
</Typography>
</CardContent>

<CardActions>
<Button fullWidth>Action</Button>
</CardActions>
</Card>
)

const CardStoryHeaderOnly = (props: CardProps) => (
<Card sx={{ maxWidth: '20rem' }} {...props}>
<CardHeader title="Header Only Card" subheader="With subtitle" />

<CardContent>
<Typography variant="bodySRegular" color="text.secondary">
This card focuses on the header section with a clean content area below.
</Typography>
</CardContent>
</Card>
)

const CardStoryTokenPairAvatar = (props: CardProps) => (
<Card sx={{ maxWidth: '20rem' }} {...props}>
<CardHeader
avatar={
<TokenPair
hideChainIcon
chain="ethereum"
assets={{
primary: { symbol: 'crvUSD', address: '0xf939e0a03fb07f59a73314e73794be0e57ac1b4e' },
secondary: { symbol: 'USDC', address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' },
}}
/>
}
title="USDC/crvUSD"
/>

<CardContent>
<Typography variant="headingSBold">Simple Card</Typography>
<Typography variant="bodySRegular" color="textSecondary">
A simple card with just content. Perfect for displaying basic information about llamas and their habitat.
</Typography>
</CardContent>

<CardActions>
<Button fullWidth>Action</Button>
</CardActions>
</Card>
)

const meta: Meta<typeof CardStory> = {
title: 'UI Kit/Primitives/Card',
argTypes: {
variant: {
control: 'select',
options: ['elevation', 'outlined'],
description: 'The variant of the component',
},
},
}

type Story = StoryObj<typeof CardStory>

export const Default: Story = { render: (args) => <CardStory {...args} /> }
export const Simple: Story = { render: (args) => <CardStorySimple {...args} /> }
export const HeaderOnly: Story = { render: (args) => <CardStoryHeaderOnly {...args} /> }
export const TokenPairAvatar: Story = { render: (args) => <CardStoryTokenPairAvatar {...args} /> }

export default meta