Token Transformation
Overview
Section titled “Overview”The TokenTransformer is a core component of Sparkle’s theme system that enables cross-platform token transformation. It converts design tokens between web format (CSS custom properties) and React Native format (StyleSheet values) while maintaining type safety and performance through intelligent caching.
Related Pages
Section titled “Related Pages”- Theme Overview - Introduction to Sparkle’s theme system
- Theme Providers - Setup and configuration guides
- Complete Workflow - End-to-end implementation guide
- Advanced Customization - Enterprise patterns and custom transformers
- Troubleshooting - Common issues and performance optimization
Core Concepts
Section titled “Core Concepts”Platform-Specific Formats
Section titled “Platform-Specific Formats”Design tokens need different formats for different platforms:
Web Format (CSS Custom Properties):
:root { --color-primary-500: #3b82f6; --spacing-md: 1rem; --font-size-base: 1rem;}React Native Format (StyleSheet Values):
// Example of transformed native tokensconst nativeTokens = { colorPrimary500: '#3b82f6', spacingMd: 16, fontSizeBase: 16,}TokenTransformer Class
Section titled “TokenTransformer Class”The TokenTransformer handles the conversion between these formats automatically:
import {lightTokens, TokenTransformer} from '@sparkle/theme'
const transformer = new TokenTransformer()
// Transform to web formatconst webTokens = transformer.toWeb(lightTokens)// Result: { '--color-primary-500': '#3b82f6', '--spacing-md': '1rem', ... }
// Transform to React Native formatconst nativeTokens = transformer.toNative(lightTokens)// Result: { colorPrimary500: '#3b82f6', spacingMd: 16, ... }Basic Usage
Section titled “Basic Usage”Web Applications
Section titled “Web Applications”For web applications, transform tokens to CSS custom properties:
import {lightTokens, TokenTransformer} from '@sparkle/theme'
const transformer = new TokenTransformer()
// Basic transformationconst cssVariables = transformer.toWeb(lightTokens)
// With custom prefixconst prefixedVariables = transformer.toWeb(lightTokens, {prefix: 'sparkle'})// Result: { '--sparkle-color-primary-500': '#3b82f6', ... }React Native Applications
Section titled “React Native Applications”For React Native, transform tokens to native StyleSheet values:
import {lightTokens, TokenTransformer} from '@sparkle/theme'
const transformer = new TokenTransformer()
// Basic transformationconst nativeTheme = transformer.toNative(lightTokens)
// With custom base font size (affects rem calculations)const customNativeTheme = transformer.toNative(lightTokens, { baseFontSize: 18,})
// With flattened color structure for easier accessconst flattenedTheme = transformer.toNative(lightTokens, { flattenColors: true,})Advanced Usage
Section titled “Advanced Usage”Full Transformation Control
Section titled “Full Transformation Control”Use the main transform method for complete control:
import {lightTokens, TokenTransformer} from '@sparkle/theme'
const transformer = new TokenTransformer()
// Web transformation with metadataconst webResult = transformer.transform(lightTokens, { platform: 'web', prefix: 'app',})
console.log(webResult.platform) // 'web'console.log(webResult.tokens) // CSS custom properties objectconsole.log(webResult.metadata.tokenCount) // Number of generated tokensconsole.log(webResult.metadata.transformedAt) // ISO timestamp
// Native transformation with optionsconst nativeResult = transformer.transform(lightTokens, { platform: 'native', baseFontSize: 16, flattenColors: false,})Caching and Performance
Section titled “Caching and Performance”The TokenTransformer includes intelligent caching to improve performance:
import {darkTokens, lightTokens, TokenTransformer} from '@sparkle/theme'
const transformer = new TokenTransformer()
// First call - performs transformation and caches resultconst result1 = transformer.toWeb(lightTokens)
// Second call with same tokens - returns cached result instantlyconst result2 = transformer.toWeb(lightTokens)
// Different tokens - performs new transformationconst result3 = transformer.toWeb(darkTokens)
// Check cache statisticsconst stats = transformer.getCacheStats()console.log(`Cache size: ${stats.size}`)console.log(`Cache keys: ${stats.keys}`)
// Clear cache when needed (e.g., after token updates)transformer.clearCache()Transformation Options
Section titled “Transformation Options”Web Platform Options
Section titled “Web Platform Options”interface WebTransformOptions { platform: 'web' /** CSS custom property prefix (default: no prefix) */ prefix?: string}
// Examplestransformer.toWeb(tokens, {prefix: 'sparkle'})// → '--sparkle-color-primary-500': '#3b82f6'
transformer.toWeb(tokens, {prefix: 'theme'})// → '--theme-color-primary-500': '#3b82f6'React Native Platform Options
Section titled “React Native Platform Options”interface NativeTransformOptions { platform: 'native' /** Base font size for rem calculations (default: 16) */ baseFontSize?: number /** Whether to flatten color objects for easier access (default: false) */ flattenColors?: boolean}
// Examplestransformer.toNative(tokens, {baseFontSize: 18})// → Converts 1rem to 18 instead of 16
transformer.toNative(tokens, {flattenColors: true})// → { primary500: '#3b82f6' } instead of { primary: { 500: '#3b82f6' } }Token Utilities
Section titled “Token Utilities”The package also includes utility functions for common token operations:
import {lightTokens, tokenUtils} from '@sparkle/theme'
// Compare two themesconst differences = tokenUtils.compareThemes(lightTokens, darkTokens)console.log(differences) // Array of changed token paths
// Extract color paletteconst colors = tokenUtils.extractColorPalette(lightTokens)console.log(colors) // Object with all color values
// Get semantic color namesconst colorNames = tokenUtils.getColorNames(lightTokens)console.log(colorNames) // ['primary', 'secondary', 'success', ...]
// Get spacing scale keysconst spacingKeys = tokenUtils.getSpacingKeys(lightTokens)console.log(spacingKeys) // ['xs', 'sm', 'md', 'lg', ...]
// Merge themes with overridesconst customTheme = tokenUtils.mergeThemes(lightTokens, { colors: { primary: {500: '#custom-color'}, },})Integration Patterns
Section titled “Integration Patterns”Web Component Integration
Section titled “Web Component Integration”import {TokenTransformer, useTheme} from '@sparkle/theme'
function ThemedButton({children}: {children: React.ReactNode}) { const {theme} = useTheme()
// Method 1: Use CSS custom properties (recommended) const buttonStyle = { backgroundColor: 'var(--color-primary-500)', color: 'var(--color-text-inverse)', padding: 'var(--spacing-md)', }
return <button style={buttonStyle}>{children}</button>
// Method 2: Transform tokens manually const transformer = new TokenTransformer() const cssVars = transformer.toWeb(theme)
return <button style={{backgroundColor: cssVars['--color-primary-500']}}>{children}</button>}React Native Component Integration
Section titled “React Native Component Integration”import {TokenTransformer, useTheme} from '@sparkle/theme'
import {StyleSheet, Text, TouchableOpacity} from 'react-native'
function ThemedButton({children}: {children: string}) { const {theme} = useTheme() const transformer = new TokenTransformer() const nativeTokens = transformer.toNative(theme)
const styles = StyleSheet.create({ button: { backgroundColor: nativeTokens.colorPrimary500, paddingHorizontal: nativeTokens.spacingMd, paddingVertical: nativeTokens.spacingSm, borderRadius: nativeTokens.borderRadiusMd, }, text: { color: nativeTokens.colorTextInverse, fontSize: nativeTokens.fontSizeBase, fontWeight: nativeTokens.fontWeightMedium, }, })
return ( <TouchableOpacity style={styles.button}> <Text style={styles.text}>{children}</Text> </TouchableOpacity> )}Theme Provider Integration
Section titled “Theme Provider Integration”The TokenTransformer is used internally by theme providers but can also be used directly:
// Web - CSS variables are automatically injectedimport {ThemeProvider} from '@sparkle/theme'
function App() { return ( <ThemeProvider defaultTheme="light"> <YourComponents /> </ThemeProvider> )}// React Native - Use transformer to convert tokens as neededimport {NativeThemeProvider} from '@sparkle/theme'
// React Native - Use transformer to convert tokens as neededimport {NativeThemeProvider} from '@sparkle/theme'
function NativeApp() { return ( <NativeThemeProvider defaultTheme="light"> <YourComponents /> </NativeThemeProvider> )}Best Practices
Section titled “Best Practices”1. Use Singleton Pattern for Better Performance
Section titled “1. Use Singleton Pattern for Better Performance”// Create a single transformer instance and reuse itconst globalTransformer = new TokenTransformer()
export {globalTransformer as transformer}2. Cache Transformed Tokens
Section titled “2. Cache Transformed Tokens”import {TokenTransformer, useTheme} from '@sparkle/theme'
import {useMemo} from 'react'
function useNativeTokens() { const {theme} = useTheme()
return useMemo(() => { const transformer = new TokenTransformer() return transformer.toNative(theme) }, [theme])}3. Type-Safe Token Access
Section titled “3. Type-Safe Token Access”import {lightTokens, TokenTransformer} from '@sparkle/theme'
const transformer = new TokenTransformer()const tokens = transformer.toNative(lightTokens)
// TypeScript will provide autocomplete and type checkingconst primaryColor = tokens.colorPrimary500 // ✅ Type-safeconst invalidKey = tokens.nonExistentKey // ❌ TypeScript error4. Error Handling
Section titled “4. Error Handling”import {TokenTransformer} from '@sparkle/theme'
function transformTokensSafely(tokens: ThemeConfig) { try { const transformer = new TokenTransformer() return transformer.toWeb(tokens) } catch (error) { console.error('Token transformation failed:', error) // Return fallback or throw appropriate error return {} }}Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”Issue: Tokens not updating after theme change
Section titled “Issue: Tokens not updating after theme change”// Solution: Clear cache after token updatestransformer.clearCache()const newTokens = transformer.toWeb(updatedTheme)Issue: Performance problems with frequent transformations
Section titled “Issue: Performance problems with frequent transformations”// Solution: Use memoization and cachingconst tokens = useMemo(() => transformer.toNative(theme), [theme]) // Only recalculate when theme changesIssue: Different font sizes between web and native
Section titled “Issue: Different font sizes between web and native”// Solution: Adjust base font size for native platformconst nativeTokens = transformer.toNative(theme, {baseFontSize: 18})Performance Tips
Section titled “Performance Tips”- Reuse transformer instances - Don’t create new instances repeatedly
- Leverage caching - Let the transformer cache results automatically
- Use memoization - Combine with React hooks to prevent unnecessary recalculations
- Clear cache appropriately - Only clear when tokens actually change
API Reference
Section titled “API Reference”For complete API documentation, see the TokenTransformer API reference.