Skip to content

Conversation

@tiagocandido
Copy link
Contributor

What changes are you making?

Added InlineCheckout SwiftUI Component:

  • Added a new InlineCheckout SwiftUI component that can be embedded directly into SwiftUI applications without requiring modal presentation
  • Introduced SwiftUI-friendly event handlers using closures instead of the delegate pattern for better SwiftUI integration
  • Implemented auto-resize height functionality that allows the checkout webview to automatically adjust its height based on content size
  • Added loading state management with visual feedback (spinner and loading text)
  • Implemented smooth spring animations for height transitions with customizable timing

Library Implementation:

  • Added InlineCheckout struct conforming to UIViewRepresentable for SwiftUI integration
  • Created InlineCheckoutWebViewWrapper class to bridge UIKit CheckoutWebView with SwiftUI
  • Implemented InlineCheckoutDelegateWrapper to convert closure-based event handling to the existing delegate pattern
  • Enhanced CheckoutWebView with height monitoring capabilities using JavaScript to track content size changes
  • Added proper configuration change handling via notifications to ensure webview recreation when needed
  • Implemented loading state detection based on meaningful height changes (threshold: 300px)
  • Added smooth UIView spring animations with configurable duration and damping

Sample App Enhancements:

  • Added new ChatView demonstrating inline checkout in a chat-like interface
  • Added dedicated "Chat" tab with chat bubbles icon (message.circle) in the sample app navigation
  • Implemented complete chat UI with message bubbles, quick actions, and inline checkout integration
  • Enhanced tab bar structure to include 5 tabs: Catalog, Products, Cart, Chat, Settings
  • Added loading state UI with progress spinner matching app's accent color
  • Implemented smooth fade transitions between loading and loaded states

Key Features:

  • Automatic Height Adjustment: The inline checkout automatically resizes based on content with smooth animations
  • Loading State Management: Visual feedback with spinner and loading text while content loads
  • Smooth Animations: Spring-based height transitions with customizable timing (0.8-1.2 seconds)
  • SwiftUI Integration: Clean closure-based API that fits naturally with SwiftUI patterns
  • Event Handling: Complete event handling for completion, cancellation, errors, height changes, pixel events, and loading state changes
  • Backward Compatibility: Existing modal presentation functionality remains unaffected
  • Configuration Support: Proper handling of configuration changes (color scheme, etc.)
  • Production Ready: Clean code with no compiler warnings or unused elements

How to test

Basic Usage:

InlineCheckout(
    checkout: checkoutURL,
    autoResizeHeight: true,
    onCheckoutComplete: { event in
        print("Checkout completed: \(event)")
    },
    onCheckoutCancel: {
        print("Checkout cancelled")
    },
    onCheckoutFail: { error in
        print("Checkout failed: \(error)")
    },
    onHeightChange: { height in
        print("Content height changed to: \(height)")
    },
    onLoadingStateChange: { isLoading in
        print("Loading state changed: \(isLoading)")
    }
)

Testing Steps:

  1. Run the sample app and navigate to the "Chat" tab (chat bubbles icon)
  2. Add items to cart from the Catalog or Products tabs
  3. Use the chat interface to trigger inline checkout with the "Checkout" quick action
  4. Observe loading state - verify spinner and loading text appear in a compact 80px container
  5. Watch smooth animation - observe the dramatic height expansion from 80px to full checkout size (0.8-1.2 seconds)
  6. Test auto-resize functionality - verify continued smooth animations as checkout content changes
  7. Test all event handlers (complete, cancel, fail, height change, loading state) work as expected
  8. Verify existing functionality - ensure modal checkout in Settings tab still works
  9. Test configuration changes - switch color schemes to verify proper webview recreation
  10. Run tests - execute InlineCheckoutTests to verify all functionality

What to Verify:

  • ✅ Inline checkout renders correctly within SwiftUI layouts
  • ✅ Loading state shows compact spinner with accent color matching app theme
  • ✅ Smooth spring animations for height transitions (0.8-1.2 second duration)
  • ✅ Loading state transitions smoothly to loaded state when content reaches 300px threshold
  • ✅ Auto-resize height functionality works with continued smooth animations
  • ✅ All event handlers fire appropriately (including new loading state handler)
  • ✅ Existing modal presentation functionality remains unchanged
  • ✅ Configuration changes (color scheme) properly recreate webview
  • ✅ Chat interface provides intuitive demonstration of inline checkout
  • ✅ Navigation between tabs works seamlessly
  • ✅ No compiler warnings or unused code elements
  • ✅ All tests pass successfully

Implementation Notes

  • The InlineCheckout component uses UIViewRepresentable to wrap the enhanced CheckoutWebView
  • Height monitoring is implemented using JavaScript to track DOM element dimensions
  • Loading state detection uses a 300px threshold to determine when content has meaningfully loaded
  • Smooth animations use UIView.animate with spring damping (0.85) and customizable duration (0.8-1.2s)
  • Configuration changes are handled via NotificationCenter to ensure proper cache invalidation
  • The sample app demonstrates real-world usage in a chat support scenario with loading UX
  • Comprehensive test suite added (InlineCheckoutTests) covering all functionality
  • Code cleanup performed to eliminate compiler warnings and unused elements
  • All existing APIs and functionality remain unchanged for backward compatibility

Technical Implementation Details

  • Loading State Management: Uses isLoading flag and hasReceivedFirstHeightChange to track content load status
  • Animation System: Custom spring animations with view hierarchy propagation for smooth transitions
  • Height Threshold: 300px minimum height required to exit loading state (prevents false positives)
  • SwiftUI Integration: Uses ZStack with opacity transitions for loading/loaded state management
  • Event Handling: Complete closure-based API with onLoadingStateChange callback for SwiftUI state synchronization

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant