Last active
March 31, 2025 22:35
-
-
Save ricardobeat/05cff84697909213523c05cee07fbe35 to your computer and use it in GitHub Desktop.
Thanks Claude
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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