Skip to main content

Overview

The OneBalance onboarding system provides a comprehensive user education experience through multiple components working together:
  • OnboardingProvider: Context provider for managing onboarding state
  • WelcomeModal: Multi-slide welcome experience for first-time users
  • OnboardingTooltip: Interactive tooltips that guide users through key features
  • ContextualHelp: Hover/click help icons for specific features
  • HelpMenu: Centralized help and support menu

Components

OnboardingProvider

The context provider that manages all onboarding state and provides methods to control the tour.

Import

import { OnboardingProvider, useOnboarding } from '@/components/onboarding/OnboardingProvider';

Setup

App Setup
import { OnboardingProvider } from '@/components/onboarding/OnboardingProvider';
import { WelcomeModal } from '@/components/onboarding/WelcomeModal';
import { OnboardingTooltip } from '@/components/onboarding/OnboardingTooltip';

function App() {
  return (
    <OnboardingProvider>
      <WelcomeModal />
      <OnboardingTooltip />
      
      {/* Your app content */}
    </OnboardingProvider>
  );
}

Hook API

const {
  state,                    // Current onboarding state
  startOnboarding,          // Begin the guided tour
  nextStep,                 // Move to next step
  prevStep,                 // Move to previous step
  completeStep,             // Mark a step as completed
  skipOnboarding,           // Skip/exit the tour
  markActionCompleted,      // Track completed user actions
  shouldShowHelp,           // Check if help should be shown
  resetOnboarding           // Reset to initial state
} = useOnboarding();

State Interface

interface OnboardingState {
  isActive: boolean;               // Whether tour is currently active
  currentStep: number;             // Current step index
  steps: OnboardingStep[];         // Array of all steps
  hasSeenWelcome: boolean;         // Whether user has seen welcome modal
  completedActions: Set<string>;   // Set of completed action IDs
}

interface OnboardingStep {
  id: string;                      // Unique step identifier
  title: string;                   // Step title
  description: string;             // Step description text
  target: string;                  // CSS selector for target element
  position: 'top' | 'bottom' | 'left' | 'right';  // Tooltip position
  action?: 'click' | 'hover' | 'focus';  // Expected user action
  completed: boolean;              // Whether step is completed
}

WelcomeModal

A multi-slide modal that greets first-time users and introduces key features.

Import

import { WelcomeModal } from '@/components/onboarding/WelcomeModal';

Features

  • 4 informational slides: Welcome, features, security, chain-abstraction
  • Auto-detection: Only shows to first-time users
  • Route-aware: Adapts tour based on current page (swap vs transfer)
  • LocalStorage persistence: Remembers if user has seen it

Usage

import { WelcomeModal } from '@/components/onboarding/WelcomeModal';

function Layout() {
  return (
    <OnboardingProvider>
      <WelcomeModal />
      {/* Rest of app */}
    </OnboardingProvider>
  );
}

Slide Content

✨ Welcome to OneBalance!
Move tokens across different blockchains in seconds, without the complexity.
No network switching, no gas worries, just simple transactions.

OnboardingTooltip

Interactive tooltips that guide users through the application step-by-step.

Import

import { OnboardingTooltip } from '@/components/onboarding/OnboardingTooltip';

Features

  • Smart positioning: Automatically repositions to stay in viewport
  • Element highlighting: Highlights target elements during tour
  • Progress indicator: Visual progress bar
  • Navigation controls: Next, back, and skip buttons
  • Backdrop overlay: Dims background to focus attention

Target Elements

Add data-onboarding attributes to elements you want to highlight:
<div data-onboarding="connect-button">
  <ConnectButton />
</div>

<div data-onboarding="from-token">
  <TokenSelect />
</div>

<div data-onboarding="amount-input">
  <AmountInput />
</div>

Swap Tour Steps

const SWAP_ONBOARDING_STEPS = [
  { id: 'welcome', target: '[data-onboarding="main-card"]' },
  { id: 'connect-wallet', target: '[data-onboarding="connect-button"]', action: 'click' },
  { id: 'select-token', target: '[data-onboarding="from-token"]', action: 'click' },
  { id: 'enter-amount', target: '[data-onboarding="amount-input"]', action: 'focus' },
  { id: 'select-target', target: '[data-onboarding="to-token"]', action: 'click' },
  { id: 'review-quote', target: '[data-onboarding="quote-details"]' },
  { id: 'execute-swap', target: '[data-onboarding="swap-button"]', action: 'click' }
];

ContextualHelp

Small help icons that show tooltips with detailed explanations.

Import

import { ContextualHelp, helpContent } from '@/components/onboarding/ContextualHelp';

Props

