Docs/AI Chat App

AI Chat App

New

A modern chat interface with message bubbles, typing indicators, and smooth animations. Demonstrates real-time messaging UI patterns and chat-specific components.

AI Chat app showcase

Overview

An AI chat interface that echoes user messages with realistic typing indicators and smooth message animations. Perfect for understanding chat UI patterns.

  • Message bubbles with user/AI distinction
  • Typing indicator animation
  • Auto-scroll to latest message
  • Avatar and online status display
  • Smooth message insertion animations

Components Used

DSMessageBubble
DSChatInputBar
DSAvatar
DSSpinner

Key Features

Message Bubbles

User and AI messages with different alignments and colors. Messages automatically align left for AI and right for user.

Typing Indicators

Animated dots showing when the AI is 'typing' a response, creating a realistic chat experience.

Auto-Scroll

Automatically scrolls to the latest message when new messages arrive, with smooth animations.

Avatars

User and AI avatars with proper spacing and alignment for each message type.

Keyboard Handling

Input bar sticks to the bottom and moves with the keyboard on iOS.

Message Animations

Smooth insertion animations with messages sliding in from the appropriate side.

Code Highlights

Message List Layout

Messages are displayed in a scrollable list with proper alignment for user and AI messages.

swift
ScrollView {
    LazyVStack(spacing: DSSpacing.sm) {
        ForEach(messages) { message in
            HStack {
                if message.isUser { Spacer() }
                
                DSMessageBubble(
                    text: message.text,
                    isUser: message.isUser,
                    timestamp: message.timestamp
                )
                
                if !message.isUser { Spacer() }
            }
        }
    }
}
.scrollDismissesKeyboard(.interactively)

Typing Indicator

Animated dots that appear when the AI is composing a response.

swift
if isTyping {
    HStack {
        DSAvatar(name: "AI", size: .sm)
        
        HStack(spacing: 4) {
            ForEach(0..<3) { i in
                Circle()
                    .fill(Color.dsForegroundMuted)
                    .frame(width: 6, height: 6)
                    .scaleEffect(animatingDot == i ? 1.2 : 1.0)
                    .animation(
                        .easeInOut(duration: 0.6)
                        .repeatForever()
                        .delay(Double(i) * 0.2),
                        value: animatingDot
                    )
            }
        }
        .padding(.horizontal, DSSpacing.sm)
        .padding(.vertical, DSSpacing.xs)
        .background(Color.dsSurface)
        .cornerRadius(DSRadius.medium)
        
        Spacer()
    }
}

Chat Input Bar

Input bar with send button that sticks to the bottom of the screen.

swift
VStack(spacing: 0) {
    Divider()
    
    DSChatInputBar(
        text: $messageText,
        placeholder: "Ask me anything...",
        onSend: { text in
            sendMessage(text)
        }
    )
}
.background(Color.dsSurface)

Auto-Scroll to Bottom

Automatically scroll to the latest message when new messages arrive.

swift
ScrollViewReader { proxy in
    ScrollView {
        LazyVStack(spacing: DSSpacing.sm) {
            ForEach(messages) { message in
                MessageRow(message: message)
                    .id(message.id)
            }
        }
    }
    .onChange(of: messages.count) { _ in
        if let lastMessage = messages.last {
            withAnimation {
                proxy.scrollTo(lastMessage.id, anchor: .bottom)
            }
        }
    }
}

Send Message Logic

Handling message sending with typing indicator and simulated AI response.

swift
private func sendMessage(_ text: String) {
    // Add user message
    let userMessage = Message(text: text, isUser: true)
    messages.append(userMessage)
    
    // Show typing indicator
    isTyping = true
    
    // Simulate AI response
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
        isTyping = false
        
        let aiResponse = Message(
            text: generateAIResponse(to: text),
            isUser: false
        )
        messages.append(aiResponse)
    }
}

What You'll Learn

Chat Interface Patterns

Building a modern chat UI with proper message alignment and spacing.

Message Bubbles

Creating message bubbles that adapt to user/AI with different colors and alignment.

Typing Indicators

Implementing animated typing indicators with dot animations.

Real-time Updates

Handling real-time message updates and auto-scrolling to new messages.

Keyboard Handling

Managing keyboard appearance and dismissal with proper input bar positioning.

Scroll to Bottom

Automatically scrolling to the latest message when new messages arrive.

View Source Code

Explore the complete implementation in the DesignSystem repository.

View on GitHub