# Adding Custom Background Colors/Gradients to Plugins in UI ## Overview Plan for allowing plugins to define custom background colors or gradients that will be displayed in the browser control panel UI. This will help visually differentiate plugins and group them by category or functionality. Plugins can specify either a single color or multiple colors to create a left-to-right gradient. ## Implementation Steps ### 1. Backend: Add `bg_color` field to `PluginMetadata` **File:** `lib/plugin_loader.py` Add optional `bg_color` field to the `PluginMetadata` dataclass as a list of colors: ```python @dataclass class PluginMetadata: """Plugin metadata describing the plugin's interface and behavior.""" name: str # URL-safe name: "wikipedia-search" description: str # What the plugin does (shown as button label) methods: list[str] = None # HTTP methods, defaults to ["POST"] parameters: list[PluginParameter] = None # Parameter schema for validation and UI bg_color: list[str] = None # Optional background color(s) - single color or list for gradient (left-to-right) def __post_init__(self): if self.methods is None: self.methods = ["POST"] if self.parameters is None: self.parameters = [] ``` **Why:** - List allows both single color (1 item) and gradients (2+ items) - Will be serialized with plugin info when `/plugins` endpoint is called - Frontend can detect list length and apply solid color or gradient accordingly ### 2. Backend: Ensure `bg_color` is included in API response **File:** `routers/plugin.py` Verify that the `/plugins` endpoint returns the `bg_color` field as a list. If using dataclass serialization, it should be automatic. Otherwise, add it to the response dict. Example check: ```python # Should include bg_color in the plugin metadata serialization { "name": "plugin-name", "description": "Plugin Description", "bg_color": ["#ff6600", "#ff8800"], # <-- ensure this is present as list "parameters": [...] } ``` ### 3. Frontend: Apply `bg_color` to plugin buttons with gradient support **File:** `html/browser_control.html` Modify the `createPluginUI()` function to apply background color or gradient to the button: ```javascript function createPluginUI(plugin) { const div = document.createElement('div'); div.className = 'operation'; // Create button const button = document.createElement('button'); button.textContent = plugin.description; button.onclick = () => executePlugin(plugin); // Apply custom background color/gradient if provided if (plugin.bg_color && Array.isArray(plugin.bg_color) && plugin.bg_color.length > 0) { if (plugin.bg_color.length === 1) { // Single color: solid background button.style.background = plugin.bg_color[0]; } else { // Multiple colors: create left-to-right gradient const gradient = `linear-gradient(to right, ${plugin.bg_color.join(', ')})`; button.style.background = gradient; } // Optional: Calculate contrasting text color for readability button.style.color = getContrastTextColor(plugin.bg_color[0]); } // ... rest of function } // Helper function to determine text color based on background luminance function getContrastTextColor(bgColor) { // Simple heuristic: light bg -> dark text, dark bg -> light text // Can use more sophisticated approach if needed // For now, return white or black based on first color return '#fff'; // or '#000' based on luminance calculation } ``` ### 4. Frontend (Optional): Add hover/active state handling **File:** `html/browser_control.css` or inline styles Consider how hover and active states should look with custom colors/gradients. Best option is to use `filter` CSS property which works with both solid colors and gradients: ```css .operation button[style*="background"] { transition: filter 0.2s ease; } .operation button[style*="background"]:hover { filter: brightness(1.1); } .operation button[style*="background"]:active { filter: brightness(0.9); } ``` This approach works seamlessly with both solid colors and gradients. ### 5. Documentation: Update plugin template **File:** `docs/ADDING_PLUGINS.md` Add `bg_color` to the plugin template: ```python metadata = PluginMetadata( name="your-plugin", description="Button Label", methods=["POST"], bg_color=["#4CAF50"], # Optional: Custom button color or gradient (list of colors) parameters=[...] ) ``` Add section explaining the feature: ```markdown ### Custom Background Color/Gradient Plugins can specify a custom background color or gradient for their button in the UI using a list of colors: ```python # Single color (solid background) bg_color=["#ff6600"] # Two colors (gradient left-to-right) bg_color=["#ff6600", "#ff8800"] # Multiple colors (multi-stop gradient) bg_color=["#667eea", "#764ba2", "#f093fb"] # Any CSS color format works bg_color=["rgb(255, 102, 0)", "rgb(255, 136, 0)"] bg_color=["orange", "darkorange"] ``` If not specified, the default button styling will be used. Gradients always flow from left to right. ``` ### 6. Example: Update existing plugin **File:** `plugins/nytimes_search/plugin.py` (or any other) Add `bg_color` to demonstrate (solid or gradient): ```python # Solid color example metadata = PluginMetadata( name="nytimes-search", description="NYTimes Search", methods=["POST"], bg_color=["#6C9EB5"], # NYTimes blue-ish color parameters=[...] ) # Gradient example metadata = PluginMetadata( name="archive-save", description="Archive Save", methods=["POST"], bg_color=["#4CAF50", "#2E7D32"], # Green gradient parameters=[...] ) ``` ## Color Suggestions Recommended colors/gradients for different plugin categories: ### Solid Colors - **Search/Research:** Blue shades (`["#3b9dbb"]`, `["#4285F4"]`) - **Archive/Storage:** Green shades (`["#4CAF50"]`, `["#2E7D32"]`) - **Data Extraction:** Orange shades (`["#ff6600"]`, `["#FF9800"]`) - **Form Filling:** Purple shades (`["#9C27B0"]`, `["#6A1B9A"]`) - **Navigation:** Teal shades (`["#009688"]`, `["#00796B"]`) ### Gradient Examples - **Search/Research:** `["#667eea", "#764ba2"]` (purple-blue) - **Archive/Storage:** `["#4CAF50", "#2E7D32", "#1B5E20"]` (green gradient) - **Data Extraction:** `["#ff6600", "#ff8800", "#ffaa00"]` (orange gradient) - **Form Filling:** `["#9C27B0", "#E91E63"]` (purple-pink) - **Navigation:** `["#00bcd4", "#009688"]` (cyan-teal) ## Testing Checklist - [ ] Add `bg_color` field to `PluginMetadata` dataclass as list - [ ] Verify `/plugins` endpoint returns `bg_color` as list - [ ] Update `createPluginUI()` to apply solid color or gradient - [ ] Test with single color (solid background) - [ ] Test with two colors (simple gradient) - [ ] Test with 3+ colors (multi-stop gradient) - [ ] Test with various color formats (hex, rgb, CSS names) - [ ] Verify readability with both light and dark colors - [ ] Test hover/active states with `filter` CSS - [ ] Update plugin template in documentation - [ ] Add `bg_color` to at least one existing plugin as example (both solid and gradient) ## Edge Cases to Consider 1. **Invalid color values:** Let browser handle invalid CSS (will fall back to default) 2. **Empty list:** Treat `[]` same as `None` - use default styling 3. **Single color in list:** Apply as solid background, not gradient 4. **Accessibility:** Ensure sufficient contrast between button color and text (use first color for contrast calculation) 5. **No color specified:** Fall back to default button styling 6. **Very long gradient lists:** Browser will handle, but keep it short (2-4 colors recommended) 7. **Color conflicts:** Multiple plugins with same color/gradient (acceptable, user's choice) ## Alternative Approaches (Not Recommended) - **String vs List:** Use string and parse for gradient (e.g., `"#fff, #000"`) - less type-safe, harder to validate - **Gradient direction field:** Allow custom gradient directions - adds complexity, left-to-right is standard - **Theme-based:** Define color themes centrally rather than per-plugin (less flexible) - **Category-based:** Auto-assign colors based on plugin category (requires category system) - **Card background:** Apply color to entire plugin card instead of just button (more visual noise)