Patterns
Settings Surface
When to use:
- A small set of related settings should share one surface.
Composition notes:
- Use headings and internal spacing explicitly.
- Keep the surface responsible for grouping, not for every spacing decision.
Trade-offs:
- Strong visual grouping.
- Easy to overuse as generic padding wrappers.
settings-form-card.tsx · 42 lines
import { FormEvent, useState } from 'react';
import { Button, Card, Heading, Label, Text, TextField, TextFieldInput } from '@vega-ui/react';
export default function SettingsFormCard() {
const [saved, setSaved] = useState('');
const submit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
setSaved(`Saved “${data.get('workspace')}” at ${data.get('slug')}.vega.app`);
};
Metrics Or Summary Surface
When to use:
- A dashboard or billing view needs grouped summary content.
Composition notes:
- Keep key metrics visually prominent within the card.
- Use content hierarchy, not only surface styling.
Trade-offs:
- Good for summaries and grouped metadata.
- Weak fit when the content is really just one inline label.
metrics-card.tsx · 32 lines
import { useState } from 'react';
import { Button, Card, Heading, Spinner, Text } from '@vega-ui/react';
const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
export default function MetricsCard() {
const [revenue, setRevenue] = useState(48210.4);
const [updatedAt, setUpdatedAt] = useState('09:00');
const [loading, setLoading] = useState(false);
const refresh = () => {
setLoading(true);Navigational Surface
When to use:
- One grouped surface should navigate to a deeper screen.
Composition notes:
- Use
asChildwith a real anchor or router link. - Keep the destination understandable from the card content.
Trade-offs:
- Good for dashboard entry points.
- Easy to blur layout and navigation semantics if overused.
link-cards.tsx · 27 lines
import { Card, Heading, Text } from '@vega-ui/react';
import './examples.css';
const destinations = [
{ href: '#billing', title: 'Billing', description: 'Plan, invoices and payment methods.' },
{ href: '#members', title: 'Members', description: '18 members, 3 pending invitations.' },
{ href: '#security', title: 'Security', description: 'Two-factor authentication, sessions and SSO.' },
];
export default function LinkCards() {
return (
<nav aria-label='Workspace settings' style={{ width: '100%' }}>Comparison
Quick Decision Rule
Use Card when grouped content needs a surface container.
Card vs Alert
Use Card when:
- the content is grouped layout, not a feedback message
Use Alert when:
- the content is a short semantic feedback or status message
Main trade-off: card is a content surface, while alert is message-oriented feedback.
Card vs Badge
Use Card when:
- multiple pieces of related content need grouping
Use Badge when:
- only a tiny status or category label is needed
Main trade-off: card is a container, while badge is a compact label.
Card vs Fieldset
Use Card when:
- the grouping is layout or presentation
Use Fieldset when:
- the grouping is semantic form structure
Choose This Component When
- Grouped content needs a distinct surface.
- The layout benefits from one bounded container.
- Headings, metrics, or settings should feel related.
- the component should stay neutral rather than encode feedback or status semantics
Do Not Choose This Component When
- The content is just a short feedback message.
- The UI only needs a tiny status label.
- Surface styling would be the only source of hierarchy.
Troubleshooting
Card Content Feels Unstructured
Symptom
The surface exists, but users still cannot scan the content clearly.
Likely Cause
The card is being used as a generic wrapper without internal heading or spacing structure.
How To Verify
- Hide the card border mentally and inspect the remaining content hierarchy.
Fix
- Add headings, spacing, and clearer inner layout.
- Treat the card as grouping, not as the whole information architecture.
Transparent Card Disappears Into The Background
Symptom
The grouped surface loses separation and feels visually flat.
Likely Cause
appearance='transparent' is used on a low-contrast or noisy background.
How To Verify
- Compare the transparent card against the real parent surface.
Fix
- Switch back to
outline. - Strengthen the parent surface contrast or content hierarchy.