Skip to main content

useBrand()

The main React hook for managing brands. Provides complete control over static and dynamic brand switching with state management.

Hook Signature

function useBrand(): UseBrandReturn
return
UseBrandReturn
Object containing brand state and management functions.

Return Value

interface UseBrandReturn {
  // Current state
  currentBrand: string;
  currentBrandType: 'static' | 'dynamic';
  availableBrands: BrandTheme[];
  dynamicBrands: DynamicBrandConfig[];
  allBrands: Array<BrandTheme | DynamicBrandConfig>;
  
  // Brand management
  setBrand: (brandId: string) => void;
  getCurrentBrandTheme: () => BrandTheme | DynamicBrandConfig | undefined;
  
  // Dynamic brand management
  registerDynamicBrand: (config: DynamicBrandConfig) => void;
  unregisterDynamicBrand: (brandId: string) => boolean;
  isDynamicBrand: (brandId: string) => boolean;
  clearAllDynamicBrands: () => void;
  
  // System configuration
  configureDynamicSystem: (config: Partial<DynamicBrandSystemConfig>) => void;
}

Properties

currentBrand
string
The ID of the currently active brand.
currentBrandType
'static' | 'dynamic'
Whether the current brand is static or dynamic.
availableBrands
BrandTheme[]
Array of all available static brands (Stride, Coral, Forest, Runswap, Acme).
dynamicBrands
DynamicBrandConfig[]
Array of all registered dynamic brands.
allBrands
Array<BrandTheme | DynamicBrandConfig>
Combined array of static and dynamic brands.

Methods

setBrand
(brandId: string) => void
Applies a brand theme by ID. Automatically handles both static and dynamic brands.
getCurrentBrandTheme
() => BrandTheme | DynamicBrandConfig | undefined
Returns the full configuration object for the current brand.
registerDynamicBrand
(config: DynamicBrandConfig) => void
Registers a new dynamic brand and updates the hook state.
unregisterDynamicBrand
(brandId: string) => boolean
Removes a dynamic brand and updates state. Returns true if successful.
isDynamicBrand
(brandId: string) => boolean
Checks if a brand ID corresponds to a dynamic brand.
clearAllDynamicBrands
() => void
Removes all dynamic brands from the system.
configureDynamicSystem
(config: Partial<DynamicBrandSystemConfig>) => void
Updates the dynamic brand system configuration.

Usage Examples

Basic Brand Switcher

import { useBrand } from 'stride-ds';

function BrandSwitcher() {
  const { currentBrand, availableBrands, setBrand } = useBrand();

  return (
    <div>
      <h3>Current Brand: {currentBrand}</h3>
      <div>
        {availableBrands.map((brand) => (
          <button
            key={brand.id}
            onClick={() => setBrand(brand.id)}
            disabled={currentBrand === brand.id}
          >
            {brand.name}
          </button>
        ))}
      </div>
    </div>
  );
}

Complete Brand Manager

import { useBrand } from 'stride-ds';

function BrandManager() {
  const {
    currentBrand,
    currentBrandType,
    allBrands,
    setBrand,
    getCurrentBrandTheme
  } = useBrand();

  const currentTheme = getCurrentBrandTheme();

  return (
    <div>
      <h2>Brand Manager</h2>
      
      <div>
        <strong>Current:</strong> {currentTheme?.name} ({currentBrandType})
      </div>
      
      <h3>Available Brands</h3>
      <select 
        value={currentBrand} 
        onChange={(e) => setBrand(e.target.value)}
      >
        {allBrands.map((brand) => (
          <option key={brand.id} value={brand.id}>
            {brand.name}
          </option>
        ))}
      </select>
    </div>
  );
}

Dynamic Brand Registration

import { useBrand } from 'stride-ds';

function DynamicBrandCreator() {
  const {
    registerDynamicBrand,
    setBrand,
    dynamicBrands
  } = useBrand();

  const createBrand = () => {
    const newBrand = {
      id: 'my-custom-brand',
      name: 'My Custom Brand',
      description: 'A dynamically created brand',
      tokens: {
        core: {
          primary: {
            500: '#8B5CF6',
            600: '#7C3AED',
            700: '#6D28D9'
          }
        },
        semantic: {
          textPrimary: '#1F2937',
          interactivePrimary: 'var(--brand-primary-500)'
        }
      }
    };

    registerDynamicBrand(newBrand);
    setBrand(newBrand.id);
  };

  return (
    <div>
      <button onClick={createBrand}>
        Create Custom Brand
      </button>
      
      <h3>Dynamic Brands ({dynamicBrands.length})</h3>
      <ul>
        {dynamicBrands.map((brand) => (
          <li key={brand.id}>{brand.name}</li>
        ))}
      </ul>
    </div>
  );
}

Dynamic Brand with Form

import { useBrand, validateDynamicBrandConfig } from 'stride-ds';
import { useState } from 'react';

