Skip to main content

RProductSlider

A powerful horizontal scrolling component for displaying collections of products in your iOS applications. The RProductSlider automatically adapts to different use cases with multiple layout options, built-in headers, and "See All" functionality.

Overview

The RProductSlider is designed for creating engaging product discovery experiences. It supports multiple layouts optimized for different use cases, from featured product showcases to compact recommendation lists.

Basic Usage

Basic Product Slider
import SwiftUI
import ReachuUI
import ReachuCore

struct ProductHomeView: View {
@StateObject private var viewModel = ProductViewModel()

var body: some View {
ScrollView {
VStack(spacing: 24) {
// Featured products
RProductSlider(
title: "Featured Products",
products: viewModel.featuredProducts,
layout: .featured,
showSeeAll: true,
maxItems: 5,
onProductTap: { product in
viewModel.showProductDetail(product)
},
onAddToCart: { product in
viewModel.addToCart(product)
},
onSeeAllTap: {
viewModel.showFeaturedProducts()
}
)

// Category products
RProductSlider(
title: "Electronics",
products: viewModel.electronicsProducts,
layout: .cards,
showSeeAll: true,
onProductTap: { product in
viewModel.showProductDetail(product)
},
onAddToCart: { product in
viewModel.addToCart(product)
}
)
}
}
}
}

Layout Variants

The RProductSlider supports six distinct layout variants, each optimized for different use cases:

Perfect for highlighting premium products and promotions.

Featured Layout
RProductSlider(
title: "Featured Products",
products: featuredProducts,
layout: .featured,
showSeeAll: true,
maxItems: 5
)

Features:

  • Large Cards: Hero-style product cards (280pt width)
  • Full Information: Shows brand, title, description, and price
  • Prominent CTA: Large "Add to Cart" buttons
  • Perfect for: Homepage banners, special promotions, new arrivals

Cards Layout (.cards)

Ideal for browsing product collections and categories.

Cards Layout
RProductSlider(
title: "Electronics",
products: electronicsProducts,
layout: .cards,
showSeeAll: true,
maxItems: 6
)

Features:

  • Medium Cards: Grid-style product cards (180pt width)
  • Balanced Information: Brand, title, and price with Add to Cart
  • Efficient Browsing: Optimal for category exploration
  • Perfect for: Category listings, search results, related products

Showcase Layout (.showcase) ✨

Premium layout for luxury products and special collections.

Showcase Layout
RProductSlider(
title: "Premium Collection",
products: premiumProducts,
layout: .showcase,
showSeeAll: true,
maxItems: 3
)

Features:

  • Extra Large Cards: Premium hero cards (360pt width)
  • Maximum Impact: Full descriptions, premium styling
  • Luxury Experience: Optimal spacing and visual hierarchy
  • Perfect for: Premium collections, luxury items, special editions

Wide Layout (.wide)

Comprehensive layout for detailed product browsing.

Wide Layout
RProductSlider(
title: "Detailed Browse",
products: detailedProducts,
layout: .wide,
showSeeAll: true,
maxItems: 4
)

Features:

  • Wide Cards: List-style cards with comprehensive info (320pt width)
  • Detailed Information: Full product specifications and descriptions
  • Comparison Friendly: Wide format perfect for feature comparison
  • Perfect for: Detailed browsing, comparison views, specifications

Compact Layout (.compact)

Designed for recommendations and space-constrained areas.

Compact Layout
RProductSlider(
title: "You Might Like",
products: recommendedProducts,
layout: .compact,
showSeeAll: true,
maxItems: 8
)

Features:

  • Small Cards: Minimal product cards (120pt width)
  • Essential Information: Title and price only
  • Tap-only Interaction: No Add to Cart button (space optimization)
  • Perfect for: Recommendations, quick picks, footer suggestions

Micro Layout (.micro) 🔍

Ultra-compact layout for dense product listings.

Micro Layout
RProductSlider(
title: "Related Items",
products: relatedProducts,
layout: .micro,
showSeeAll: false,
maxItems: 12
)

Features:

  • Ultra-Small Cards: Minimal footprint cards (80pt width)
  • Dense Layout: Maximum products in minimal space
  • Simplified Interaction: Tap-only, no add-to-cart buttons
  • Perfect for: Footer recommendations, related items, accessories

Convenience Initializers

The RProductSlider includes pre-configured convenience initializers for common use cases:

Featured Convenience Initializer
// Automatically configured for featured products
let featuredSlider = RProductSlider.featured(
title: "Featured Products",
products: featuredProducts,
maxItems: 5,
onProductTap: { product in
showProductDetail(product)
},
onAddToCart: { product in
addToCart(product)
},
onSeeAllTap: {
showAllFeatured()
}
)

