Last updated: Aug 4, 2025, 11:26 AM UTC

Interaction Design Patterns: The Details That Delight

Status: UI Component & Behavior Specifications
Verified: Based on usability testing and accessibility standards


Executive Summary

Great interaction design is like a conversation with a helpful friend โ€“ natural, predictable, and occasionally delightful. This document defines the interaction patterns that make NudgeCampaign feel effortless to use, addressing the Phase 1 finding that users feel "constantly confused" by competitor interfaces.

Interaction Principles

Our patterns follow these core principles:

  • Immediate feedback: Every action has instant visual response
  • Forgiveness: Undo is always available
  • Predictability: Similar things behave similarly
  • Delight: Micro-interactions that spark joy
  • Accessibility: Works for everyone, every time

The Interaction Philosophy

graph LR A[User Intent] --> B[Clear Affordance] B --> C[Immediate Feedback] C --> D[Progressive Disclosure] D --> E[Success State] E --> F[Next Action] style A fill:#e3f2fd style C fill:#e8f5e9 style E fill:#4caf50,color:#fff

Core Interaction Patterns

Try It Live: Experience these patterns in action with our interactive examples below.

1. Click/Tap Interactions

Primary Buttons

/* Rest State */
background: #2196f3;
transform: scale(1);
transition: all 0.2s ease;

/* Hover State */
background: #1976d2;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);

/* Active State */
transform: scale(0.98);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);

/* Loading State */
opacity: 0.8;
cursor: wait;
/* Show spinner */

Visual Feedback Timeline

0ms:    Click detected
0-50ms: Active state (scale down)
50ms:   Begin action
100ms:  Show loading if needed
200ms+: Complete or show progress

Secondary Actions

  • Hover: Underline or subtle background
  • Click: Immediate but subtle feedback
  • Disabled: 50% opacity, cursor: not-allowed

2. Form Interactions

Interactive Demo: Try the smart form validation and auto-formatting features below.

Input Field Behavior

Unfocused (Empty):
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Email address       โ”‚ (placeholder, light gray)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Focused:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ |                   โ”‚ (blue border, cursor blinks)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Typing:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ sarah@exam|         โ”‚ (real-time validation)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Valid:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ sarah@example.com โœ“ โ”‚ (green check, green border)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Error:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ sarah@exam โœ—        โ”‚ (red X, red border)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Email must be valid format

Smart Form Patterns

Auto-advance

// Phone number input
(555) 555-5555
      โ†‘
// Cursor auto-advances after area code

Inline Validation

  • Validate on blur, not while typing
  • Show success immediately
  • Explain errors clearly
  • Suggest corrections

Smart Defaults

// Detect timezone
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone

// Smart country selection
country: geoIP.country || 'US'

// Intelligent date picker
minDate: today
defaultTime: nextBusinessHour()

3. Loading & Progress States

Live Examples: See different loading patterns and timing guidelines in action.

Loading Hierarchy

Instant (0-100ms)
No loading indicator needed

Quick (100-300ms)

[Save] โ†’ [ยทยทยทยท] (subtle dots)

Medium (300-1000ms)

Creating campaign...
[โ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘] 40%

Long (1000ms+)

Importing 5,234 contacts...
[โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘] 80% (4,187 of 5,234)
Time remaining: ~15 seconds

โœ“ Validated email format
โœ“ Removed duplicates
โŸณ Adding to database...

Skeleton Screens

For page loads:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘    โ”‚ (animated shimmer)
โ”‚ โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ โ–‘โ–‘โ–‘โ–‘โ–‘    โ”‚
โ”‚                     โ”‚
โ”‚ โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ โ”‚
โ”‚ โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

4. Drag & Drop Patterns

Visual Feedback Sequence

Rest State

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Email Block โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Hover to Drag

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โ‹ฎโ‹ฎ Email    โ”‚ (grab handle appears)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Dragging

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘ Email Block โ•‘ (lifted shadow, 70% opacity)
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ (ghost placeholder)

Valid Drop Zone

โ”Œ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€โ”
  Drop here   (dashed border, highlight)
โ”” โ”€ โ”€ โ”€ โ”€ โ”€ โ”€โ”˜

