11 KiB
11 KiB
Button Component Quick Reference
Component: js/components/buttons.js
Status: ✅ Ready to Use
Updated: October 12, 2025
Import
import {
createButton,
createIconButton,
createButtonGroup,
createConfigButton,
BUTTON_VARIANTS,
BUTTON_SIZES,
BUTTON_CONFIGS
} from '../components/buttons.js';
Basic Usage
Simple Button
const button = createButton('Click Me');
Button with Variant
const saveBtn = createButton('Save', {
variant: BUTTON_VARIANTS.SUCCESS
});
const deleteBtn = createButton('Delete', {
variant: BUTTON_VARIANTS.DANGER
});
Button with Click Handler
const refreshBtn = createButton('Refresh', {
variant: BUTTON_VARIANTS.INFO,
onClick: () => {
console.log('Refreshing...');
}
});
Button with Icon
const saveBtn = createButton('Save', {
variant: BUTTON_VARIANTS.SUCCESS,
icon: '💾'
});
// Result: "💾 Save"
Button with Custom Color
const customBtn = createButton('Custom', {
color: '#9C27B0' // Overrides variant
});
Sizes
const smallBtn = createButton('Small', {
size: BUTTON_SIZES.SMALL // 11px font, 4px 8px padding
});
const mediumBtn = createButton('Medium', {
size: BUTTON_SIZES.MEDIUM // 12px font, 6px 12px padding (default)
});
const largeBtn = createButton('Large', {
size: BUTTON_SIZES.LARGE // 14px font, 8px 16px padding
});
Variants
const variants = {
primary: createButton('Primary', { variant: BUTTON_VARIANTS.PRIMARY }), // Blue #2196F3
secondary: createButton('Secondary', { variant: BUTTON_VARIANTS.SECONDARY }), // Gray #757575
success: createButton('Success', { variant: BUTTON_VARIANTS.SUCCESS }), // Green #4CAF50
warning: createButton('Warning', { variant: BUTTON_VARIANTS.WARNING }), // Orange #FF9800
danger: createButton('Danger', { variant: BUTTON_VARIANTS.DANGER }), // Red #f44336
info: createButton('Info', { variant: BUTTON_VARIANTS.INFO }) // Cyan #00BCD4
};
Pre-configured Buttons
Use createConfigButton() for common buttons:
const refreshBtn = createConfigButton('refresh');
const pullBtn = createConfigButton('pull');
const editBtn = createConfigButton('edit');
const scanBtn = createConfigButton('scan');
const reportBtn = createConfigButton('report');
const saveBtn = createConfigButton('save');
const deleteBtn = createConfigButton('delete');
const cancelBtn = createConfigButton('cancel');
const confirmBtn = createConfigButton('confirm');
Override Config Options
const saveBtn = createConfigButton('save', {
onClick: () => saveFile(),
disabled: true
});
Icon Buttons
Icon-only buttons (no text):
const editIcon = createIconButton('✏️', {
variant: BUTTON_VARIANTS.WARNING,
title: 'Edit item'
});
const deleteIcon = createIconButton('🗑️', {
variant: BUTTON_VARIANTS.DANGER,
title: 'Delete item'
});
Button Groups
Multiple buttons in a row:
const saveBtn = createButton('Save', { variant: BUTTON_VARIANTS.SUCCESS });
const cancelBtn = createButton('Cancel', { variant: BUTTON_VARIANTS.SECONDARY });
const deleteBtn = createButton('Delete', { variant: BUTTON_VARIANTS.DANGER });
const buttonGroup = createButtonGroup([saveBtn, cancelBtn, deleteBtn], {
gap: '8px',
marginTop: '16px',
wrap: true
});
container.appendChild(buttonGroup);
Advanced Options
All Available Options
const button = createButton('Advanced', {
// Appearance
variant: BUTTON_VARIANTS.PRIMARY, // Button variant
size: BUTTON_SIZES.MEDIUM, // Button size
icon: '🚀', // Icon/emoji to prepend
color: '#custom', // Custom color (overrides variant)
// Behavior
onClick: () => {}, // Click handler
disabled: false, // Disabled state
// Attributes
id: 'my-button-id', // Element ID
className: 'my-button', // Additional CSS class
title: 'Tooltip text', // Tooltip
// Styling
hoverEffect: true, // Enable hover opacity (default: true)
marginTop: '8px', // Top margin (default: '8px')
// Custom overrides
style: { // Any CSS style overrides
fontWeight: 'bold',
borderRadius: '8px'
}
});
Button with ID
const searchBtn = createButton('Search', {
id: 'search-button',
variant: BUTTON_VARIANTS.SUCCESS
});
// Can now be found with: document.getElementById('search-button')
Disabled Button
const disabledBtn = createButton('Disabled', {
disabled: true,
variant: BUTTON_VARIANTS.SUCCESS
});
// Automatically: cursor: not-allowed, opacity: 0.6, click handler disabled
No Hover Effect
const staticBtn = createButton('Static', {
hoverEffect: false
});
Custom Margin
const noMarginBtn = createButton('No Margin', {
marginTop: '0'
});
Complete Examples
File Browser Action Buttons
const actions = document.createElement('div');
actions.style.cssText = 'display: flex; gap: 8px;';
if (allowCreate) {
const createBtn = createButton('Create File', {
variant: BUTTON_VARIANTS.SUCCESS,
size: 'small',
marginTop: '0',
onClick: () => this.callbacks.onFileCreate()
});
actions.appendChild(createBtn);
}
const refreshBtn = createButton('Refresh', {
variant: BUTTON_VARIANTS.WARNING,
size: 'small',
marginTop: '0',
onClick: () => this.loadFiles()
});
actions.appendChild(refreshBtn);
File Editor Buttons
const saveBtn = createButton('Save', {
variant: BUTTON_VARIANTS.SUCCESS,
icon: '💾',
disabled: true,
onClick: () => this.saveFile()
});
const deleteBtn = createButton('Delete', {
variant: BUTTON_VARIANTS.DANGER,
icon: '🗑️',
disabled: true,
onClick: async () => {
if (confirm('Delete this file?')) {
await this.deleteFile();
}
}
});
// Enable when file is loaded
this.currentFile = file;
saveBtn.disabled = false;
deleteBtn.disabled = false;
Modal Dialog Buttons
const confirmBtn = createButton('Confirm', {
variant: BUTTON_VARIANTS.PRIMARY,
icon: '✓',
onClick: () => {
dialog.close();
onConfirm();
}
});
const cancelBtn = createButton('Cancel', {
variant: BUTTON_VARIANTS.SECONDARY,
icon: '✖',
onClick: () => dialog.close()
});
const buttonGroup = createButtonGroup([confirmBtn, cancelBtn], {
gap: '12px',
marginTop: '20px'
});
dialog.appendChild(buttonGroup);
Migration from Old Patterns
From createStyledButton()
// OLD ❌
const btn = createStyledButton('Save', '#4CAF50', '💾');
// NEW ✅
const btn = createButton('Save', {
variant: BUTTON_VARIANTS.SUCCESS,
icon: '💾'
});
// OR use config ✅
const btn = createConfigButton('save');
From createActionButton()
// OLD ❌
const btn = this.createActionButton('Delete', '#f44336', () => {
this.deleteFile();
});
// NEW ✅
const btn = createButton('Delete', {
variant: BUTTON_VARIANTS.DANGER,
size: 'small',
onClick: () => this.deleteFile()
});
// OR use config ✅
const btn = createConfigButton('delete', {
size: 'small',
onClick: () => this.deleteFile()
});
From Manual Button Creation
// OLD ❌
const button = document.createElement('button');
button.textContent = 'Save';
button.style.cssText = `
background: #4CAF50;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
`;
button.addEventListener('click', () => save());
// NEW ✅
const button = createButton('Save', {
variant: BUTTON_VARIANTS.SUCCESS,
onClick: () => save()
});
Style Customization
Override Individual Styles
const button = createButton('Custom', {
variant: BUTTON_VARIANTS.PRIMARY,
style: {
borderRadius: '20px',
fontWeight: 'bold',
textTransform: 'uppercase',
minWidth: '120px'
}
});
Use Custom Colors with Variants
// Purple button with all variant features
const purpleBtn = createButton('Custom Purple', {
color: '#9C27B0',
size: BUTTON_SIZES.LARGE
});
Available Constants
BUTTON_VARIANTS
BUTTON_VARIANTS = {
PRIMARY: 'primary', // #2196F3
SECONDARY: 'secondary', // #757575
SUCCESS: 'success', // #4CAF50
WARNING: 'warning', // #FF9800
DANGER: 'danger', // #f44336
INFO: 'info' // #00BCD4
}
BUTTON_SIZES
BUTTON_SIZES = {
SMALL: 'small', // 11px, 4px 8px
MEDIUM: 'medium', // 12px, 6px 12px (default)
LARGE: 'large' // 14px, 8px 16px
}
BUTTON_CONFIGS
BUTTON_CONFIGS = {
refresh: { text: 'Refresh', variant: BUTTON_VARIANTS.SUCCESS, icon: '↻' },
pull: { text: 'Pull', variant: BUTTON_VARIANTS.INFO, icon: '⬇' },
edit: { text: 'Edit', variant: BUTTON_VARIANTS.WARNING, icon: '✏' },
scan: { text: 'Scan All', color: '#9C27B0', icon: '🔍' },
report: { text: 'Generate Report', color: '#673AB7', icon: '📊' },
save: { text: 'Save', variant: BUTTON_VARIANTS.SUCCESS, icon: '💾' },
delete: { text: 'Delete', variant: BUTTON_VARIANTS.DANGER, icon: '🗑️' },
cancel: { text: 'Cancel', variant: BUTTON_VARIANTS.SECONDARY, icon: '✖' },
confirm: { text: 'Confirm', variant: BUTTON_VARIANTS.PRIMARY, icon: '✓' }
}
Best Practices
- Use Variants: Prefer
variantover customcolorfor consistency - Use Configs: Use
createConfigButton()for common buttons - Group Buttons: Use
createButtonGroup()for multiple related buttons - Set Titles: Add
titlefor tooltips on icon buttons - Disable Properly: Use
disabled: trueinstead of manual opacity changes - Reset Margins: Set
marginTop: '0'when inside flex containers
Common Patterns
Conditional Button
const button = allowEdit
? createConfigButton('edit', { onClick: () => edit() })
: createButton('View', { variant: BUTTON_VARIANTS.INFO });
Toggle Button State
function setModified(isModified) {
saveBtn.disabled = !isModified;
// Disabled state automatically handles opacity
}
Dynamic Button Group
const buttons = [];
if (allowSave) buttons.push(createConfigButton('save', { onClick: save }));
if (allowDelete) buttons.push(createConfigButton('delete', { onClick: del }));
buttons.push(createConfigButton('cancel', { onClick: cancel }));
const group = createButtonGroup(buttons);
Need Help? Check the main component documentation in components/buttons.js