BigBlocks Docs
Components/Providers

BitcoinThemeProvider

Core theme provider for Bitcoin-inspired theming with extensive color schemes

The core theme provider component that enables Bitcoin-inspired theming across your entire application. Built on Radix Themes, it provides extensive color schemes, dark/light mode support, and comprehensive theme customization.

Installation

npx bigblocks add bitcoin-theme-provider

Import

import { BitcoinThemeProvider } from 'bigblocks';

Props

PropTypeRequiredDefaultDescription
childrenReactNodeYes-Child components
defaultThemeBitcoinThemeNo'orange'Default theme selection
appearance'light' | 'dark' | 'inherit'No'inherit'Color mode
storageKeystringNo-localStorage key for persistence
showThemePanelbooleanNofalseShow dev theme panel
radius'none' | 'small' | 'medium' | 'large' | 'full'No'medium'Border radius
scaling'90%' | '95%' | '100%' | '105%' | '110%'No'100%'UI scaling
grayColorstringNo-Custom gray color
panelBackground'solid' | 'translucent'No-Panel background style
hasBackgroundbooleanNo-Enable background

Available Themes

The provider includes all Radix UI colors plus custom Bitcoin-inspired themes:

Standard Colors

  • orange - Classic Bitcoin orange (default)
  • blue, green, red, purple, cyan, gray
  • yellow, amber, lime, mint, sky, iris
  • pink, plum, crimson, indigo, teal, jade
  • grass, bronze, gold, brown, tomato, ruby

Custom Themes

  • light, dark - Base light/dark themes
  • neo, cyberpunk, neon, noir - Futuristic themes
  • aurora, nebula, prism, vortex - Cosmic themes
  • forest, ocean, sunset, midnight - Nature themes
  • dawn, twilight, storm, arctic - Weather themes
  • rose, lavender, emerald, sapphire - Gem themes
  • ruby, topaz, onyx, pearl - Precious themes
  • vintage, sepia, monochrome - Classic themes
  • pastel, vibrant, minimal, luxury, cosmic - Style themes

Basic Usage

import { BitcoinThemeProvider } from 'bigblocks';

function App() {
  return (
    <BitcoinThemeProvider>
      <YourAppContent />
    </BitcoinThemeProvider>
  );
}

Advanced Usage

Custom Theme Selection

import { BitcoinThemeProvider } from 'bigblocks';

export default function ThemedApp() {
  return (
    <BitcoinThemeProvider 
      defaultTheme="cyberpunk"
      appearance="dark"
      radius="large"
      scaling="105%"
    >
      <App />
    </BitcoinThemeProvider>
  );
}

With Theme Persistence

import { BitcoinThemeProvider } from 'bigblocks';

export default function PersistentThemeApp() {
  return (
    <BitcoinThemeProvider
      defaultTheme="ocean"
      appearance="inherit" // Follow system preference
      storageKey="my-app-theme"
    >
      <App />
    </BitcoinThemeProvider>
  );
}

Development with Theme Panel

import { BitcoinThemeProvider } from 'bigblocks';

export default function DevApp() {
  return (
    <BitcoinThemeProvider
      defaultTheme="orange"
      showThemePanel={process.env.NODE_ENV === 'development'}
      storageKey="dev-theme"
    >
      <App />
    </BitcoinThemeProvider>
  );
}

Dynamic Theme Switching

import { BitcoinThemeProvider, useTheme } from 'bigblocks';
import { useState } from 'react';

function ThemeSwitcher() {
  const { theme, setTheme } = useTheme();
  
  return (
    <select value={theme} onChange={(e) => setTheme(e.target.value)}>
      <option value="orange">Bitcoin Orange</option>
      <option value="cyberpunk">Cyberpunk</option>
      <option value="ocean">Ocean</option>
      <option value="cosmic">Cosmic</option>
    </select>
  );
}

export default function DynamicThemeApp() {
  return (
    <BitcoinThemeProvider defaultTheme="orange">
      <ThemeSwitcher />
      <App />
    </BitcoinThemeProvider>
  );
}

Theme Hook

Use the useTheme hook to access and control the current theme:

import { useTheme } from 'bigblocks';

function ThemedComponent() {
  const { theme, setTheme } = useTheme();
  
  return (
    <div>
      <p>Current theme: {theme}</p>
      <button onClick={() => setTheme('neon')}>
        Switch to Neon
      </button>
    </div>
  );
}

Common Patterns

Provider Nesting Order

import { 
  BitcoinQueryProvider,
  BitcoinThemeProvider,
  BitcoinAuthProvider 
} from 'bigblocks';

// Correct nesting order:
export default function App() {
  return (
    <BitcoinQueryProvider>
      <BitcoinThemeProvider defaultTheme="orange">
        <BitcoinAuthProvider config={{ apiUrl: '/api' }}>
          <YourApp />
        </BitcoinAuthProvider>
      </BitcoinThemeProvider>
    </BitcoinQueryProvider>
  );
}

User-Based Theming

import { BitcoinThemeProvider } from 'bigblocks';
import { useBitcoinAuth } from 'bigblocks';

export default function UserThemedApp() {
  const { user } = useBitcoinAuth();
  
  // Different themes for different user types
  const getUserTheme = () => {
    if (!user) return 'orange';
    if (user.isPremium) return 'gold';
    if (user.isDeveloper) return 'cyberpunk';
    if (user.isVerified) return 'emerald';
    return 'orange';
  };
  
  return (
    <BitcoinThemeProvider
      defaultTheme={getUserTheme()}
      storageKey={`theme-${user?.bapId}`}
    >
      <App />
    </BitcoinThemeProvider>
  );
}

