@hydrogen-ui/themes
v0.1.0
Published
Theme presets for Hydrogen UI
Readme
@hydrogen-ui/themes
A comprehensive theme management system for Hydrogen UI with design tokens, runtime switching, and performance optimization. Features 5 preset themes, Style Dictionary integration, and full TypeScript support.
Installation
npm install @hydrogen-ui/themes @hydrogen-ui/core @hydrogen-ui/tokens
# or
yarn add @hydrogen-ui/themes @hydrogen-ui/core @hydrogen-ui/tokens
# or
pnpm add @hydrogen-ui/themes @hydrogen-ui/core @hydrogen-ui/tokensFeatures
- 🎨 5 Preset Themes - Dawn, Craft, Studio, B2B, and Thnk
- 🎯 Design Tokens - Comprehensive token system with Style Dictionary
- ⚡ Runtime Switching - Change themes without page reload
- 🚀 Performance - Built-in caching and lazy loading
- 📊 Monitoring - Web Vitals integration and performance tracking
- 🔒 Type Safety - Full TypeScript support
- 💾 Persistence - Memory and sessionStorage options
- 🎨 CSS Variables - Automatic CSS variable generation
- 📱 Responsive - Responsive token values
- ♿ Accessible - WCAG compliant color systems
Quick Start
import { ThemeProvider } from '@hydrogen-ui/themes';
import { HydrogenProvider } from '@hydrogen-ui/core';
function App() {
return (
<HydrogenProvider>
<ThemeProvider theme="dawn" persistence="sessionStorage">
<YourApp />
</ThemeProvider>
</HydrogenProvider>
);
}Available Themes
Dawn (Default)
Clean and minimal design with teal accents
- Primary: Teal color palette
- Typography: System fonts
- Best for: General e-commerce, modern storefronts
Craft
Warm, artisanal aesthetic with amber tones
- Primary: Amber color palette
- Typography: Serif fonts (Georgia)
- Best for: Handmade goods, artisan products
Studio
Bold and contemporary with violet accents
- Primary: Violet color palette
- Typography: Modern sans-serif
- Best for: Creative products, fashion
B2B
Professional and trustworthy with blue tones
- Primary: Blue color palette
- Typography: Professional fonts
- Best for: B2B commerce, enterprise
Thnk
Minimalist premium with black and white
- Primary: Monochrome palette
- Typography: Custom premium fonts
- Best for: Luxury, high-end products
Theme Provider
The ThemeProvider component manages theme state and CSS injection:
<ThemeProvider
theme="dawn" // Theme name
persistence="sessionStorage" // 'memory' | 'sessionStorage'
enableSystemPreference={true} // Auto-detect system theme
onThemeChange={(theme) => {}} // Theme change callback
performanceMonitoring={true} // Enable performance tracking
>
{children}
</ThemeProvider>Props
| Prop | Type | Default | Description | |------|------|---------|-------------| | theme | string | 'dawn' | Active theme name | | persistence | 'memory' | 'sessionStorage' | 'memory' | Theme persistence strategy | | enableSystemPreference | boolean | false | Auto-detect system dark/light preference | | onThemeChange | (theme: string) => void | - | Callback when theme changes | | performanceMonitoring | boolean | false | Enable performance tracking | | cacheStrategy | CacheStrategy | 'standard' | Cache strategy for theme data | | children | ReactNode | - | Child components |
Theme Hooks
useTheme()
Access and control the current theme:
const { theme, setTheme, themes, isLoading } = useTheme();
// Current theme
console.log(theme); // 'dawn'
// Available themes
console.log(themes); // ['dawn', 'craft', 'studio', 'b2b', 'thnk']
// Change theme
setTheme('studio');useToken()
Get specific token values:
// Get a single token
const primaryColor = useToken('colors.primary.500');
const fontFamily = useToken('typography.fontFamily.sans');
// Get nested tokens
const spacing = useToken('spacing');
// Returns: { xs: '0.5rem', sm: '1rem', ... }useTokens()
Get all tokens for the current theme:
const tokens = useTokens();
// Access any token
console.log(tokens.colors.primary[500]);
console.log(tokens.typography.fontSize.lg);useCSSVariable()
Access computed CSS variable values:
// Get CSS variable value
const primaryColor = useCSSVariable('--color-primary-500');
// Use in styles
const style = {
color: useCSSVariable('--color-text-primary'),
fontSize: useCSSVariable('--font-size-lg')
};useResponsiveToken()
Get responsive token values:
// Responsive spacing
const spacing = useResponsiveToken('spacing.md', {
sm: 'spacing.sm',
md: 'spacing.md',
lg: 'spacing.lg'
});
// Responsive typography
const fontSize = useResponsiveToken('typography.fontSize.base', {
sm: 'typography.fontSize.sm',
lg: 'typography.fontSize.lg'
});Theme Selector Component
Pre-built UI component for theme switching:
import { ThemeSelector } from '@hydrogen-ui/themes';
// Dropdown variant (default)
<ThemeSelector variant="dropdown" />
// Button group variant
<ThemeSelector variant="buttons" />
// Grid variant with previews
<ThemeSelector variant="grid" showPreview />Props
| Prop | Type | Default | Description | |------|------|---------|-------------| | variant | 'dropdown' | 'buttons' | 'grid' | 'dropdown' | Selector UI variant | | showPreview | boolean | false | Show theme preview (grid only) | | className | string | - | Additional CSS classes | | onChange | (theme: string) => void | - | Theme change callback |
Design Tokens
Each theme defines comprehensive design tokens:
Color Tokens
{
colors: {
primary: { 50, 100, 200, ..., 900 },
neutral: { 50, 100, 200, ..., 900 },
success: { light, main, dark },
warning: { light, main, dark },
error: { light, main, dark },
info: { light, main, dark }
}
}Typography Tokens
{
typography: {
fontFamily: { sans, serif, mono },
fontSize: { xs, sm, base, lg, xl, 2xl, ... },
fontWeight: { light, normal, medium, semibold, bold },
lineHeight: { tight, normal, relaxed },
letterSpacing: { tight, normal, wide }
}
}Spacing Tokens
{
spacing: {
0: '0',
xs: '0.5rem',
sm: '1rem',
md: '1.5rem',
lg: '2rem',
xl: '3rem',
'2xl': '4rem'
}
}Component Tokens
{
components: {
button: {
padding: { sm, md, lg },
borderRadius: 'base',
fontSize: { sm, md, lg }
},
card: {
padding: 'md',
borderRadius: 'lg',
shadow: 'md'
}
// ... more components
}
}Creating Custom Themes
Basic Custom Theme
import { createTheme } from '@hydrogen-ui/themes';
const myTheme = createTheme({
name: 'my-theme',
tokens: {
colors: {
primary: {
500: '#FF6B6B',
600: '#FF5252',
700: '#FF3838'
}
},
typography: {
fontFamily: {
sans: 'Inter, system-ui, sans-serif'
}
}
}
});
// Register theme
import { registerTheme } from '@hydrogen-ui/themes';
registerTheme(myTheme);Extending Existing Themes
import { extendTheme, themes } from '@hydrogen-ui/themes';
const myTheme = extendTheme(themes.dawn, {
name: 'my-dawn',
tokens: {
colors: {
primary: themes.craft.tokens.colors.primary
}
}
});Style Dictionary Configuration
// style-dictionary.config.js
module.exports = {
source: ['tokens/**/*.json'],
platforms: {
css: {
transformGroup: 'css',
files: [{
destination: 'themes/my-theme.css',
format: 'css/variables'
}]
}
}
};Performance Features
Caching
The theme system includes built-in caching:
import { ThemeProvider } from '@hydrogen-ui/themes';
// Standard caching (recommended)
<ThemeProvider cacheStrategy="standard">
// Aggressive caching
<ThemeProvider cacheStrategy="aggressive">
// No caching
<ThemeProvider cacheStrategy="none">Performance Monitoring
Monitor theme performance with Web Vitals:
<ThemeProvider
performanceMonitoring={true}
onPerformanceReport={(metrics) => {
console.log('Theme performance:', metrics);
// Send to analytics
}}
>Lazy Loading
Themes are lazy loaded by default:
import { loadTheme } from '@hydrogen-ui/themes';
// Preload a theme
await loadTheme('studio');
// Load theme with progress
loadTheme('craft', {
onProgress: (progress) => {
console.log(`Loading: ${progress}%`);
}
});CSS Variable Reference
All tokens are available as CSS variables:
/* Colors */
var(--color-primary-500)
var(--color-neutral-100)
var(--color-success-main)
/* Typography */
var(--font-family-sans)
var(--font-size-lg)
var(--font-weight-semibold)
var(--line-height-relaxed)
/* Spacing */
var(--spacing-md)
var(--spacing-lg)
/* Shadows */
var(--shadow-sm)
var(--shadow-lg)
/* Borders */
var(--border-radius-md)
var(--border-width-2)
/* Animation */
var(--duration-normal)
var(--easing-ease-in-out)Advanced Usage
Theme Context
Access theme context directly:
import { ThemeContext } from '@hydrogen-ui/themes';
function MyComponent() {
const context = useContext(ThemeContext);
// Access internal APIs
const { cache, performance, cssManager } = context;
}Custom Token Resolution
import { resolveToken } from '@hydrogen-ui/themes';
// Resolve token path
const color = resolveToken('colors.primary.500', tokens);
// With fallback
const spacing = resolveToken('spacing.custom', tokens, 'spacing.md');Theme Composition
import { composeThemes } from '@hydrogen-ui/themes';
const composedTheme = composeThemes([
baseTheme,
brandOverrides,
seasonalOverrides
]);TypeScript
Full TypeScript support with type exports:
import type {
Theme,
ThemeTokens,
ThemeConfig,
ThemeProviderProps
} from '@hydrogen-ui/themes';
// Type-safe theme names
type ThemeName = 'dawn' | 'craft' | 'studio' | 'b2b' | 'thnk';
// Type-safe token paths
type TokenPath = keyof ThemeTokens;
// Custom theme typing
const myTheme: Theme = {
name: 'my-theme',
tokens: {
// Fully typed token structure
}
};Hydrogen Integration
The theme system is optimized for Hydrogen with dedicated utilities available via a separate import path:
Basic Usage (Works everywhere)
// Works in any React app, including Hydrogen
import { ThemeProvider } from '@hydrogen-ui/themes';
import { HydrogenProvider } from '@hydrogen-ui/core';
export default function App() {
return (
<HydrogenProvider>
<ThemeProvider theme="dawn">
<Outlet />
</ThemeProvider>
</HydrogenProvider>
);
}Hydrogen 2025 Integration
The package is fully compatible with Hydrogen 2025's caching strategies:
// Import Hydrogen-compatible cache strategies
import {
CacheLong, // Drop-in replacement for Hydrogen's CacheLong
CacheShort, // Drop-in replacement for Hydrogen's CacheShort
CacheNone, // Drop-in replacement for Hydrogen's CacheNone
CacheCustom // Drop-in replacement for Hydrogen's CacheCustom
} from '@hydrogen-ui/themes/hydrogen';
// Use exactly like Hydrogen's cache utilities
const data = await storefront.query(QUERY, {
cache: CacheLong() // 1hr + 23hr stale-while-revalidate
});
// Theme-specific helpers
import { withThemeCache, getThemeData } from '@hydrogen-ui/themes/hydrogen';
// In your loader
export async function loader(args: LoaderFunctionArgs) {
// Simple theme data loading
const { theme, tokens } = await getThemeData(args);
return json({ theme, tokens });
}
// Or with more control
export async function loader(args: LoaderFunctionArgs) {
return withThemeCache(args, async ({ context }) => {
const theme = await context.themeCache.loadTheme('dawn');
return json({ theme });
});
}Cache Strategies
// Hydrogen-compatible strategies (exact same API)
import { CacheLong, CacheShort, CacheNone } from '@hydrogen-ui/themes/hydrogen';
// Theme-specific semantic strategies
import { CacheTheme } from '@hydrogen-ui/themes/hydrogen';
CacheTheme.definitions() // Long cache for theme definitions
CacheTheme.css() // Long cache with shorter revalidate for CSS
CacheTheme.list() // Medium cache for theme lists
CacheTheme.preferences() // Private cache for user preferences
CacheTheme.preview() // No cache for previewsTesting
Test components with different themes:
import { renderWithTheme } from '@hydrogen-ui/themes/test-utils';
test('component renders with theme', () => {
const { getByText } = renderWithTheme(
<MyComponent />,
{ theme: 'craft' }
);
expect(getByText('Hello')).toBeInTheDocument();
});Browser Support
- Modern browsers (Chrome, Firefox, Safari, Edge)
- CSS Custom Properties support required
- Fallback values provided for older browsers
Contributing
Adding New Themes
- Create token files in
tokens/themes/your-theme/ - Add theme configuration in
src/themes/ - Run
npm run build:tokensto generate CSS - Update documentation and examples
Token Guidelines
- Follow existing naming conventions
- Ensure color accessibility (WCAG AA)
- Test across all themes
- Document theme use cases
License
MIT
