-
Notifications
You must be signed in to change notification settings - Fork 0
Feature Pluggable Themes
James Maes edited this page Dec 28, 2025
·
1 revision
Enable user-definable theme support for qqq-frontend-material-dashboard, allowing customization of colors, logos, fonts, sizes, icons, and images through backend configuration.
Status: In Development Epic: #290 ADR: ADR-001
Users can define custom themes by configuring QThemeMetaData in their QQQ instance. Theme values are served via the /metaData API and applied at runtime using CSS custom properties.
┌─────────────────────────────────────────────────────────────────┐
│ QQQ Backend │
│ ┌─────────────────────┐ ┌─────────────────────────────────┐ │
│ │ QThemeMetaData │ │ material-dashboard-overlay/ │ │
│ │ (colors, fonts) │ │ (logos, icons, custom CSS) │ │
│ └─────────────────────┘ └─────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼ /metaData API
┌─────────────────────────────────────────────────────────────────┐
│ qqq-frontend-core │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ QThemeMetaData.ts (TypeScript interface) ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ qqq-frontend-material-dashboard │
│ ┌───────────────┐ ┌───────────────┐ ┌────────────────────┐ │
│ │ themeUtils.ts │──│ Theme.ts │──│ Components │ │
│ │ (CSS vars) │ │ (MUI factory) │ │ (use CSS vars) │ │
│ └───────────────┘ └───────────────┘ └────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
| Property | Type | Default | Description |
|---|---|---|---|
primaryColor |
String | #0062FF |
Main brand color (buttons, links) |
secondaryColor |
String | #7b809a |
Secondary actions |
backgroundColor |
String | #f0f2f5 |
Page background |
surfaceColor |
String | #ffffff |
Card/panel backgrounds |
textPrimary |
String | #344767 |
Main text color |
textSecondary |
String | #7b809a |
Muted/secondary text |
errorColor |
String | #F44335 |
Error states |
warningColor |
String | #fb8c00 |
Warning states |
successColor |
String | #4CAF50 |
Success states |
infoColor |
String | #1A73E8 |
Info states |
fontFamily |
String | "Roboto", sans-serif |
Body text font |
headerFontFamily |
String | (inherits fontFamily) | Header font |
borderRadius |
String | 8px |
Global border radius |
density |
String | normal |
compact, normal, or comfortable
|
logoPath |
String | - | Path to logo (via overlay) |
iconPath |
String | - | Path to icon (via overlay) |
faviconPath |
String | - | Path to favicon (via overlay) |
customCss |
String | - | Raw CSS injection (use sparingly) |
QInstance instance = new QInstance();
// Configure theme
QThemeMetaData theme = new QThemeMetaData()
.withPrimaryColor("#1976D2")
.withSecondaryColor("#424242")
.withBackgroundColor("#FAFAFA")
.withFontFamily("'Inter', sans-serif")
.withBorderRadius("12px");
instance.withSupplementalMetaData(theme);All theme values are exposed as CSS custom properties with --qqq- prefix:
| CSS Variable | Maps To |
|---|---|
--qqq-primary-color |
primaryColor |
--qqq-secondary-color |
secondaryColor |
--qqq-background-color |
backgroundColor |
--qqq-surface-color |
surfaceColor |
--qqq-text-primary |
textPrimary |
--qqq-text-secondary |
textSecondary |
--qqq-error-color |
errorColor |
--qqq-warning-color |
warningColor |
--qqq-success-color |
successColor |
--qqq-info-color |
infoColor |
--qqq-font-family |
fontFamily |
--qqq-border-radius |
borderRadius |
.my-component {
background-color: var(--qqq-surface-color);
color: var(--qqq-text-primary);
border-radius: var(--qqq-border-radius);
}
.my-button {
background-color: var(--qqq-primary-color);
color: white;
}| Phase | Description | Issues |
|---|---|---|
| 1 | Backend Foundation | #291, #292, #293 |
| 2 | Frontend Types | #294, #295 |
| 3 | Theme Utilities | #296 |
| 4 | MUI Integration | #297, #298 |
| 5 | Component Migration | #299, #300, #301 |
| 6 | Testing & Docs | #302, #303 |
QBrandingMetaData continues to work for logos and icons. For color theming, migrate to QThemeMetaData:
| QBrandingMetaData | QThemeMetaData |
|---|---|
accentColor |
primaryColor |
logo |
logoPath |
icon |
iconPath |
These features are out of scope for the initial implementation:
- Runtime theme switching (dark mode toggle)
- Theme editor UI in dashboard
- Theme persistence to database
- Theme marketplace/sharing