title
string
required
The title of the help tooltip.
content
string
required
The detailed explanation text.
type
'info' | 'warning' | 'tip' | 'feature'
default:"info"
The type of help, which affects icon and styling.
trigger
'hover' | 'click'
default:"hover"
How the tooltip is triggered.
position
'top' | 'bottom' | 'left' | 'right'
default:"top"
Preferred tooltip position relative to the trigger.
children
React.ReactNode
Custom trigger element. If not provided, uses a default help icon.

Usage Examples

import { ContextualHelp } from '@/components/onboarding/ContextualHelp';

function SwapSettings() {
  return (
    <div className="flex items-center gap-2">
      <label>Slippage Tolerance</label>
      <ContextualHelp
        title="Slippage Tolerance"
        content="The maximum price difference you're willing to accept. Higher slippage means your trade is more likely to succeed."
        type="info"
      />
    </div>
  );
}

Predefined Help Content

The component includes commonly used help content:
export const helpContent = {
  slippage: {
    title: 'Slippage Tolerance',
    content: 'The maximum price difference you\'re willing to accept...',
    type: 'info'
  },
  gasless: {
    title: 'Gasless Transactions',
    content: 'We sponsor the blockchain fees for you!...',
    type: 'tip'
  },
  swap: {
    title: 'Chain-Abstracted Swap',
    content: 'Seamlessly exchange tokens across different blockchains...',
    type: 'feature'
  },
  aggregatedBalance: {
    title: 'Aggregated Balance',
    content: 'Your total token balance across all supported blockchains...',
    type: 'info'
  },
  smartAccount: {
    title: 'Smart Account',
    content: 'A more advanced wallet that can automate transactions...',
    type: 'tip'
  },
  quote: {
    title: 'Quote Expiration',
    content: 'Prices change quickly in crypto. Our quotes are valid for 30 seconds...',
    type: 'warning'
  }
};

HelpMenu

Centralized help and support menu accessible from anywhere in the app.

Import

import { HelpMenu } from '@/components/onboarding/HelpMenu';

Features

  • Guided tour restart: Launch the onboarding tour anytime
  • Tutorial reset: Reset progress to see welcome modal again
  • Quick help cards: Common questions and answers
  • External links: Documentation and community support
  • Support contact: Discord and email links

Usage

import { HelpMenu } from '@/components/onboarding/HelpMenu';

function Header() {
  return (
    <header className="flex items-center justify-between">
      <Logo />
      <div className="flex items-center gap-2">
        <ConnectButton />
        <HelpMenu />
      </div>
    </header>
  );
}

Quick Help Topics

  • Login: How to create an account
  • Make a Swap: Steps to execute a swap
  • Chain-Abstracted: Explanation of multi-chain functionality
  • Gasless: Information about sponsored transactions

Complete Integration Example

Complete App Setup
import { OnboardingProvider } from '@/components/onboarding/OnboardingProvider';
import { WelcomeModal } from '@/components/onboarding/WelcomeModal';
import { OnboardingTooltip } from '@/components/onboarding/OnboardingTooltip';
import { HelpMenu } from '@/components/onboarding/HelpMenu';
import { ContextualHelp } from '@/components/onboarding/ContextualHelp';

function App() {
  return (
    <OnboardingProvider>
      {/* Onboarding UI components */}
      <WelcomeModal />
      <OnboardingTooltip />
      
      <div className="app">
        <header>
          <Logo />
          <HelpMenu />
        </header>
        
        <main>
          {/* Add data-onboarding attributes to key elements */}
          <div data-onboarding="main-card">
            <SwapCard />
          </div>
          
          {/* Use contextual help for complex features */}
          <div className="settings">
            <label>Slippage</label>
            <ContextualHelp
              title="Slippage Tolerance"
              content="..."
              type="info"
            />
          </div>
        </main>
      </div>
    </OnboardingProvider>
  );
}

State Persistence

Onboarding state is persisted to localStorage:
interface SavedState {
  isActive: boolean;
  currentStep: number;
  hasSeenWelcome: boolean;
  completedActions: string[];
}

// Saved to: localStorage['onebalance-onboarding']

Customization

Custom Tour Steps

You can modify the tour steps by editing OnboardingProvider.tsx:
Custom Steps
const CUSTOM_STEPS: OnboardingStep[] = [
  {
    id: 'custom-step',
    title: 'Your Feature',
    description: 'Explanation of your feature',
    target: '[data-onboarding="your-target"]',
    position: 'bottom',
    action: 'click',
    completed: false
  },
  // ... more steps
];

Styling

All components use Tailwind CSS and support dark mode:
Custom Styling
<ContextualHelp
  className="ml-2"  // Add custom classes
  title="Custom"
  content="..."
/>

Best Practices

Place data-onboarding attributes on the actual interactive elements (buttons, inputs) rather than wrapper divs for better highlighting.
Keep tooltip descriptions concise (1-2 sentences) for better readability on mobile devices.
Don’t start the tour automatically on every page load. Let users control when they want guidance via the HelpMenu.

Build docs developers (and LLMs) love