Card
Usage
Card component is a wrapper around Paper component with context styles for Card.Section component. Combine Card component with other Mantine components to create cards with your design requirements:
import React from 'react';import { Card, Image, Text, Badge, Button, Group, useMantineTheme } from '@mantine/core';function Demo() {const theme = useMantineTheme();const secondaryColor = theme.colorScheme === 'dark'? theme.colors.dark[1]: theme.colors.gray[7];return (<div style={{ width: 340, margin: 'auto' }}><Card shadow="sm" padding="lg"><Card.Section><Image src="./image.png" height={160} alt="Norway" /></Card.Section><Group position="apart" style={{ marginBottom: 5, marginTop: theme.spacing.sm }}><Text weight={500}>Norway Fjord Adventures</Text><Badge color="pink" variant="light">On Sale</Badge></Group><Text size="sm" style={{ color: secondaryColor, lineHeight: 1.5 }}>With Fjord Tours you can explore more of the magical fjord landscapes with tours andactivities on and around the fjords of Norway</Text><Button variant="light" color="blue" fullWidth style={{ marginTop: 14 }}>Book classic tour now</Button></Card></div>);}
Card.Section
Card.Section is a special component that is used to remove Card padding from its children while other elements still have horizontal spacing. Card.Section works the following way:
- It component is a first child in Card then it has negative top, left and right margins
- If it is a last child in Card then it has negative bottom, left and right margins
- If it is in the middle then only left and right margins will be negative
<Card padding="xl">{/* top, right, left margins are negative – -1 * theme.spacing.xl */}<Card.Section>First section</Card.Section>{/* Content that is not inside Card.Section will have theme.spacing.xl spacing on all sides relative to Card */}<Text>Some other content</Text>{/* right, left margins are negative – -1 * theme.spacing.xl */}<Card.Section>Middle section</Card.Section>{/* bottom, right, left margins are negative – -1 * theme.spacing.xl */}<Card.Section>Last section</Card.Section></Card>
Note that Card relies on mapping direct children and you cannot use fragments or others wrappers for Card.Section:
<Card padding="xl"><div><Card.Section>Won't work</Card.Section></div><><Card.Section>Won't work either</Card.Section></><Card.Section>Works fine</Card.Section></Card>
Custom root element
You can set component
prop on Card to use provide custom root element,
for example, you can make whole card a link:
<Cardshadow="sm"padding="xl"component="a"href="https://www.youtube.com/watch?v=dQw4w9WgXcQ"target="_blank"><Card.Section><Image src="unsplash.png" height={160} alt="No way!" /></Card.Section><Text weight={500} size="lg">You've won a million dollars in cash!</Text><Text size="sm">Please click anywhere on this card to claim your reward, this is not a fraud, trust us</Text></Card>
You can also use React component instead of an element, for example, Link from react-router-dom:
import { Link } from 'react-router-dom';import { Card } from '@mantine/core';function Demo() {return <Card component={Link} to="/my-route/" />;}
Usage with Next Link
Next Link component requires ref
prop usage, however all Mantine components use elementRef
,
to make Card and other similar components work with Next Link, create wrapper component in your components folder:
// This component can be reused in every Mantine component which supports component pass throughimport React, { forwardRef } from 'react';import Link from 'next/link';export const NextLink = forwardRef(({ href, ...others }: React.ComponentPropsWithoutRef<typeof Link>,ref: React.ForwardedRef<HTMLAnchorElement>) => (<Link href={href}>{/* eslint-disable-next-line jsx-a11y/anchor-has-content */}<a {...others} ref={ref} /></Link>));
And then pass it to Card or other component:
<Card component={NextLink} href="/hello" />
Get element ref
You can get root element ref by setting elementRef
prop:
import { useRef } from 'react';import { Card } from '@mantine/core';function Demo() {const ref = useRef();return <Card elementRef={ref} />;}
TypeScript
You need to pass additional types to use custom component with TypeScript
in case you need full type coverage for events and elementRef
:
// With element<Card<'a', HTMLAnchorElement>component="a"onClick={(event) => console.log(event)}elementRef={(node) => {window.myRef = node;}}/>// With component<Card<typeof Link, HTMLAnchorElement>component={Link}onClick={(event) => console.log(event)}elementRef={(node) => {window.myRef = node;}}/>