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)
VariantStyleBest For
.standardConnected, shared backgroundFAQs, documentation
.borderedShared container with borderSteps, tutorials
.separatedIndividual cards with gapsSettings, 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:

ModifierTypeDescription
.variant(_:)PAccordionVariantVisual style
.expansionMode(_:)PAccordionExpansionModeSingle or multiple
.radius(_:)RadiusSizeCorner radius
.showBorder(_:)BoolShow/hide border

PAccordionItem

PAccordionItem(
    _ title: String,
    subtitle: String? = nil,
    icon: String? = nil,
    iconColor: Color? = nil,
    id: String? = nil
) {
    // Content
}

Modifiers:

ModifierTypeDescription
.expanded(_:)BoolInitially expanded
.radius(_:)RadiusSizeCorner radius
.showDivider(_:)BoolShow/hide divider

PStandaloneAccordionItem

PStandaloneAccordionItem(
    _ title: String,
    subtitle: String? = nil,
    icon: String? = nil,
    iconColor: Color? = nil,
    initiallyExpanded: Bool = false
) {
    // Content
}

Modifiers:

ModifierTypeDescription
.radius(_:)RadiusSizeCorner radius
.showBorder(_:)BoolShow/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