Skip to content

Instantly share code, notes, and snippets.

@ricardobeat
Last active March 31, 2025 22:35
Show Gist options
  • Save ricardobeat/05cff84697909213523c05cee07fbe35 to your computer and use it in GitHub Desktop.
Save ricardobeat/05cff84697909213523c05cee07fbe35 to your computer and use it in GitHub Desktop.
Thanks Claude
// UI Controls Generator
(function() {
// Create a container for our controls
const container = document.createElement('div');
container.id = 'ui-controls-container';
container.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background-color: #fafafa;
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
z-index: 9999;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
font-family: Arial, sans-serif;
max-width: 600px;
font-size: 11px;
`;
document.body.appendChild(container);
// Create a header
const header = document.createElement('div');
header.style.cssText = `
font-weight: bold;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #ddd;
display: flex;
justify-content: space-between;
align-items: center;
`;
const title = document.createElement('span')
title.textContent = 'UI Controls';
header.append(title)
// Add collapse button
const collapseBtn = document.createElement('button');
collapseBtn.innerHTML = '−';
collapseBtn.style.cssText = `
background: none;
border: none;
cursor: pointer;
font-size: 14px;
width: 20px;
height: 20px;
`;
const controlsWrapper = document.createElement('div');
controlsWrapper.id = 'ui-controls-wrapper';
controlsWrapper.style.cssText = `
column-count: 2;
column-gap: 12px;
`
let isCollapsed = false;
collapseBtn.addEventListener('click', () => {
isCollapsed = !isCollapsed;
controlsWrapper.style.display = isCollapsed ? 'none' : 'block';
collapseBtn.innerHTML = isCollapsed ? '+' : '−';
});
header.prepend(collapseBtn);
container.appendChild(header);
container.appendChild(controlsWrapper);
// Store references to all controls
const controls = {};
// Expose the UI Controls API to the window
window.UIControls = {
setTitle: function (s = "Controls") {
title.innerText = s
},
/**
* Add a toggle control
* @param {string} id - Unique identifier for the control
* @param {string} label - Display name for the control
* @param {boolean} initialValue - Initial state (true=checked, false=unchecked)
* @param {function} callback - Function to call when toggled, receives boolean value
* @returns {Object} - Control interface
*/
add: function(id, label, initialValue = false, callback = null) {
if (controls[id]) {
console.warn(`Control with ID '${id}' already exists. Returning existing control.`);
return controls[id];
}
const controlWrapper = document.createElement('div');
controlWrapper.style.cssText = `
margin-bottom: 4px;
display: flex;
align-items: center;
`;
const toggle = document.createElement('input');
toggle.type = 'checkbox';
toggle.id = `ui-control-${id}`;
toggle.checked = initialValue;
toggle.style.cssText = `
margin-right: 8px;
`;
const labelEl = document.createElement('label');
labelEl.htmlFor = toggle.id;
labelEl.textContent = label;
labelEl.style.cssText = `
flex-grow: 1;
cursor: pointer;
`;
controlWrapper.appendChild(toggle);
controlWrapper.appendChild(labelEl);
controlsWrapper.appendChild(controlWrapper);
// Handle toggle events
toggle.addEventListener('change', function() {
if (typeof callback === 'function') {
callback(toggle.checked);
}
});
// Store reference to control
const control = {
element: controlWrapper,
toggle: toggle,
set: function(value) {
const checked = !!value;
if (toggle.checked !== checked) {
toggle.checked = checked;
if (typeof callback === 'function') {
callback(checked);
}
}
return this;
},
get: function() {
return toggle.checked;
},
remove: function() {
controlWrapper.remove();
delete controls[id];
}
};
controls[id] = control;
return control;
},
/**
* Get a control by ID
* @param {string} id - Control identifier
* @returns {Object|null} - Control interface or null if not found
*/
get: function(id) {
return controls[id] || null;
},
/**
* Remove a control by ID
* @param {string} id - Control identifier
* @returns {boolean} - True if removed, false if not found
*/
remove: function(id) {
if (controls[id]) {
controls[id].remove();
return true;
}
return false;
},
/**
* Hide the controls panel
*/
hide: function() {
container.style.display = 'none';
},
/**
* Show the controls panel
*/
show: function() {
container.style.display = 'block';
},
/**
* Make the panel draggable
* @param {boolean} draggable - Whether to enable dragging
*/
setDraggable: function(draggable = true) {
if (draggable) {
let isDragging = false;
let offsetX, offsetY;
header.style.cursor = 'move';
header.addEventListener('mousedown', function(e) {
// Only handle drag on header (not buttons)
if (e.target === header) {
isDragging = true;
offsetX = e.clientX - container.getBoundingClientRect().left;
offsetY = e.clientY - container.getBoundingClientRect().top;
}
});
document.addEventListener('mousemove', function(e) {
if (isDragging) {
container.style.left = (e.clientX - offsetX) + 'px';
container.style.top = (e.clientY - offsetY) + 'px';
container.style.right = 'auto';
}
});
document.addEventListener('mouseup', function() {
isDragging = false;
});
} else {
header.style.cursor = 'default';
// Would need to remove event listeners here if disabling dragging
}
}
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment