js/components Directory Documentation
This directory contains component utility functions that provide specialized display and interaction capabilities for ComfyUI custom nodes. The components system enables rich content display including text, markdown, images, and videos within the node interface.
Architecture Overview
The components system provides a standardized approach to creating and managing display components that:
- Extend ComfyUI's native widget system with custom functionality
- Support multiple content types with appropriate rendering
- Provide overlay-based display for rich content presentation
- Handle user interaction and content management
- Maintain consistent styling across the interface
Core Components
The components system includes two main categories:
- Display Widgets: Overlay-based widgets for rich content display (text, markdown, images, videos)
- UI Components: Reusable form elements, buttons, and utilities for consistent interface creation
UI Component Files
buttons.js
Purpose: Centralized button creation system with variants and pre-configured options
Complexity: Low
File Size: 310 lines
Dependencies:
- No external dependencies - standalone component
Key Functions:
-
createButton(text, options): Main button creation function with extensive customization- Parameters: Button text, options object (variant, size, icon, onClick, etc.)
- Returns: Configured button element
- Features: Variants, sizes, icons, tooltips, disabled state, custom styles
-
createIconButton(icon, options): Icon-only buttons for compact UI- Parameters: Icon character/emoji, options object
- Returns: Icon button element
- Features: Consistent sizing, hover effects, tooltips
-
createButtonGroup(buttons, options): Group multiple buttons with consistent spacing- Parameters: Array of button elements, options object
- Returns: Container element with grouped buttons
- Features: Horizontal/vertical layout, custom spacing and alignment
-
createConfigButton(configKey, overrides): Quick button creation from predefined configs- Parameters: Config key (e.g., 'save', 'delete', 'refresh'), optional overrides
- Returns: Pre-configured button element
- Features: Common button patterns, consistent styling
Constants:
BUTTON_VARIANTS: Color schemes (primary, success, warning, danger, info, secondary)BUTTON_SIZES: Size options (small, medium, large)BUTTON_CONFIGS: Pre-configured common buttons (refresh, pull, edit, scan, report, save, delete, cancel, confirm)
Usage Example:
import { createButton, createConfigButton, BUTTON_VARIANTS } from '../components/buttons.js';
// Custom button
const saveBtn = createButton('Save', {
variant: BUTTON_VARIANTS.SUCCESS,
icon: '💾',
onClick: () => saveData()
});
// Pre-configured button
const deleteBtn = createConfigButton('delete', {
onClick: () => deleteItem()
});
See Also: docs/BUTTON_COMPONENT_GUIDE.md for complete API reference
clipboard.js
Purpose: Centralized clipboard operations with fallback support
Complexity: Low
File Size: 106 lines
Dependencies:
shared/imageUtils.js(re-exportscopyImageToClipboard)shared/notifications.js(forcopyWithNotification)
Key Functions:
-
copyToClipboard(text): Copy text to clipboard with automatic fallback- Parameters: Text string to copy
- Returns: Promise - success status
- Features: Modern Clipboard API with execCommand fallback
-
readFromClipboard(): Read text from clipboard- Parameters: None
- Returns: Promise - clipboard text content
- Features: Permission handling, error recovery
-
copyWithNotification(text, message, showNotification): Copy with automatic toast- Parameters: Text to copy, optional success message, show notification flag
- Returns: Promise
- Features: Integrated toast notifications, customizable messages
-
isClipboardSupported(): Check clipboard API availability -
isClipboardWriteSupported(): Check write capability -
isClipboardReadSupported(): Check read capability
Re-exports:
copyImageToClipboardfromshared/imageUtils.js
Usage Example:
import { copyToClipboard, copyWithNotification } from '../components/clipboard.js';
// Basic copy
const success = await copyToClipboard('Hello World');
// Copy with notification
await copyWithNotification('Copied text', 'Copied to clipboard!', true);
formElements.js
Purpose: Comprehensive form element creation system for consistent UI
Complexity: Medium-High
File Size: 761 lines
Dependencies:
- No external dependencies - standalone component
Key Functions:
-
createInput(options): Create input elements (text, number, email, password, etc.)- Parameters: Options object (type, value, placeholder, min, max, step, etc.)
- Returns: Input element
- Features: All HTML5 input types, validation, event handlers, ARIA labels
-
createSelect(options): Create dropdown/select elements- Parameters: Options object (items, value, multiple, onChange, etc.)
- Returns: Select element
- Features: Flexible item formats (string, object, optgroup), multiple selection
-
createTextarea(options): Create multi-line text input- Parameters: Options object (rows, cols, placeholder, monospace, etc.)
- Returns: Textarea element
- Features: Auto-sizing, monospace option, keyboard shortcuts support
-
createCheckbox(labelText, options): Create checkbox with integrated label- Parameters: Label text, options object (checked, onChange, etc.)
- Returns: Object with {label, checkbox} elements
- Features: Accessible labeling, custom styling, event handlers
-
createSlider(labelText, options): Create range slider with value display- Parameters: Label text, options object (min, max, step, value, formatValue, etc.)
- Returns: Object with {container, slider, valueDisplay} elements
- Features: Automatic value display, custom formatting, real-time updates
-
createRadioGroup(name, items, options): Create radio button group- Parameters: Group name, items array, options object
- Returns: Object with {container, radios} elements
- Features: Horizontal/vertical layout, pre-selection, change handlers
-
createFormRow(labelText, element, options): Create label + element row- Parameters: Label text, form element, options object
- Returns: Container with labeled form element
- Features: Consistent spacing, required indicators, help text
-
createFormGroup(elements, options): Create grouped form section- Parameters: Array of elements, options object
- Returns: Container with grouped elements
- Features: Section titles, consistent spacing, fieldset support
Constants:
DEFAULT_STYLES: Default CSS styling for all form elements
Helper Functions:
applyStyles(element, styles): Apply CSS styles safely to elements
Usage Examples:
import { createSlider, createSelect, createInput } from '../components/formElements.js';
// Slider with custom formatting
const { container, slider } = createSlider('Temperature', {
min: 0, max: 2, step: 0.1, value: 0.7,
formatValue: (v) => `${v} (randomness)`
});
// Dropdown
const select = createSelect({
items: [
{ value: 'opt1', text: 'Option 1' },
{ value: 'opt2', text: 'Option 2' }
],
value: 'opt1',
onChange: (e) => handleChange(e.target.value)
});
// Input field
const input = createInput({
type: 'number',
placeholder: 'Enter value...',
min: 0, max: 100,
onInput: (e) => updateValue(e.target.value)
});
See Also: docs/FORM_ELEMENTS_GUIDE.md for complete API reference and 40+ examples
tabs.js
Purpose: Comprehensive tab management system with lazy loading and state management
Complexity: Medium
File Size: 576 lines
Dependencies:
- No external dependencies - standalone component
Key Classes:
TabManager: Main class for managing tabbed interfaces- Constructor Parameters: Options object (container, onTabSwitch, onTabInit, lazyLoad, styles)
- Returns: TabManager instance with full tab lifecycle management
- Features: State tracking, lazy loading, visibility control, event callbacks
Key Methods:
-
init(): Initializes the TabManager by creating tab header and content containers- Returns: TabManager instance (chainable)
- Features: Creates DOM structure for tabs
-
addTab(id, label, contentFactory, options): Adds a new tab to the interface- Parameters: Tab ID, label text, content factory function, options object
- Returns: TabManager instance (chainable)
- Features: Lazy loading support, visibility control, custom styles
-
switchTab(tabId): Switches to the specified tab, initializing if needed- Parameters: Tab ID to switch to
- Features: Automatic lazy loading, state management, callback invocation
-
removeTab(tabId): Removes a tab from the interface -
showTab(tabId)/hideTab(tabId): Show or hide specific tabs -
getActiveTab(): Returns the currently active tab ID -
isTabInitialized(tabId): Checks if a tab has been initialized -
getTabIds()/getVisibleTabIds(): Get all or only visible tab IDs -
activateFirstTab(): Activates the first visible tab -
updateVisibility(settings): Updates tab visibility based on settings object -
destroy(): Cleans up all resources and event listeners
Standalone Functions:
createTabButton(text, isActive): Standalone tab button creation (deprecated, use TabManager)- Parameters: Button text, active state
- Returns: Styled button element
- Features: Backward compatibility for legacy code
Usage Example:
import { TabManager } from '../components/tabs.js';
// Create TabManager
const tabManager = new TabManager({
container: document.getElementById('tab-container'),
onTabSwitch: (tabId) => console.log(`Switched to: ${tabId}`),
lazyLoad: true
});
// Initialize and add tabs
tabManager.init()
.addTab('home', 'Home', createHomeContent, { visible: true })
.addTab('settings', 'Settings', createSettingsContent, { visible: true })
.addTab('advanced', 'Advanced', createAdvancedContent, { visible: false });
// Activate first visible tab
tabManager.activateFirstTab();
// Dynamic visibility control
tabManager.updateVisibility({
home: true,
settings: true,
advanced: userIsAdmin
});
See Also: docs/TAB_MANAGER_GUIDE.md for complete API reference
layout.js
Purpose: Comprehensive layout utilities for consistent UI structure
Complexity: Medium
File Size: 680 lines
Dependencies:
- No external dependencies - standalone component
Key Functions:
-
createFlexContainer(options): Flexible box layout with common configurations- Parameters: Options object (direction, justify, align, gap, wrap, padding, etc.)
- Returns: Configured flex container
- Features: Row/column direction, justify content, align items, gap spacing, wrapping
-
createGrid(options): CSS Grid layout with flexible column/row definitions- Parameters: Options object (columns, rows, gap, padding, background, etc.)
- Returns: Configured grid container
- Features: Numeric or string column definitions, auto-fit, custom gaps
-
createResponsiveGrid(options): Auto-fitting grid that adapts to container width- Parameters: Options object (minItemWidth, maxItemWidth, gap, padding, etc.)
- Returns: Responsive grid container using CSS auto-fill
- Features: Automatic column calculation, min/max item widths
-
createCard(options): Card container with optional title and action buttons- Parameters: Options object (title, content, actions, padding, background, etc.)
- Returns: Card element with header and content areas
- Features: Optional title, action buttons in header, custom styling
-
createSection(title, content, options): Titled section with bordered header- Parameters: Title string, content element/HTML, options object
- Returns: Section container with title and content
- Features: Collapsible sections, custom colors and borders
-
createScrollContainer(content, options): Scrollable container with max-height/width- Parameters: Content element/HTML, options object
- Returns: Scrollable container
- Features: Max height/width, show/hide scrollbars, custom styling
-
createSplitPane(leftContent, rightContent, options): Two-column layout with optional resizing- Parameters: Left and right content elements, options object
- Returns: Split pane container
- Features: Configurable split ratios, resizable panes, min widths
-
createCenteredContainer(content, options): Centered container with max-width- Parameters: Content element/HTML, options object
- Returns: Centered container
- Features: Max width, auto margins, custom padding
-
createStack(items, options): Vertical stack with consistent spacing- Parameters: Array of elements, options object
- Returns: Vertical flex container
- Features: Shorthand for column flex layout
-
createInline(items, options): Horizontal inline layout with consistent spacing- Parameters: Array of elements, options object
- Returns: Horizontal flex container
- Features: Shorthand for row flex layout, optional wrapping
Usage Example:
import { createCard, createGrid, createResponsiveGrid, createStack } from '../components/layout.js';
import { createButton, BUTTON_VARIANTS } from '../components/buttons.js';
// Responsive image gallery
const gallery = createResponsiveGrid({
minItemWidth: 200,
gap: '16px',
children: imageElements
});
// Settings card with actions
const editBtn = createButton('Edit', { variant: BUTTON_VARIANTS.INFO });
const card = createCard({
title: 'Model Info',
content: detailsElement,
actions: [editBtn]
});
// Form with stacked fields
const form = createStack([
nameInput,
emailInput,
submitButton
], { gap: '12px' });
// Two-column grid
const twoColumns = createGrid({
columns: 2,
gap: '16px',
children: [leftPanel, rightPanel]
});
See Also: docs/LAYOUT_COMPONENT_GUIDE.md for complete API reference
Display Widget Files
display.js
Purpose: Core widget creation and content display utilities
Complexity: High
Dependencies:
ComfyWidgetsfrom ComfyUI core for base widget functionalityrenderMarkdown, ensureMarkdownStylesfromshared/markdown.jsfor markdown processing
gallery.js
Purpose: Reusable UI components for image gallery and media display
Complexity: High
Dependencies:
stateManager.js,config.js,imageUtils.js,datasetTextManager.jsfrom shared modules- Complex image gallery functionality with thumbnail grids and metadata
cacheUI.js
Purpose: Cache sidebar UI component factory functions
Complexity: Medium
Dependencies:
- Standalone component creation utilities
- Re-exports
createProgressBarfromprogressBar.js - Provides labeled containers, buttons, dropdowns, and styled elements
progressBar.js
Purpose: Centralized progress bar implementations for various UI contexts
Complexity: Medium
Dependencies:
dialogManager.jsfor dialog-based progress display- Standalone progress bar creation utilities
Key Functions:
createProgressBar(labelText): Basic progress bar with label and percentage displaycreateProgressDialog(title, initialMessage): Modal dialog with progress trackingcreateInlineProgressBar(options): Embeddable progress bar for inline UIcreateDatasetProgressDialog(title): Specialized progress dialog with image previewcreateInlineProgressHTML(current, total, message): HTML string generator for quick inline usecreateBatchProgressIndicator(options): Simple progress container for batch operations
navigation.js
Purpose: Navigation controls for image galleries and editors
Complexity: Medium
Dependencies:
- Standalone navigation button creation
- Configurable size, style variants (gradient/flat), and label options
dialogManager.js
Purpose: Modal dialogs and overlay management
Complexity: Medium
Dependencies:
- Standalone dialog creation utilities
- Re-exports
createProgressDialogandcreateInlineProgressBarfromprogressBar.js - Confirmation dialogs, alerts, prompts, and custom dialogs with backdrop blur
infoDisplay.js
Purpose: Detailed model information display with images and metadata
Complexity: High
Dependencies:
stateManager.js,civitai.jsfrom shared modules- Complex model version finding and metadata display functionality
Key Functions:
Core Widget Management
-
createTextOutputWidget(node, app, widgetName = "output"): Creates or retrieves text output widget- Parameters: node instance, ComfyUI app, optional widget name
- Returns: Widget object with readonly text input
- Usage: Base function for creating display widgets across all content types
-
updateTextWidget(widget, message): Updates widget content with defensive handling- Parameters: widget object, message with text content (array or string)
- Features: Handles both array and string inputs, defensive programming for edge cases
- Usage: Safe content updates for dynamic text display
Content Display Systems
-
setupMarkdownDisplay(widget, content): Creates markdown overlay with full HTML rendering- Parameters: text widget, markdown content string
- Features:
- Asynchronous initialization with retry logic
- Complete textarea overlay with styled markdown
- Automatic CSS injection for markdown elements
- Responsive layout with scrolling support
- Z-index management for proper display layering
- Usage: Primary function for rich text content display
-
setupImageDisplay(widget, filename): Creates image overlay with error handling- Parameters: text widget, image filename
- Features:
- Direct image loading from notes directory
- Responsive image scaling and centering
- Comprehensive error handling with user feedback
- Automatic overlay cleanup and replacement
- Support for various image formats
- Usage: Display images within node interface
-
setupVideoDisplay(widget, filename, isSupported = true): Creates video overlay with format validation- Parameters: text widget, video filename, format support flag
- Features:
- Browser-native video controls for supported formats
- Detailed format compatibility information for unsupported files
- Responsive video scaling and centering
- Comprehensive error handling with codec information
- Educational messaging about video format requirements
- Usage: Display videos with format guidance
Technical Architecture
Overlay System Design
The widgets use an overlay approach that provides several advantages:
Positioning Strategy:
- Absolute positioning over existing ComfyUI text widgets
- Parent element modification to
position: relativefor proper containment - Z-index management to ensure proper layering
- Automatic cleanup of previous overlays when switching content types
Content Rendering:
- Markdown: Full HTML rendering with syntax highlighting and styling
- Images: Responsive display with automatic scaling and centering
- Videos: Native browser controls with format compatibility checking
- Text: Fallback display in original textarea for compatibility
Error Handling and Robustness
Initialization Safety:
- Asynchronous widget initialization with retry mechanisms
- Defensive programming for missing DOM elements
- Graceful fallbacks when advanced features are unavailable
- Comprehensive logging for debugging display issues
Content Loading:
- Error handling for failed image/video loads
- User-friendly error messages with actionable guidance
- Format validation and compatibility warnings
- Automatic fallback to text display when media fails
Integration Points
ComfyUI Integration:
- Uses
ComfyWidgets["STRING"]as the base widget type - Preserves ComfyUI's widget management and serialization
- Maintains compatibility with node graph operations
- Respects ComfyUI's styling and theming conventions
Shared System Dependencies:
- Markdown rendering through
shared/markdown.js - File serving through custom server routes (
/sage_utils/read_notes_file) - CSS styling through
ensureMarkdownStyles()injection - Event handling integration with ComfyUI's event system
Usage Patterns
Node Integration
Widgets are typically used in node setup functions:
import { createTextOutputWidget, setupMarkdownDisplay } from "../components/display.js";
// Create base widget
const widget = createTextOutputWidget(nodeData, app, "content");
// Set up content-specific display
setupMarkdownDisplay(widget, markdownContent);
Content Type Switching
The overlay system allows dynamic switching between content types:
// Switch from markdown to image
setupImageDisplay(widget, "image.png");
// Switch back to markdown
setupMarkdownDisplay(widget, "# New Content");
Error Handling
All display functions include comprehensive error handling:
// Image display with automatic error recovery
setupImageDisplay(widget, filename);
// Automatically shows error message if image fails to load
// Video display with format checking
setupVideoDisplay(widget, filename, isSupportedFormat);
// Shows format guidance for unsupported files
File Dependencies
Used By (Import Statements)
nodes/viewNotes.js: All display functions for file preview systemnodes/modelInfoDisplay.js: Text and markdown display functionsnodes/viewAnything.js: Basic text display and update functions
Dependency Graph
widgets/display.js
├── ComfyWidgets (ComfyUI core)
├── shared/markdown.js
│ ├── renderMarkdown()
│ └── ensureMarkdownStyles()
└── Server routes
└── /sage_utils/read_notes_file
Development Guidelines
Widget Creation Standards
- Base Widget Setup: Always use
createTextOutputWidget()as the foundation - Overlay Management: Clean up existing overlays before creating new ones
- Error Handling: Include comprehensive error handling for all content types
- Responsive Design: Ensure content scales properly within widget boundaries
- Accessibility: Maintain keyboard navigation and screen reader compatibility
Content Display Principles
- Graceful Degradation: Always provide text fallback for rich content
- Performance: Use lazy loading and efficient DOM manipulation
- User Feedback: Provide clear error messages and loading states
- Format Support: Clearly communicate supported and unsupported formats
- Consistency: Maintain consistent styling across all content types
Extension Patterns
When adding new content types:
- Follow the overlay pattern established by existing functions
- Include comprehensive error handling and user feedback
- Provide format validation and compatibility information
- Maintain consistency with existing styling and interaction patterns
- Add appropriate cleanup and overlay management
Maintenance Notes
- Overlay Cleanup: Ensure proper cleanup of DOM elements when switching content types
- Memory Management: Remove event listeners and references when widgets are destroyed
- Style Isolation: Maintain CSS encapsulation to avoid conflicts with ComfyUI styling
- Browser Compatibility: Test video and image support across different browsers
- Performance: Monitor DOM manipulation performance with large content
- Component Consistency: Use centralized components (buttons.js, formElements.js, clipboard.js) for all new UI development
- Migration Progress: Legacy button and form creation patterns are being phased out in favor of components
Migration to Component System
The codebase is undergoing a gradual migration to use centralized UI components:
Completed Migrations (Phase 1 & 2)
✅ Button System (buttons.js)
- Files migrated:
modelsTab.js,fileBrowser.js,fileEditor.js,tagLibrary.js,cacheUI.js - Legacy functions deprecated with forwarding for backward compatibility
- ~80 lines of duplicate code eliminated
✅ Clipboard & Toast (clipboard.js + shared/notifications.js)
- Files migrated:
tagLibrary.js,promptBuilderTab.js - Centralized clipboard operations with fallback support
- ~83 lines of duplicate code eliminated
✅ Form Elements (formElements.js)
- Files migrated:
llmTab.js(5991 → 5827 lines, 164 lines saved) - Replaces manual creation of: sliders, selects, inputs, textareas, checkboxes
- Consistent styling and behavior across all form elements
- 14 sliders, 5 selects, 3 inputs, 2 textareas, 2 checkboxes refactored in llmTab.js
Pending Migrations
⚠️ Other Sidebar Tabs (In Progress)
- Files pending:
civitaiSearchTab.js,modelsTab.js,filesTab.js,settingsDialog.js - Estimated: ~100 additional lines to be eliminated
Migration Guidelines
When updating existing code or creating new UI:
-
Buttons: Always use
createButton()orcreateConfigButton()frombuttons.js// Old (deprecated) createStyledButton('Save', '#4CAF50', '💾') // New createButton('Save', { variant: BUTTON_VARIANTS.SUCCESS, icon: '💾' }) // Or even simpler: createConfigButton('save') -
Form Elements: Use functions from
formElements.jsinstead of manual DOM creation// Old (manual creation) const slider = document.createElement('input'); slider.type = 'range'; slider.min = '0'; slider.max = '100'; // ... 15+ more lines // New const { slider, container } = createSlider('Label', { min: 0, max: 100 }); -
Clipboard: Use
copyToClipboard()fromclipboard.js// Old (inline implementation) navigator.clipboard.writeText(text).catch(err => { /* ... */ }); // New await copyToClipboard(text); // Or with notification: await copyWithNotification(text, 'Copied!'); -
Toast Notifications: Use
showToast()fromshared/notifications.jsimport { showToast, NOTIFICATION_TYPES } from '../shared/notifications.js'; showToast('Success!', NOTIFICATION_TYPES.SUCCESS);
Component Documentation References
- buttons.js: See
docs/BUTTON_COMPONENT_GUIDE.md - formElements.js: See
docs/FORM_ELEMENTS_GUIDE.md - Refactoring Progress: See
docs/REFACTORING_PROGRESS.mdfor session-by-session migration details - Component Analysis: See
docs/COMPONENT_DUPLICATION_ANALYSIS.mdfor original analysis and plan
Future Enhancement Opportunities
Display Widgets
- Audio Support: Add audio file display capabilities
- PDF Rendering: Support for PDF file preview
- Code Highlighting: Enhanced syntax highlighting for code blocks
- Interactive Elements: Support for interactive content within widgets
- Thumbnail Generation: Automatic thumbnail creation for media files
UI Components
- Tab Component: Reusable tab system for multi-section interfaces
- Modal System: Standardized modal dialogs (currently in
dialogManager.js, could be enhanced) - Table Component: Data table with sorting, filtering, pagination
- Tree View: Hierarchical data display
- Date/Time Pickers: Specialized input components for temporal data
- Color Picker: Color selection component
- File Upload: Drag-and-drop file upload component
- Autocomplete: Type-ahead search/selection component
Component System Benefits
The centralized component system provides:
- Consistency: Uniform styling and behavior across the application
- Maintainability: Single source of truth for UI patterns - fix once, fix everywhere
- Developer Efficiency: Faster development with pre-built components
- Code Quality: Less duplication, cleaner codebase, easier to test
- Accessibility: Built-in ARIA labels and semantic HTML
- Flexibility: Extensive customization options while maintaining defaults
- Documentation: Comprehensive guides with examples
Total Code Reduction (So Far): ~300+ lines eliminated across Phases 1 & 2
This directory provides the foundation for rich content display within ComfyUI nodes, enabling sophisticated user interfaces while maintaining compatibility with the existing ComfyUI ecosystem.