Invalid Drop Zone

๐Ÿšซ Cannot drop here (red overlay)

Drop Behavior

  • Snap to grid: Align to nearest valid position
  • Auto-scroll: When dragging near edges
  • Multi-select: Ctrl/Cmd for multiple items
  • Undo: Immediate undo after drop

5. Notification Patterns

Live Notifications: Test different notification types, timing, and interaction patterns.

Toast Notifications

Success

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โœ… Campaign sent!           โ”‚
โ”‚ 2,847 emails delivered      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Auto-dismiss: 4 seconds

Warning

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โš ๏ธ Low sending credits      โ”‚
โ”‚ Only 500 emails remaining   โ”‚
โ”‚ [Upgrade] [Dismiss]         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Persistent until action

Error

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โŒ Send failed              โ”‚
โ”‚ API connection timeout      โ”‚
โ”‚ [Retry] [Details] [X]       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Persistent until dismissed

Notification Hierarchy

  1. System-critical: Modal dialog
  2. Action result: Toast notification
  3. Background update: Status bar
  4. FYI: Badge on relevant section

6. Modal & Overlay Patterns

๐ŸชŸ Interactive Overlays: Experience modals, drawers, popovers, and toasts with proper focus management.

Modal Behavior

Opening Animation (200ms):
- Background fade to 60% black
- Modal slides up + fade in
- Focus trapped inside

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Send Test Email     [X] โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Send a test to:         โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ your@email.com      โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚                         โ”‚
โ”‚ [Cancel] [Send Test]    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Closing Animation (150ms):
- Modal slides down + fade out
- Background fade to clear
- Focus returns to trigger

Overlay Types

  • Modal: Important actions, blocks interaction
  • Drawer: Secondary forms, slide from right
  • Popover: Quick info, dismisses on outside click
  • Tooltip: Helpful hints, appears on hover

7. Micro-interactions

Delightful Details: Play with micro-interactions that add personality and provide instant feedback.

Delightful Details

Checkbox Animation

[ ] โ†’ [โœ“] 
    โ†—๏ธ (bounce effect)

Counter Updates

2,846 โ†’ 2,847
      โ†—๏ธ (number rolls up)

Progress Celebration

99% โ†’ 100% โ†’ ๐ŸŽ‰ (confetti burst)

Empty State Personality

No campaigns yet
    ยฏ\_(ใƒ„)_/ยฏ
    
[Create Your First Campaign]

8. Navigation Transitions

Page Transitions

Current Page โ†’ Loading โ†’ New Page
         fade out โ†’ progress โ†’ fade in
         (150ms)    (varies)   (150ms)

Tab Switching

[Tab 1] [Tab 2] [Tab 3]
   โ–”โ–”โ–”
Content slides left/right (200ms)
Underline animates to new position

Accordion Behavior

โ–ถ Section Title        (Collapsed)
  Click โ†“
โ–ผ Section Title        (Expanded)
  Content fades in
  Height animates
  (250ms ease-out)

Touch-Specific Patterns

Gesture Support

Swipe Actions

Contact Row
โ† Swipe left: Delete (red)
โ†’ Swipe right: Edit (blue)

Pull to Refresh

โ†“ Pull down list
"Release to refresh" appears
โœ“ Refreshing...

Long Press

Hold 500ms โ†’ Context menu
- Edit
- Duplicate  
- Delete

Touch Targets

  • Minimum size: 44x44px (iOS), 48x48px (Android)
  • Spacing: 8px minimum between targets
  • Visual feedback: Immediate on touch
  • Hover states: Removed on touch devices

Accessibility Patterns

Keyboard Navigation

Tab Order

1. Skip to main content
2. Primary navigation
3. Page actions (left to right)
4. Main content (top to bottom)
5. Sidebar (if present)
6. Footer

Keyboard Shortcuts

Global:
- / : Focus search
- ? : Show shortcuts
- Esc : Close modal/cancel

Lists:
- j/k : Next/previous item
- x : Select item
- Enter : Open item

Editor:
- Cmd/Ctrl + S : Save
- Cmd/Ctrl + Enter : Send
- Cmd/Ctrl + Z : Undo

Screen Reader Support