Route-Based Theming

import { BitcoinThemeProvider } from 'bigblocks';
import { useLocation } from 'react-router-dom';

export default function RouteThemedApp() {
  const location = useLocation();
  
  const getRouteTheme = (pathname: string) => {
    if (pathname.startsWith('/wallet')) return 'gold';
    if (pathname.startsWith('/social')) return 'ocean';
    if (pathname.startsWith('/market')) return 'emerald';
    if (pathname.startsWith('/dev')) return 'cyberpunk';
    return 'orange';
  };
  
  return (
    <BitcoinThemeProvider
      defaultTheme={getRouteTheme(location.pathname)}
      appearance="dark"
    >
      <App />
    </BitcoinThemeProvider>
  );
}

Accessibility Settings

import { BitcoinThemeProvider } from 'bigblocks';
import { useEffect, useState } from 'react';

export default function AccessibleApp() {
  const [highContrast, setHighContrast] = useState(false);
  const [largeText, setLargeText] = useState(false);
  
  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-contrast: high)');
    setHighContrast(mediaQuery.matches);
    
    const handleChange = (e) => setHighContrast(e.matches);
    mediaQuery.addEventListener('change', handleChange);
    
    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);
  
  return (
    <BitcoinThemeProvider
      defaultTheme={highContrast ? 'monochrome' : 'orange'}
      scaling={largeText ? '110%' : '100%'}
      radius="medium"
    >
      <App />
    </BitcoinThemeProvider>
  );
}

CSS Variables

The theme provider makes numerous CSS variables available:

/* Accent colors (1-12 scale) */
--accent-1 through --accent-12

/* Gray colors (1-12 scale) */
--gray-1 through --gray-12

/* Semantic colors */
--color-background
--color-panel
--color-overlay

/* Spacing */
--space-1 through --space-9

/* Radius */
--radius-1 through --radius-6

/* Font sizes */
--font-size-1 through --font-size-9

/* Shadows */
--shadow-1 through --shadow-6

Custom Styling

.custom-component {
  /* Use theme colors */
  background-color: var(--accent-3);
  color: var(--accent-11);
  border: 1px solid var(--accent-6);
  
  /* Use theme spacing */
  padding: var(--space-3);
  margin: var(--space-2);
  
  /* Use theme radius */
  border-radius: var(--radius-3);
  
  /* Use theme shadows */
  box-shadow: var(--shadow-2);
}

.custom-component:hover {
  background-color: var(--accent-4);
  box-shadow: var(--shadow-3);
}

SSR Support

// pages/_app.tsx (Next.js)
import { BitcoinThemeProvider } from 'bigblocks';

function MyApp({ Component, pageProps }) {
  return (
    <BitcoinThemeProvider
      defaultTheme="orange"
      appearance="inherit"
      storageKey="app-theme"
    >
      <Component {...pageProps} />
    </BitcoinThemeProvider>
  );
}

export default MyApp;

Best Practices

  1. Single Provider: Use one BitcoinThemeProvider at the app root
  2. Theme Persistence: Use storageKey for consistent user experience
  3. System Preference: Use appearance="inherit" to respect user settings
  4. Performance: Theme changes use CSS variables for instant updates
  5. Accessibility: Test themes with high contrast and color blindness simulators

Troubleshooting

Theme Not Persisting

// Ensure storageKey is set
<BitcoinThemeProvider storageKey="my-theme">

Hydration Mismatch

// Wait for client-side mount
const [mounted, setMounted] = useState(false);

useEffect(() => {
  setMounted(true);
}, []);

if (!mounted) return null;

return <BitcoinThemeProvider>...</BitcoinThemeProvider>;

Theme Not Updating

// Ensure useTheme is called within provider
function Component() {
  const { theme, setTheme } = useTheme(); // Must be inside provider
  // ...
}

API Reference

BitcoinTheme Type

type BitcoinTheme = 
  // Radix colors
  | 'gray' | 'gold' | 'bronze' | 'brown' | 'yellow' | 'amber' 
  | 'orange' | 'tomato' | 'red' | 'ruby' | 'crimson' | 'pink'
  | 'plum' | 'purple' | 'violet' | 'iris' | 'indigo' | 'blue'
  | 'cyan' | 'teal' | 'jade' | 'green' | 'grass' | 'lime'
  | 'mint' | 'sky'
  // Custom themes
  | 'light' | 'dark' | 'neo' | 'cyberpunk' | 'neon' | 'noir'
  | 'aurora' | 'nebula' | 'prism' | 'vortex' | 'forest' | 'ocean'
  | 'sunset' | 'midnight' | 'dawn' | 'twilight' | 'storm' | 'arctic'
  | 'rose' | 'lavender' | 'emerald' | 'sapphire' | 'ruby' | 'topaz'
  | 'onyx' | 'pearl' | 'vintage' | 'sepia' | 'monochrome' | 'pastel'
  | 'vibrant' | 'minimal' | 'luxury' | 'cosmic';

useTheme Hook

interface ThemeContextValue {
  theme: BitcoinTheme;
  setTheme: (theme: BitcoinTheme) => void;
}

Notes for Improvement

Extended Theme Support: The actual component supports many more themes than the prompt described, including all Radix UI colors plus extensive custom themes. The implementation is built directly on Radix Themes rather than being a custom solution, providing better compatibility and performance.