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
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
The ID of the currently active brand.
Whether the current brand is static or dynamic.
Array of all available static brands (Stride, Coral, Forest, Runswap, Acme).
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.
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>
);
}
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]);
}