Examples

Examples

Real-world usage patterns and code examples for Bao UI components.

Interactive Demo

🚀 Live Demo →

Try the interactive demo to see all components in action.

Common Patterns

Confirmation Dialog

import { useState } from 'react'
import {
  Button,
  DialogRoot,
  DialogBackdrop,
  DialogPopup,
  DialogTitle,
  DialogClose,
} from '@bao-ui/react'
 
function DeleteConfirmation() {
  const [open, setOpen] = useState(false)
 
  const handleDelete = () => {
    // Perform delete action
    console.log('Item deleted')
    setOpen(false)
  }
 
  return (
    <DialogRoot open={open} onOpenChange={setOpen}>
      <Button variant="destructive" onClick={() => setOpen(true)}>
        Delete Item
      </Button>
 
      <DialogBackdrop />
      <DialogPopup>
        <DialogTitle>Confirm Deletion</DialogTitle>
        <p>
          Are you sure you want to delete this item? This action cannot be
          undone.
        </p>
 
        <div style={{ display: 'flex', gap: '0.5rem', marginTop: '1rem' }}>
          <DialogClose>
            <Button variant="outline">Cancel</Button>
          </DialogClose>
          <Button variant="destructive" onClick={handleDelete}>
            Delete
          </Button>
        </div>
      </DialogPopup>
    </DialogRoot>
  )
}

Tooltip with Rich Content

import {
  Button,
  TooltipRoot,
  TooltipTrigger,
  TooltipPopup,
} from '@bao-ui/react'
 
function UserProfile() {
  return (
    <TooltipRoot>
      <TooltipTrigger>
        <Button variant="ghost">@username</Button>
      </TooltipTrigger>
      <TooltipPopup>
        <div style={{ padding: '0.5rem' }}>
          <div style={{ fontWeight: 'bold' }}>John Doe</div>
          <div style={{ color: '#666', fontSize: '0.875rem' }}>
            Software Engineer
          </div>
          <div style={{ marginTop: '0.25rem', fontSize: '0.75rem' }}>
            Joined March 2024
          </div>
        </div>
      </TooltipPopup>
    </TooltipRoot>
  )
}

Button Loading States

import { useState } from 'react'
import { Button } from '@bao-ui/react'
 
function AsyncAction() {
  const [loading, setLoading] = useState(false)
 
  const handleSubmit = async () => {
    setLoading(true)
    try {
      await new Promise(resolve => setTimeout(resolve, 2000))
      console.log('Action completed')
    } finally {
      setLoading(false)
    }
  }
 
  return (
    <Button
      onClick={handleSubmit}
      disabled={loading}
      style={{ minWidth: '120px' }}
    >
      {loading ? 'Loading...' : 'Submit'}
    </Button>
  )
}

Form with Validation

import { useState } from 'react'
import {
  Button,
  DialogRoot,
  DialogPopup,
  DialogTitle,
  DialogClose,
} from '@bao-ui/react'
 
function ContactForm() {
  const [formData, setFormData] = useState({ name: '', email: '' })
  const [errors, setErrors] = useState({})
  const [showSuccess, setShowSuccess] = useState(false)
 
  const validate = () => {
    const newErrors = {}
    if (!formData.name) newErrors.name = 'Name is required'
    if (!formData.email) newErrors.email = 'Email is required'
    if (formData.email && !formData.email.includes('@')) {
      newErrors.email = 'Invalid email'
    }
    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }
 
  const handleSubmit = e => {
    e.preventDefault()
    if (validate()) {
      setShowSuccess(true)
      setFormData({ name: '', email: '' })
    }
  }
 
  return (
    <>
      <form onSubmit={handleSubmit} style={{ maxWidth: '400px' }}>
        <div style={{ marginBottom: '1rem' }}>
          <label>
            Name
            <input
              type="text"
              value={formData.name}
              onChange={e => setFormData({ ...formData, name: e.target.value })}
              style={{
                width: '100%',
                padding: '0.5rem',
                marginTop: '0.25rem',
                border: errors.name ? '1px solid red' : '1px solid #ccc',
                borderRadius: '0.25rem',
              }}
            />
            {errors.name && (
              <div style={{ color: 'red', fontSize: '0.875rem' }}>
                {errors.name}
              </div>
            )}
          </label>
        </div>
 
        <div style={{ marginBottom: '1rem' }}>
          <label>
            Email
            <input
              type="email"
              value={formData.email}
              onChange={e =>
                setFormData({ ...formData, email: e.target.value })
              }
              style={{
                width: '100%',
                padding: '0.5rem',
                marginTop: '0.25rem',
                border: errors.email ? '1px solid red' : '1px solid #ccc',
                borderRadius: '0.25rem',
              }}
            />
            {errors.email && (
              <div style={{ color: 'red', fontSize: '0.875rem' }}>
                {errors.email}
              </div>
            )}
          </label>
        </div>
 
        <Button type="submit">Submit</Button>
      </form>
 
      <DialogRoot open={showSuccess} onOpenChange={setShowSuccess}>
        <DialogPopup>
          <DialogTitle>Success!</DialogTitle>
          <p>Your form has been submitted successfully.</p>
          <DialogClose>
            <Button>Close</Button>
          </DialogClose>
        </DialogPopup>
      </DialogRoot>
    </>
  )
}

Component Composition

import {
  Button,
  TooltipRoot,
  TooltipTrigger,
  TooltipPopup,
  DialogRoot,
  DialogTrigger,
  DialogPopup,
  DialogTitle,
} from '@bao-ui/react'
 
function ActionButton({ action, tooltip, confirmMessage, children }) {
  return (
    <DialogRoot>
      <TooltipRoot>
        <TooltipTrigger>
          <DialogTrigger>
            <Button variant="outline">{children}</Button>
          </DialogTrigger>
        </TooltipTrigger>
        <TooltipPopup content={tooltip} />
      </TooltipRoot>
 
      <DialogPopup>
        <DialogTitle>Confirm Action</DialogTitle>
        <p>{confirmMessage}</p>
        <div style={{ display: 'flex', gap: '0.5rem', marginTop: '1rem' }}>
          <Button variant="outline">Cancel</Button>
          <Button onClick={action}>Confirm</Button>
        </div>
      </DialogPopup>
    </DialogRoot>
  )
}
 
// Usage
;<ActionButton
  action={() => console.log('Archive action')}
  tooltip="Archive this item"
  confirmMessage="Are you sure you want to archive this item?"
>
  Archive
</ActionButton>

Integration Examples

Next.js App Router

// app/layout.tsx
import '@bao-ui/react/styles.css'
 
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
 
// app/page.tsx
import { Button } from '@bao-ui/react'
 
export default function HomePage() {
  return (
    <main>
      <h1>My App</h1>
      <Button>Get Started</Button>
    </main>
  )
}

React + Vite

// main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import '@bao-ui/react/styles.css'
import App from './App'
 
ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)
 
// App.tsx
import { Button } from '@bao-ui/react'
 
function App() {
  return (
    <div>
      <h1>Vite + React + Bao UI</h1>
      <Button>Click me</Button>
    </div>
  )
}

Styling Examples

Custom Button Styles

// With Tailwind classes
<Button className="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600">
  Gradient Button
</Button>
 
// With inline styles
<Button style={{
  background: 'linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%)',
  borderRadius: '20px',
  color: 'white'
}}>
  Custom Style
</Button>