function BrandCreator() {
  const { registerDynamicBrand, setBrand } = useBrand();
  const [brandName, setBrandName] = useState('');
  const [primaryColor, setPrimaryColor] = useState('#8B5CF6');
  const [errors, setErrors] = useState<string[]>([]);

  const handleCreate = () => {
    const config = {
      id: brandName.toLowerCase().replace(/\s+/g, '-'),
      name: brandName,
      tokens: {
        core: {
          primary: {
            500: primaryColor
          }
        }
      }
    };

    const validation = validateDynamicBrandConfig(config);
    
    if (validation.valid) {
      registerDynamicBrand(config);
      setBrand(config.id);
      setErrors([]);
    } else {
      setErrors(validation.errors);
    }
  };

  return (
    <form onSubmit={(e) => { e.preventDefault(); handleCreate(); }}>
      <input
        placeholder="Brand Name"
        value={brandName}
        onChange={(e) => setBrandName(e.target.value)}
      />
      
      <input
        type="color"
        value={primaryColor}
        onChange={(e) => setPrimaryColor(e.target.value)}
      />
      
      <button type="submit">Create Brand</button>
      
      {errors.length > 0 && (
        <ul>
          {errors.map((error, i) => (
            <li key={i}>{error}</li>
          ))}
        </ul>
      )}
    </form>
  );
}

System Configuration

import { useBrand } from 'stride-ds';
import { useEffect } from 'react';

function App() {
  const { configureDynamicSystem } = useBrand();

  useEffect(() => {
    // Configure the dynamic brand system on app initialization
    configureDynamicSystem({
      defaultFallbackBrand: 'stride',
      enableTransitions: true,
      transitionDuration: 200,
      enableLocalStorage: true
    });
  }, [configureDynamicSystem]);

  return <YourApp />;
}

Brand Management Dashboard

import { useBrand } from 'stride-ds';

function BrandDashboard() {
  const {
    currentBrand,
    dynamicBrands,
    availableBrands,
    setBrand,
    unregisterDynamicBrand
  } = useBrand();

  return (
    <div>
      <h2>Brand Dashboard</h2>
      
      <section>
        <h3>Static Brands</h3>
        {availableBrands.map((brand) => (
          <div key={brand.id}>
            <span>{brand.name}</span>
            <button onClick={() => setBrand(brand.id)}>
              {currentBrand === brand.id ? 'Active' : 'Activate'}
            </button>
          </div>
        ))}
      </section>
      
      <section>
        <h3>Dynamic Brands</h3>
        {dynamicBrands.map((brand) => (
          <div key={brand.id}>
            <span>{brand.name}</span>
            <button onClick={() => setBrand(brand.id)}>
              Activate
            </button>
            <button onClick={() => unregisterDynamicBrand(brand.id)}>
              Delete
            </button>
          </div>
        ))}
      </section>
    </div>
  );
}

useBrandTheme()

A simplified hook that only tracks the current brand theme configuration and updates when the brand changes.

Hook Signature

function useBrandTheme(): BrandTheme | DynamicBrandConfig | undefined
return
BrandTheme | DynamicBrandConfig | undefined
The current brand’s full configuration object.

Usage Example

import { useBrandTheme } from 'stride-ds';

function BrandInfo() {
  const theme = useBrandTheme();

  if (!theme) return null;

  return (
    <div>
      <h3>{theme.name}</h3>
      <p>{theme.description}</p>
      <code>ID: {theme.id}</code>
    </div>
  );
}

When to Use Each Hook

Use useBrand():
  • When you need to switch brands
  • When you need to register/manage dynamic brands
  • When building brand management UI
  • When you need access to all available brands
Use useBrandTheme():
  • When you only need to read the current brand
  • When displaying brand information
  • When you don’t need to modify brands
  • For simpler, read-only use cases

Best Practices

1. Single Brand Provider

Use useBrand() once at a high level in your component tree:
// App.tsx
function App() {
  const brand = useBrand();
  
  return (
    <BrandContext.Provider value={brand}>
      <YourApp />
    </BrandContext.Provider>
  );
}

2. Memoize Brand Configs

When creating dynamic brands, memoize the configuration:
import { useBrand } from 'stride-ds';
import { useMemo } from 'react';

function DynamicBrandSetup() {
  const { registerDynamicBrand } = useBrand();
  
  const brandConfig = useMemo(() => ({
    id: 'my-brand',
    name: 'My Brand',
    tokens: { /* ... */ }
  }), []);
  
  useEffect(() => {
    registerDynamicBrand(brandConfig);
  }, [brandConfig, registerDynamicBrand]);
}

3. Error Handling

Always validate before registering:
import { useBrand, validateDynamicBrandConfig } from 'stride-ds';

function SafeBrandRegistration({ config }) {
  const { registerDynamicBrand } = useBrand();
  
  const handleRegister = () => {
    const validation = validateDynamicBrandConfig(config);
    
    if (validation.valid) {
      registerDynamicBrand(config);
    } else {
      console.error('Invalid brand config:', validation.errors);
    }
  };
}

4. Cleanup

Clean up dynamic brands when components unmount:
function TenantBrandProvider({ tenantId, brandConfig }) {
  const { registerDynamicBrand, unregisterDynamicBrand } = useBrand();
  
  useEffect(() => {
    registerDynamicBrand(brandConfig);
    
    return () => {
      unregisterDynamicBrand(brandConfig.id);
    };
  }, [tenantId, brandConfig]);
}

Build docs developers (and LLMs) love