Card
A flexible card component for grouping related content with optional headers, footers, and interactive states.
Import
import PrettyUI
Basic Usage
PCard {
Text("This is card content.")
}
Variants
PCard supports 3 visual variants:
// Standard - subtle shadow (default)
PCard {
Text("Standard card")
}.variant(.standard)
// Elevated - larger shadow for floating appearance
PCard {
Text("Elevated card")
}.variant(.elevated)
// Flat - no shadow, border only
PCard {
Text("Flat card")
}.variant(.flat)
| Variant | Shadow | Border | Best For |
|---|---|---|---|
.standard | Small | Optional | Most use cases |
.elevated | Large | None | Featured content, floating elements |
.flat | None | Yes | Subtle grouping, forms |
With Header
Add a title and optional description:
PCard {
Text("Your card content here...")
} header: {
PCardTitle("Settings", description: "Manage your preferences")
}
Custom Header
PCard {
Text("Content...")
} header: {
HStack {
Image(systemName: "star.fill")
.foregroundColor(.yellow)
Text("Featured")
.font(.headline)
Spacer()
PIconButton("ellipsis") {}
}
}
With Footer
Add action buttons or supplementary content:
PCard {
VStack(alignment: .leading, spacing: 8) {
Text("Email")
.font(.caption)
.foregroundColor(.gray)
Text("john@example.com")
}
} header: {
PCardTitle("Account")
} footer: {
HStack {
Spacer()
PButton("Cancel").variant(.ghost)
PButton("Save").variant(.primary)
}
}
Pressable Cards
Make cards interactive with tap gestures:
PCard {
HStack {
VStack(alignment: .leading, spacing: 4) {
Text("Main Wallet")
.font(.headline)
Text("0x1234...5678")
.font(.caption)
.foregroundColor(.gray)
}
Spacer()
Text("$10,234.56")
.font(.title2)
.fontWeight(.semibold)
}
}
.pressable {
print("Wallet tapped!")
}
Selected State
Highlight selected cards with a border:
PCard {
HStack {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
Text("Premium Plan")
Spacer()
Text("$9.99/mo")
}
}
.selected(isSelected)
// With custom border color
.selected(isSelected, borderColor: .purple)
Custom Padding
Control padding independently:
// Both horizontal and vertical
PCard {
Text("Content")
}
.padding(horizontal: .xl, vertical: .sm)
// Individual axis
PCard {
Text("Content")
}
.paddingHorizontal(.lg)
.paddingVertical(.xs)
Real-World Examples
Wallet Card
PCard {
HStack {
VStack(alignment: .leading, spacing: 4) {
Text("Main Wallet")
.font(.headline)
Text("0x1234...5678")
.font(.caption)
.foregroundColor(.gray)
}
Spacer()
Text("$10,234.56")
.font(.title2)
.fontWeight(.semibold)
}
}
.variant(.elevated)
.pressable {
openWallet()
}
Settings Card
PCard {
VStack(spacing: 0) {
SettingsRow(icon: "bell", title: "Notifications")
Divider()
SettingsRow(icon: "lock", title: "Privacy")
Divider()
SettingsRow(icon: "paintbrush", title: "Appearance")
}
} header: {
PCardTitle("Preferences")
}
.paddingVertical(.xs)
Selection Card
ForEach(plans) { plan in
PCard {
HStack {
VStack(alignment: .leading) {
Text(plan.name).font(.headline)
Text(plan.description).font(.caption)
}
Spacer()
Text(plan.price)
}
}
.selected(selectedPlan == plan.id)
.pressable {
selectedPlan = plan.id
}
}
API Reference
Initializers
// Content only
PCard(
radius: RadiusSize? = nil,
shadow: ShadowSize? = nil,
padding: SpacingSize? = nil,
@ViewBuilder content: () -> Content
)
// With header
PCard(
@ViewBuilder content: () -> Content,
@ViewBuilder header: () -> Header
)
// With header and footer
PCard(
@ViewBuilder content: () -> Content,
@ViewBuilder header: () -> Header,
@ViewBuilder footer: () -> Footer
)
Modifiers
| Modifier | Type | Description |
|---|---|---|
.variant(_:) | PCardVariant | Visual style |
.pressable(_:) | () -> Void | Make card tappable |
.selected(_:borderColor:) | Bool, Color? | Selection state |
.paddingHorizontal(_:) | SpacingSize | Horizontal padding |
.paddingVertical(_:) | SpacingSize | Vertical padding |
.padding(horizontal:vertical:) | SpacingSize | Both axes |
Enums
PCardVariant
.standard— Default with subtle shadow.elevated— Large shadow, floating appearance.flat— Border only, no shadow
Helper Components
PCardTitle
PCardTitle(_ title: String, description: String? = nil)
Styled title with optional description for card headers.
PCardHeader
PCardHeader {
// Custom header content
}
Wrapper with proper styling for custom headers.
PCardFooter
PCardFooter {
// Custom footer content
}
Wrapper with muted styling for footer content.
Accessibility
PCard automatically:
- Groups content logically for VoiceOver
- Announces pressable cards as buttons
- Shows visual feedback for selected state