<!-- Loading State -->
<div role="status" aria-live="polite">
  Loading campaigns...
</div>

<!-- Success Message -->
<div role="alert" aria-live="assertive">
  Campaign sent successfully
</div>

<!-- Form Error -->
<input 
  aria-invalid="true" 
  aria-describedby="email-error"
/>
<div id="email-error" role="alert">
  Please enter a valid email
</div>

Interactive States

Component State Matrix

Component Default Hover Focus Active Disabled Loading
Button Blue Darker Outline Pressed Gray Spinner
Input Border Darker Blue Typing Gray -
Link Blue Underline Outline Visited Gray -
Card White Shadow Outline - Opacity Skeleton
Toggle Off Cursor Outline Switching Gray -

State Persistence

// Remember user preferences
localStorage.setItem('viewMode', 'grid');
localStorage.setItem('sortBy', 'date-desc');
localStorage.setItem('filterTags', JSON.stringify(['newsletter']));

// Restore on return
const viewMode = localStorage.getItem('viewMode') || 'list';

Undo/Redo Patterns

Undo Notification

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Contact deleted                โ”‚
โ”‚ [Undo] (5 seconds remaining)   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Undo Stack

  • Depth: Last 10 actions
  • Persistence: Current session only
  • Clear actions: Non-undoable actions marked
  • Batch operations: Undo as single action

Error Handling Patterns

Error Prevention

// Confirm destructive actions
if (selectedCount > 10) {
  confirm({
    title: "Delete 47 contacts?",
    message: "This cannot be undone.",
    actions: ["Cancel", "Delete"],
    destructive: 1
  });
}

Error Recovery

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โš ๏ธ Connection Lost          โ”‚
โ”‚                             โ”‚
โ”‚ Don't worry, we saved your  โ”‚
โ”‚ work. Reconnecting...       โ”‚
โ”‚                             โ”‚
โ”‚ [Work Offline] [Retry Now]  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Performance Patterns

Perceived Performance

Optimistic Updates

// Update UI immediately
UI.markAsSent(campaign);

// Then sync with server
API.sendCampaign(campaign)
  .catch(error => {
    UI.markAsError(campaign);
    UI.showError(error);
  });

Progressive Enhancement

  1. Show cached content immediately
  2. Load essential data
  3. Enhance with live data
  4. Add interactive features

Animation Principles

Animation Timing

/* Micro-interactions: Quick */
transition: all 0.15s ease-out;

/* State changes: Moderate */
transition: all 0.25s ease-in-out;

/* Page transitions: Smooth */
transition: all 0.35s ease;

/* Complex animations: Natural */
animation: slideIn 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);

Animation Purpose

  • Orientation: Show spatial relationships
  • Feedback: Confirm user actions
  • Personality: Add delight
  • Focus: Direct attention
  • Continuity: Connect states

Testing Patterns

A/B Test Variations

// Test interaction patterns
const variants = {
  A: { confirmDelete: true },
  B: { confirmDelete: false, undoWindow: 10000 }
};

// Measure success
track('deletion_completed', {
  variant: userVariant,
  undoUsed: false,
  timeToComplete: 3.4
});

Implementation for Next.js

These interactive patterns are designed to be copy-paste ready for Next.js applications. Each pattern includes:

  • React Component Structure: Easily adaptable to React/Next.js
  • CSS-in-JS Ready: Styles can be converted to styled-components or Tailwind
  • Accessibility Built-in: ARIA attributes and keyboard navigation included
  • Performance Optimized: Minimal JavaScript with efficient animations

Integration Example

// Button interaction component for Next.js
import { useState } from 'react';
import styles from './Button.module.css';

export const InteractiveButton = ({ children, onClick, variant = 'primary' }) => {
  const [isLoading, setIsLoading] = useState(false);
  
  const handleClick = async (e) => {
    setIsLoading(true);
    await onClick?.(e);
    setIsLoading(false);
  };
  
  return (
    <button 
      className={`${styles.btn} ${styles[variant]} ${isLoading ? styles.loading : ''}`}
      onClick={handleClick}
      disabled={isLoading}
    >
      {isLoading ? '' : children}
    </button>
  );
};

Interaction patterns designed to make every click feel right and every action feel effortless.