Default Settings:

  • Layout: .featured
  • Show See All: true
  • Max Items: 5
  • Show Description: true

Category Products

Category Convenience Initializer
// Automatically configured for category browsing
let categorySlider = RProductSlider.category(
title: "Electronics",
products: electronicsProducts,
maxItems: 6,
onProductTap: { product in
showProductDetail(product)
},
onAddToCart: { product in
addToCart(product)
},
onSeeAllTap: {
showCategory("electronics")
}
)

Default Settings:

  • Layout: .cards
  • Show See All: true
  • Max Items: 6
  • Show Brand: true

Recommendations

Recommendations Convenience Initializer
// Automatically configured for recommendations
let recommendationsSlider = RProductSlider.recommendations(
title: "You Might Like",
products: recommendedProducts,
maxItems: 8,
onProductTap: { product in
showProductDetail(product)
},
onSeeAllTap: {
showRecommendations()
}
)

Default Settings:

  • Layout: .compact
  • Show See All: true
  • Max Items: 8
  • No Add to Cart button (tap-only interaction)

Premium Showcase

Showcase Convenience Initializer
// Automatically configured for premium products
let showcaseSlider = RProductSlider.showcase(
title: "Premium Collection",
products: luxuryProducts,
maxItems: 3,
onProductTap: { product in
showProductDetail(product)
},
onAddToCart: { product in
addToCart(product)
},
onSeeAllTap: {
showPremiumCollection()
}
)

Default Settings:

  • Layout: .showcase
  • Show See All: true
  • Max Items: 3
  • Show Description: true
  • Premium styling and spacing

Detailed Browse

Detailed Convenience Initializer
// Automatically configured for detailed browsing
let detailedSlider = RProductSlider.detailed(
title: "Compare Products",
products: comparisonProducts,
maxItems: 4,
onProductTap: { product in
showProductDetail(product)
},
onAddToCart: { product in
addToCart(product)
},
onSeeAllTap: {
showDetailedBrowse()
}
)

Default Settings:

  • Layout: .wide
  • Show See All: true
  • Max Items: 4
  • Show Description: true
  • Comprehensive product information

Micro Recommendations

Micro Convenience Initializer
// Automatically configured for dense listings
let microSlider = RProductSlider.micro(
title: "Related",
products: relatedProducts,
maxItems: 12,
onProductTap: { product in
showProductDetail(product)
},
onSeeAllTap: {
showRelated()
}
)

Default Settings:

  • Layout: .micro
  • Show See All: false
  • Max Items: 12
  • No Add to Cart button
  • Ultra-compact spacing

Advanced Configuration

Custom Headers

Custom Header Options
RProductSlider(
title: "Best Sellers", // Optional header title
products: bestSellingProducts,
layout: .cards,
showSeeAll: true, // Show/hide "See All" button
maxItems: 10, // Limit number of displayed items
onSeeAllTap: {
// Handle "See All" action
showAllBestSellers()
}
)

Without Header

Header-less Slider
RProductSlider(
title: nil, // No header
products: products,
layout: .cards,
showSeeAll: false, // No "See All" needed
onProductTap: { product in
showProductDetail(product)
}
)

Item Limiting

Item Limiting Options
// Show maximum 5 items
RProductSlider(
title: "Limited Selection",
products: allProducts, // Large array
maxItems: 5, // Only show first 5
layout: .featured
)

// Show all items (no limit)
RProductSlider(
title: "Complete Collection",
products: products,
maxItems: nil, // Show all products
layout: .cards
)

Real-World Examples

Homepage Product Sections

Homepage Implementation
struct HomepageView: View {
@StateObject private var viewModel = HomepageViewModel()

var body: some View {
ScrollView {
VStack(spacing: 32) {
// Hero featured products
RProductSlider.featured(
title: "Featured This Week",
products: viewModel.featuredProducts,
onProductTap: viewModel.showProduct,
onAddToCart: viewModel.addToCart,
onSeeAllTap: viewModel.showFeaturedCollection
)

// Category sections
ForEach(viewModel.categories) { category in
RProductSlider.category(
title: category.title,
products: viewModel.products(for: category),
maxItems: 6,
onProductTap: viewModel.showProduct,
onAddToCart: viewModel.addToCart,
onSeeAllTap: {
viewModel.showCategory(category)
}
)
}

// Recommendations at bottom
RProductSlider.recommendations(
title: "Recommended for You",
products: viewModel.recommendedProducts,
onProductTap: viewModel.showProduct,
onSeeAllTap: viewModel.showRecommendations
)
}
.padding(.vertical, 24)
}
}
}

Product Detail Recommendations

