Accordion
A collapsible content component with fluid spring animations. Perfect for FAQs, settings panels, and progressive disclosure patterns.
Import
import PrettyUI
Basic Usage
PAccordion {
PAccordionItem("What is PrettyUI?") {
Text("PrettyUI is a SwiftUI component library...")
}
PAccordionItem("How do I get started?") {
Text("Simply import PrettyUI and start using components...")
}
PAccordionItem("Is it customizable?") {
Text("Yes! PrettyUI uses a comprehensive theming system...")
}
}
Variants
Three visual styles are available:
// Standard - connected items with shared background
PAccordion {
// items...
}
.variant(.standard)
// Bordered - items share a border
PAccordion {
// items...
}
.variant(.bordered)
// Separated - each item is a separate card
PAccordion {
// items...
}
.variant(.separated)
| Variant | Style | Best For |
|---|---|---|
.standard | Connected, shared background | FAQs, documentation |
.bordered | Shared container with border | Steps, tutorials |
.separated | Individual cards with gaps | Settings, distinct sections |
Expansion Mode
Control how items expand:
// Multiple items can be open (default)
PAccordion {
// items...
}
.expansionMode(.multiple)
// Only one item open at a time
PAccordion {
// items...
}
.expansionMode(.single)
With Icons
Add icons to accordion items:
PAccordion {
PAccordionItem("Account", icon: "person.circle.fill") {
Text("Manage your account settings...")
}
PAccordionItem("Notifications", icon: "bell.fill") {
Text("Configure notification preferences...")
}
PAccordionItem("Privacy", icon: "lock.shield.fill") {
Text("Review privacy settings...")
}
}
.variant(.separated)
Custom Icon Colors
PAccordionItem("Important", icon: "exclamationmark.triangle.fill", iconColor: .orange) {
Text("This requires your attention...")
}
With Subtitles
Add a subtitle for additional context:
PAccordionItem("Notifications", subtitle: "3 unread", icon: "bell.fill") {
Text("You have new notifications...")
}
Initially Expanded
Set items to start expanded:
PAccordionItem("First Section") {
Text("This section starts expanded...")
}
.expanded(true)
Hide Dividers
Control dividers between items:
// For the last item in a standard/bordered accordion
PAccordionItem("Last Item") {
Text("Content...")
}
.showDivider(false)
Standalone Accordion Item
Use a single accordion item outside a container:
PStandaloneAccordionItem(
"Advanced Options",
subtitle: "For power users",
icon: "slider.horizontal.3"
) {
VStack(alignment: .leading, spacing: 12) {
Text("Configure advanced settings...")
HStack {
PButton("Reset").variant(.destructive).size(.sm)
PButton("Save").variant(.primary).size(.sm)
}
}
}
Standalone Modifiers
PStandaloneAccordionItem("Title") {
// content...
}
.radius(.xl)
.showBorder(true)
Custom Content
Items can contain any SwiftUI views:
PAccordionItem("Profile Settings", icon: "person.fill") {
VStack(alignment: .leading, spacing: 16) {
HStack {
Text("Username")
Spacer()
Text("@johndoe")
.foregroundColor(.secondary)
}
Divider()
HStack {
Text("Email")
Spacer()
Text("john@example.com")
.foregroundColor(.secondary)
}
Divider()
PButton("Edit Profile") {
// Handle edit
}
.variant(.outline)
.fullWidth()
}
}
Real-World Examples
FAQ Section
PAccordion {
PAccordionItem("What payment methods do you accept?") {
Text("We accept Visa, Mastercard, American Express, and PayPal.")
}
PAccordionItem("How long does shipping take?") {
Text("Standard shipping takes 5-7 business days. Express shipping is 2-3 days.")
}
PAccordionItem("What is your return policy?") {
Text("You can return items within 30 days for a full refund.")
}
.showDivider(false)
}
Settings Panel
PAccordion {
PAccordionItem("Account", subtitle: "Profile, security", icon: "person.circle.fill") {
VStack(spacing: 12) {
SettingRow(title: "Edit Profile", icon: "pencil")
SettingRow(title: "Change Password", icon: "lock")
SettingRow(title: "Two-Factor Auth", icon: "shield")
}
}
.expanded(true)
PAccordionItem("Notifications", subtitle: "3 enabled", icon: "bell.fill") {
VStack(spacing: 12) {
Toggle("Push Notifications", isOn: $pushEnabled)
Toggle("Email Notifications", isOn: $emailEnabled)
Toggle("Marketing", isOn: $marketingEnabled)
}
}
PAccordionItem("Privacy", icon: "lock.shield.fill") {
VStack(spacing: 12) {
Toggle("Share Analytics", isOn: $analytics)
Toggle("Personalized Ads", isOn: $ads)
}
}
}
.variant(.separated)
.expansionMode(.single)
Onboarding Steps
PAccordion {
PAccordionItem("Step 1: Create Account") {
Text("Sign up with your email to get started.")
}
.expanded(true)
PAccordionItem("Step 2: Verify Email") {
Text("Check your inbox and click the verification link.")
}
PAccordionItem("Step 3: Complete Profile") {
Text("Add your information to personalize your experience.")
}
.showDivider(false)
}
.variant(.bordered)
.expansionMode(.single)
API Reference
PAccordion
PAccordion {
// PAccordionItem views
}
Modifiers:
| Modifier | Type | Description |
|---|---|---|
.variant(_:) | PAccordionVariant | Visual style |
.expansionMode(_:) | PAccordionExpansionMode | Single or multiple |
.radius(_:) | RadiusSize | Corner radius |
.showBorder(_:) | Bool | Show/hide border |
PAccordionItem
PAccordionItem(
_ title: String,
subtitle: String? = nil,
icon: String? = nil,
iconColor: Color? = nil,
id: String? = nil
) {
// Content
}
Modifiers:
| Modifier | Type | Description |
|---|---|---|
.expanded(_:) | Bool | Initially expanded |
.radius(_:) | RadiusSize | Corner radius |
.showDivider(_:) | Bool | Show/hide divider |
PStandaloneAccordionItem
PStandaloneAccordionItem(
_ title: String,
subtitle: String? = nil,
icon: String? = nil,
iconColor: Color? = nil,
initiallyExpanded: Bool = false
) {
// Content
}
Modifiers:
| Modifier | Type | Description |
|---|---|---|
.radius(_:) | RadiusSize | Corner radius |
.showBorder(_:) | Bool | Show/hide border |
Enums
PAccordionVariant
.standard— Connected items.bordered— With border.separated— Individual cards
PAccordionExpansionMode
.single— One item at a time.multiple— Multiple items (default)
Accessibility
PAccordion automatically:
- Announces expanded/collapsed state for VoiceOver
- Provides haptic feedback on iOS when toggling
- Respects reduced motion preferences