Card
A container component that displays content in a compact and organized way.
Usage
Team Members
Add new members to your organisation.
import { Stack } from 'styled-system/jsx'
import { Button, Card, FormLabel, Input } from '~/components/ui'
export const Demo = (props: Card.RootProps) => {
return (
<Card.Root width="sm" {...props}>
<Card.Header>
<Card.Title>Team Members</Card.Title>
<Card.Description>Add new members to your organisation.</Card.Description>
</Card.Header>
<Card.Body>
<Stack gap="4">
<Stack gap="1.5">
<FormLabel htmlFor="name">Name</FormLabel>
<Input id="name" placeholder="Name" />
</Stack>
<Stack gap="1.5">
<FormLabel htmlFor="email">Email</FormLabel>
<Input id="email" type="email" placeholder="Email" />
</Stack>
</Stack>
</Card.Body>
<Card.Footer gap="3">
<Button variant="outline">Cancel</Button>
<Button>Invite</Button>
</Card.Footer>
</Card.Root>
)
}
Installation
npx @park-ui/cli components add card
1
Styled Primitive
Copy the code snippet below into ~/components/ui/primitives/card.tsx
'use client'
import type { Assign, PolymorphicProps } from '@ark-ui/react'
import { type HTMLArkProps, ark } from '@ark-ui/react/factory'
import { type CardVariantProps, card } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withProvider, withContext } = createStyleContext(card)
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, PolymorphicProps>, CardVariantProps>
>(ark.div, 'root')
export const Body = withContext<HTMLDivElement, Assign<HTMLStyledProps<'div'>, PolymorphicProps>>(
ark.div,
'body',
)
export const Description = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, PolymorphicProps>
>(ark.div, 'description')
export const Footer = withContext<HTMLDivElement, Assign<HTMLStyledProps<'div'>, PolymorphicProps>>(
ark.div,
'footer',
)
export const Header = withContext<HTMLDivElement, Assign<HTMLStyledProps<'div'>, PolymorphicProps>>(
ark.div,
'header',
)
export const Title = withContext<
HTMLHeadingElement,
Assign<HTMLStyledProps<'h3'>, HTMLArkProps<'h3'>>
>(ark.h3, 'title')
import { type Assign, type PolymorphicProps, ark } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { card } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withProvider, withContext } = createStyleContext(card)
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<Assign<HTMLStyledProps<'div'>, PolymorphicProps<'div'>>>(
ark.div,
'root',
)
export const Body = withContext<Assign<HTMLStyledProps<'div'>, PolymorphicProps<'div'>>>(
ark.div,
'body',
)
export const Description = withContext<Assign<HTMLStyledProps<'div'>, PolymorphicProps<'div'>>>(
ark.div,
'description',
)
export const Footer = withContext<Assign<HTMLStyledProps<'div'>, PolymorphicProps<'div'>>>(
ark.div,
'footer',
)
export const Header = withContext<Assign<HTMLStyledProps<'div'>, PolymorphicProps<'div'>>>(
ark.div,
'header',
)
export const Title = withContext<Assign<HTMLStyledProps<'h3'>, PolymorphicProps<'h3'>>>(
ark.h3,
'title',
)
import { type AccordionVariantProps, card } from 'styled-system/recipes'
import type { Assign, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withProvider, withContext } = createStyleContext(card)
export interface RootProps extends Assign<HTMLStyledProps<'div'>, AccordionVariantProps> {}
export const Root = withProvider<RootProps>('div', 'root')
export const Header = withContext<HTMLStyledProps<'div'>>('div', 'header')
export const Body = withContext<HTMLStyledProps<'div'>>('div', 'body')
export const Footer = withContext<HTMLStyledProps<'div'>>('div', 'footer')
export const Title = withContext<HTMLStyledProps<'h3'>>('h3', 'title')
export const Description = withContext<HTMLStyledProps<'div'>>('div', 'description')
Extend ~/components/ui/primitives/index.ts
with the following line:
export * as Card from './card'
2
Integrate Recipe
If you're not using @park-ui/preset
, add the following recipe to yourpanda.config.ts
:
import { defineSlotRecipe } from '@pandacss/dev'
export const card = defineSlotRecipe({
className: 'card',
slots: ['root', 'header', 'body', 'footer', 'title', 'description'],
base: {
root: {
bg: 'bg.default',
borderRadius: 'l3',
boxShadow: 'lg',
display: 'flex',
flexDirection: 'column',
overflow: 'hidden',
position: 'relative',
},
header: {
display: 'flex',
flexDirection: 'column',
gap: '1',
p: '6',
},
body: {
display: 'flex',
flex: '1',
flexDirection: 'column',
pb: '6',
px: '6',
},
footer: {
display: 'flex',
justifyContent: 'flex-end',
pb: '6',
pt: '2',
px: '6',
},
title: {
color: 'fg.default',
textStyle: 'lg',
fontWeight: 'semibold',
},
description: {
color: 'fg.muted',
textStyle: 'sm',
},
},
})