fix(routes): complete post-refactor dependency wiring cleanup
This commit is contained in:
@@ -1,308 +1,308 @@
|
||||
/**
|
||||
* Theme Adapter
|
||||
* Ensures tooltips match the current dashboard theme
|
||||
* Integrates with Driver.js to apply theme-specific styling
|
||||
*/
|
||||
|
||||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Theme configuration mapping for Driver.js
|
||||
* Maps dashboard themes to Driver.js styling
|
||||
*/
|
||||
const THEME_CONFIGS = {
|
||||
dark: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(0, 0, 0, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
light: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent-strong)',
|
||||
overlayColor: 'rgba(0, 0, 0, 0.5)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent-strong)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
blue: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(25, 8, 172, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
nord: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(46, 52, 64, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
dracula: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(40, 42, 54, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
'solarized-dark': {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(0, 43, 54, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
'solarized-light': {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(253, 246, 227, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ThemeAdapter class
|
||||
* Manages theme integration for the tooltip system
|
||||
*/
|
||||
class ThemeAdapter {
|
||||
constructor() {
|
||||
this.currentTheme = this.getCurrentTheme();
|
||||
this.themeChangeCallbacks = [];
|
||||
this._setupThemeChangeListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current theme name from document root class
|
||||
* @returns {string} Current theme name (e.g., 'dark', 'light', 'blue')
|
||||
*/
|
||||
getCurrentTheme() {
|
||||
const root = document.documentElement;
|
||||
const classList = Array.from(root.classList);
|
||||
|
||||
// Check for theme classes
|
||||
const themeClasses = ['light', 'blue', 'nord', 'dracula', 'solarized-dark', 'solarized-light'];
|
||||
const foundTheme = themeClasses.find(theme => classList.includes(theme));
|
||||
|
||||
// Default to 'dark' if no theme class found
|
||||
return foundTheme || 'dark';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Driver.js theme configuration for current theme
|
||||
* @returns {Object} Theme configuration object
|
||||
*/
|
||||
getDriverTheme() {
|
||||
const themeName = this.getCurrentTheme();
|
||||
const config = THEME_CONFIGS[themeName] || THEME_CONFIGS.dark;
|
||||
|
||||
// Resolve CSS variables to actual values
|
||||
const resolvedConfig = {};
|
||||
for (const [key, value] of Object.entries(config)) {
|
||||
if (typeof value === 'string' && value.startsWith('var(')) {
|
||||
// Extract CSS variable name
|
||||
const varName = value.match(/var\((--[^)]+)\)/)?.[1];
|
||||
if (varName) {
|
||||
const computedValue = getComputedStyle(document.documentElement)
|
||||
.getPropertyValue(varName)
|
||||
.trim();
|
||||
resolvedConfig[key] = computedValue || value;
|
||||
} else {
|
||||
resolvedConfig[key] = value;
|
||||
}
|
||||
} else {
|
||||
resolvedConfig[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return resolvedConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback for theme changes
|
||||
* @param {Function} callback - Function to call when theme changes
|
||||
*/
|
||||
onThemeChange(callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this.themeChangeCallbacks.push(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup theme change listener using MutationObserver
|
||||
* @private
|
||||
*/
|
||||
_setupThemeChangeListener() {
|
||||
const root = document.documentElement;
|
||||
|
||||
// Create observer to watch for class changes on root element
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
|
||||
const newTheme = this.getCurrentTheme();
|
||||
if (newTheme !== this.currentTheme) {
|
||||
const oldTheme = this.currentTheme;
|
||||
this.currentTheme = newTheme;
|
||||
this._notifyThemeChange(newTheme, oldTheme);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Start observing
|
||||
observer.observe(root, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
console.log('[ThemeAdapter] Theme change listener initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all registered callbacks of theme change
|
||||
* @private
|
||||
* @param {string} newTheme - New theme name
|
||||
* @param {string} oldTheme - Old theme name
|
||||
*/
|
||||
_notifyThemeChange(newTheme, oldTheme) {
|
||||
console.log(`[ThemeAdapter] Theme changed: ${oldTheme} → ${newTheme}`);
|
||||
|
||||
this.themeChangeCallbacks.forEach(callback => {
|
||||
try {
|
||||
callback(newTheme, oldTheme);
|
||||
} catch (error) {
|
||||
console.error('[ThemeAdapter] Error in theme change callback:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply theme to Driver.js instance
|
||||
* @param {Object} driver - Driver.js instance
|
||||
*/
|
||||
applyTheme(driver) {
|
||||
if (!driver) {
|
||||
console.warn('[ThemeAdapter] No driver instance provided');
|
||||
return;
|
||||
}
|
||||
|
||||
const themeConfig = this.getDriverTheme();
|
||||
|
||||
// Apply theme configuration to driver
|
||||
// Note: Driver.js v1.0+ uses CSS variables, so we inject a style element
|
||||
this._injectDriverStyles(themeConfig);
|
||||
|
||||
console.log('[ThemeAdapter] Theme applied to driver:', this.currentTheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject custom styles for Driver.js based on theme
|
||||
* @private
|
||||
* @param {Object} themeConfig - Theme configuration
|
||||
*/
|
||||
_injectDriverStyles(themeConfig) {
|
||||
// Remove existing theme styles
|
||||
const existingStyle = document.getElementById('driver-theme-styles');
|
||||
if (existingStyle) {
|
||||
existingStyle.remove();
|
||||
}
|
||||
|
||||
// Create new style element
|
||||
const style = document.createElement('style');
|
||||
style.id = 'driver-theme-styles';
|
||||
style.textContent = `
|
||||
.driver-popover {
|
||||
background: ${themeConfig.backgroundColor} !important;
|
||||
color: ${themeConfig.textColor} !important;
|
||||
border: 1px solid ${themeConfig.borderColor} !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4) !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
}
|
||||
|
||||
.driver-popover-title {
|
||||
color: ${themeConfig.textColor} !important;
|
||||
font-weight: 600 !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
}
|
||||
|
||||
.driver-popover-description {
|
||||
color: ${themeConfig.textColor} !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
}
|
||||
|
||||
.driver-popover-footer button {
|
||||
background: ${themeConfig.primaryColor} !important;
|
||||
color: ${themeConfig.backgroundColor} !important;
|
||||
border: none !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.driver-popover-footer button:hover {
|
||||
opacity: 0.9 !important;
|
||||
}
|
||||
|
||||
.driver-popover-close-btn {
|
||||
color: ${themeConfig.textColor} !important;
|
||||
}
|
||||
|
||||
.driver-overlay {
|
||||
background: ${themeConfig.overlayColor} !important;
|
||||
}
|
||||
|
||||
.driver-highlighted-element {
|
||||
outline: 2px solid ${themeConfig.highlightColor} !important;
|
||||
outline-offset: 4px !important;
|
||||
}
|
||||
|
||||
.driver-popover-progress-text {
|
||||
color: ${themeConfig.textColor} !important;
|
||||
opacity: 0.7 !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
}
|
||||
`;
|
||||
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available theme names
|
||||
* @returns {string[]} Array of theme names
|
||||
*/
|
||||
getAvailableThemes() {
|
||||
return Object.keys(THEME_CONFIGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a theme is available
|
||||
* @param {string} themeName - Theme name to check
|
||||
* @returns {boolean} True if theme is available
|
||||
*/
|
||||
isThemeAvailable(themeName) {
|
||||
return THEME_CONFIGS.hasOwnProperty(themeName);
|
||||
}
|
||||
}
|
||||
|
||||
// Export to global scope
|
||||
window.ThemeAdapter = ThemeAdapter;
|
||||
|
||||
console.log('[ThemeAdapter] Module loaded');
|
||||
|
||||
})(window);
|
||||
/**
|
||||
* Theme Adapter
|
||||
* Ensures tooltips match the current dashboard theme
|
||||
* Integrates with Driver.js to apply theme-specific styling
|
||||
*/
|
||||
|
||||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Theme configuration mapping for Driver.js
|
||||
* Maps dashboard themes to Driver.js styling
|
||||
*/
|
||||
const THEME_CONFIGS = {
|
||||
dark: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(0, 0, 0, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
light: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent-strong)',
|
||||
overlayColor: 'rgba(0, 0, 0, 0.5)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent-strong)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
blue: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(25, 8, 172, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
nord: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(46, 52, 64, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
dracula: {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(40, 42, 54, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
'solarized-dark': {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(0, 43, 54, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
},
|
||||
'solarized-light': {
|
||||
backgroundColor: 'var(--card-base)',
|
||||
textColor: 'var(--fg)',
|
||||
primaryColor: 'var(--accent)',
|
||||
overlayColor: 'rgba(253, 246, 227, 0.7)',
|
||||
borderColor: 'var(--border)',
|
||||
highlightColor: 'var(--accent)',
|
||||
fontFamily: "'Sami Grotesk', 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ThemeAdapter class
|
||||
* Manages theme integration for the tooltip system
|
||||
*/
|
||||
class ThemeAdapter {
|
||||
constructor() {
|
||||
this.currentTheme = this.getCurrentTheme();
|
||||
this.themeChangeCallbacks = [];
|
||||
this._setupThemeChangeListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current theme name from document root class
|
||||
* @returns {string} Current theme name (e.g., 'dark', 'light', 'blue')
|
||||
*/
|
||||
getCurrentTheme() {
|
||||
const root = document.documentElement;
|
||||
const classList = Array.from(root.classList);
|
||||
|
||||
// Check for theme classes
|
||||
const themeClasses = ['light', 'blue', 'nord', 'dracula', 'solarized-dark', 'solarized-light'];
|
||||
const foundTheme = themeClasses.find(theme => classList.includes(theme));
|
||||
|
||||
// Default to 'dark' if no theme class found
|
||||
return foundTheme || 'dark';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Driver.js theme configuration for current theme
|
||||
* @returns {Object} Theme configuration object
|
||||
*/
|
||||
getDriverTheme() {
|
||||
const themeName = this.getCurrentTheme();
|
||||
const config = THEME_CONFIGS[themeName] || THEME_CONFIGS.dark;
|
||||
|
||||
// Resolve CSS variables to actual values
|
||||
const resolvedConfig = {};
|
||||
for (const [key, value] of Object.entries(config)) {
|
||||
if (typeof value === 'string' && value.startsWith('var(')) {
|
||||
// Extract CSS variable name
|
||||
const varName = value.match(/var\((--[^)]+)\)/)?.[1];
|
||||
if (varName) {
|
||||
const computedValue = getComputedStyle(document.documentElement)
|
||||
.getPropertyValue(varName)
|
||||
.trim();
|
||||
resolvedConfig[key] = computedValue || value;
|
||||
} else {
|
||||
resolvedConfig[key] = value;
|
||||
}
|
||||
} else {
|
||||
resolvedConfig[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return resolvedConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback for theme changes
|
||||
* @param {Function} callback - Function to call when theme changes
|
||||
*/
|
||||
onThemeChange(callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this.themeChangeCallbacks.push(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup theme change listener using MutationObserver
|
||||
* @private
|
||||
*/
|
||||
_setupThemeChangeListener() {
|
||||
const root = document.documentElement;
|
||||
|
||||
// Create observer to watch for class changes on root element
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
|
||||
const newTheme = this.getCurrentTheme();
|
||||
if (newTheme !== this.currentTheme) {
|
||||
const oldTheme = this.currentTheme;
|
||||
this.currentTheme = newTheme;
|
||||
this._notifyThemeChange(newTheme, oldTheme);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Start observing
|
||||
observer.observe(root, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
console.log('[ThemeAdapter] Theme change listener initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all registered callbacks of theme change
|
||||
* @private
|
||||
* @param {string} newTheme - New theme name
|
||||
* @param {string} oldTheme - Old theme name
|
||||
*/
|
||||
_notifyThemeChange(newTheme, oldTheme) {
|
||||
console.log(`[ThemeAdapter] Theme changed: ${oldTheme} → ${newTheme}`);
|
||||
|
||||
this.themeChangeCallbacks.forEach(callback => {
|
||||
try {
|
||||
callback(newTheme, oldTheme);
|
||||
} catch (error) {
|
||||
console.error('[ThemeAdapter] Error in theme change callback:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply theme to Driver.js instance
|
||||
* @param {Object} driver - Driver.js instance
|
||||
*/
|
||||
applyTheme(driver) {
|
||||
if (!driver) {
|
||||
console.warn('[ThemeAdapter] No driver instance provided');
|
||||
return;
|
||||
}
|
||||
|
||||
const themeConfig = this.getDriverTheme();
|
||||
|
||||
// Apply theme configuration to driver
|
||||
// Note: Driver.js v1.0+ uses CSS variables, so we inject a style element
|
||||
this._injectDriverStyles(themeConfig);
|
||||
|
||||
console.log('[ThemeAdapter] Theme applied to driver:', this.currentTheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject custom styles for Driver.js based on theme
|
||||
* @private
|
||||
* @param {Object} themeConfig - Theme configuration
|
||||
*/
|
||||
_injectDriverStyles(themeConfig) {
|
||||
// Remove existing theme styles
|
||||
const existingStyle = document.getElementById('driver-theme-styles');
|
||||
if (existingStyle) {
|
||||
existingStyle.remove();
|
||||
}
|
||||
|
||||
// Create new style element
|
||||
const style = document.createElement('style');
|
||||
style.id = 'driver-theme-styles';
|
||||
style.textContent = `
|
||||
.driver-popover {
|
||||
background: ${themeConfig.backgroundColor} !important;
|
||||
color: ${themeConfig.textColor} !important;
|
||||
border: 1px solid ${themeConfig.borderColor} !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4) !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
}
|
||||
|
||||
.driver-popover-title {
|
||||
color: ${themeConfig.textColor} !important;
|
||||
font-weight: 600 !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
}
|
||||
|
||||
.driver-popover-description {
|
||||
color: ${themeConfig.textColor} !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
}
|
||||
|
||||
.driver-popover-footer button {
|
||||
background: ${themeConfig.primaryColor} !important;
|
||||
color: ${themeConfig.backgroundColor} !important;
|
||||
border: none !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.driver-popover-footer button:hover {
|
||||
opacity: 0.9 !important;
|
||||
}
|
||||
|
||||
.driver-popover-close-btn {
|
||||
color: ${themeConfig.textColor} !important;
|
||||
}
|
||||
|
||||
.driver-overlay {
|
||||
background: ${themeConfig.overlayColor} !important;
|
||||
}
|
||||
|
||||
.driver-highlighted-element {
|
||||
outline: 2px solid ${themeConfig.highlightColor} !important;
|
||||
outline-offset: 4px !important;
|
||||
}
|
||||
|
||||
.driver-popover-progress-text {
|
||||
color: ${themeConfig.textColor} !important;
|
||||
opacity: 0.7 !important;
|
||||
font-family: ${themeConfig.fontFamily} !important;
|
||||
}
|
||||
`;
|
||||
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available theme names
|
||||
* @returns {string[]} Array of theme names
|
||||
*/
|
||||
getAvailableThemes() {
|
||||
return Object.keys(THEME_CONFIGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a theme is available
|
||||
* @param {string} themeName - Theme name to check
|
||||
* @returns {boolean} True if theme is available
|
||||
*/
|
||||
isThemeAvailable(themeName) {
|
||||
return Object.hasOwn(THEME_CONFIGS, themeName);
|
||||
}
|
||||
}
|
||||
|
||||
// Export to global scope
|
||||
window.ThemeAdapter = ThemeAdapter;
|
||||
|
||||
console.log('[ThemeAdapter] Module loaded');
|
||||
|
||||
})(window);
|
||||
|
||||
Reference in New Issue
Block a user