Product Detail Page
struct ProductDetailView: View {
let product: Product
@StateObject private var viewModel = ProductDetailViewModel()

var body: some View {
ScrollView {
VStack(spacing: 24) {
// Product details...
ProductDetailContent(product: product)

// Related products
RProductSlider.category(
title: "Related Products",
products: viewModel.relatedProducts,
maxItems: 5,
onProductTap: { relatedProduct in
// Navigate to related product
viewModel.showProduct(relatedProduct)
},
onAddToCart: viewModel.addToCart
)

// Recently viewed
RProductSlider.recommendations(
title: "Recently Viewed",
products: viewModel.recentlyViewed,
maxItems: 6,
onProductTap: viewModel.showProduct
)
}
}
.task {
await viewModel.loadRelatedProducts(for: product)
}
}
}

Category Browse Page

Category Page
struct CategoryView: View {
let category: Category
@StateObject private var viewModel = CategoryViewModel()

var body: some View {
VStack(spacing: 0) {
// Subcategory filters...
CategoryFilters(category: category)

ScrollView {
VStack(spacing: 24) {
// Featured in category
RProductSlider.featured(
title: "Featured in \(category.title)",
products: viewModel.featuredProducts,
maxItems: 3,
onProductTap: viewModel.showProduct,
onAddToCart: viewModel.addToCart
)

// Subcategory sliders
ForEach(viewModel.subcategories) { subcategory in
RProductSlider.category(
title: subcategory.title,
products: viewModel.products(for: subcategory),
onProductTap: viewModel.showProduct,
onAddToCart: viewModel.addToCart,
onSeeAllTap: {
viewModel.showSubcategory(subcategory)
}
)
}
}
.padding(.vertical, 16)
}
}
.navigationTitle(category.title)
}
}

Layout Guidelines

When to Use Each Layout

LayoutBest ForCard WidthUse Cases
ShowcaseLuxury products, premium collections360ptPremium brands, luxury items, special editions
WideDetailed browsing, comparisons320ptProduct specifications, detailed comparison, reviews
FeaturedPremium products, promotions280ptHomepage banners, new arrivals, special offers
CardsGeneral browsing180ptCategory listings, search results, related products
CompactRecommendations, space-constrained120ptRecently viewed, suggestions, quick picks
MicroDense listings, minimal space80ptFooter recommendations, accessories, related items

Visual Hierarchy

Proper Visual Hierarchy
VStack(spacing: 32) {
// Hero: Showcase for premium (largest)
RProductSlider.showcase(
title: "Premium Collection",
products: premium
)

// Primary: Featured for promotions
RProductSlider.featured(
title: "Featured This Week",
products: featured
)

// Secondary: Wide for detailed browsing
RProductSlider.detailed(
title: "Compare & Choose",
products: comparison
)

// Standard: Category sections
RProductSlider.category(
title: "Electronics",
products: electronics
)

// Compact: Recommendations
RProductSlider.recommendations(
title: "You Might Like",
products: recommendations
)

// Minimal: Related items
RProductSlider.micro(
title: "Related Items",
products: related
)
}

Performance Considerations

Efficient Data Loading

Efficient Implementation
class ProductSliderViewModel: ObservableObject {
@Published var featuredProducts: [Product] = []
@Published var categoryProducts: [String: [Product]] = [:]

func loadFeaturedProducts() async {
// Load only what's needed for the slider
self.featuredProducts = try await productService.getFeatured(limit: 5)
}

func loadCategoryProducts(_ categoryId: String) async {
// Lazy load category products when needed
if categoryProducts[categoryId] == nil {
categoryProducts[categoryId] = try await productService.getProducts(
categoryId: categoryId,
limit: 6
)
}
}
}

Memory Management

  • Lazy Loading: Load slider content as needed
  • Pagination: Use maxItems to limit initial load
  • Image Optimization: Product cards handle image loading efficiently
  • State Management: Use appropriate state management patterns

Accessibility

The RProductSlider includes comprehensive accessibility support:

Accessibility Features
// Automatic accessibility labels
.accessibilityLabel("Product slider: \(title)")

// Navigation accessibility
.accessibilityAddTraits(.startsMediaSession)

// Individual product accessibility
.accessibilityElement(children: .contain)

Accessibility Features:

  • VoiceOver Support: Proper navigation and announcements
  • Dynamic Type: Respects user font size preferences
  • High Contrast: Adapts to accessibility display modes
  • Keyboard Navigation: Full keyboard support for tvOS and external keyboards

Best Practices
  • Use Featured layout sparingly for maximum impact
  • Implement lazy loading for better performance
  • Provide meaningful titles that describe the product collection
  • Consider user context when choosing layouts and item limits