Theme Architecture
The theming system consists of:- Theme Colors (
packages/loopar/core/global/themes.js) - Predefined color palettes - Theme Generator (
packages/loopar/core/global/theme-generator.js) - Dynamic CSS generation - Tailwind Configuration (
packages/tailwind-env/tailwind.config.js) - Styling framework
Available Themes
Loopar includes 22 built-in color themes:themes.js
Show Colors Helper
TheshowColors export provides Tailwind CSS class mappings for common colors:
Using showColors
Generating Theme CSS
Dynamically generate theme CSS with light and dark mode support:theme-generator.js
Theme Options
Contrast Threshold
Ensure WCAG accessibility compliance:Dark Mode Intensity
Control dark mode background darkness:Custom Dark Colors
Neutral Themes
Loopar detects neutral themes automatically:theme-generator.js
- Lower saturation in dark mode
- Adjusted color mixing
- Enhanced readability
Generating All Themes
Generate CSS for all available themes:Tailwind Configuration
Loopar uses Tailwind CSS with custom configuration:tailwind.config.js
Using Theme Colors
Apply theme colors in your components:Custom Spacing
Loopar provides custom spacing variables:Custom Animations
Use built-in animations:Dark Mode Support
Toggle dark mode using thedark class:
Color Validation
Validate colors before using them:Preview Dark Background
Preview how a theme’s dark mode will look:Implementing Theme Switcher
// Save theme to local storage
function setTheme(themeName) {
localStorage.setItem('theme', themeName);
applyTheme(themeName);
}
// Get saved theme
function getTheme() {
return localStorage.getItem('theme') || 'blue';
}
import { generateThemeCSS } from "loopar";
function applyTheme(themeName) {
// Generate CSS
const css = generateThemeCSS(themeName, {
includeTitles: true,
contrastThreshold: 4.5,
darkIntensity: 0.95
});
// Inject into page
let styleTag = document.getElementById('theme-styles');
if (!styleTag) {
styleTag = document.createElement('style');
styleTag.id = 'theme-styles';
document.head.appendChild(styleTag);
}
styleTag.textContent = css;
}
import { themes } from "loopar";
function ThemeSelector() {
const currentTheme = getTheme();
return (
<div className="flex gap-2">
{themes.map(theme => (
<button
key={theme.name}
className={`w-8 h-8 rounded-full ${theme.twcolor}`}
onClick={() => setTheme(theme.name)}
aria-label={`Switch to ${theme.name} theme`}
>
{currentTheme === theme.name && '✓'}
</button>
))}
</div>
);
}
CSS Variable Reference
All available CSS variables:Best Practices
// Good - Uses theme colors
<button className="bg-primary text-primary-foreground">
Submit
</button>
// Avoid - Hard-coded colors
<button className="bg-blue-500 text-white">
Submit
</button>
import { getContrast } from "loopar";
const contrast = getContrast(primaryColor, backgroundColor);
if (contrast < 4.5) {
console.warn('Insufficient contrast for WCAG AA');
}
// Works in both modes
<div className="bg-card text-card-foreground border border-border">
Content
</div>
Next Steps
- Creating Modules - Build themed modules
- Controllers Guide - Create themed controllers
- File Management - Handle themed assets