-
-
Notifications
You must be signed in to change notification settings - Fork 0
Fix spacer background transparency and replace native color picker with custom UI #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -286,3 +286,66 @@ applyTheme(DEFAULT_THEME); | |
| applyTemplate('grid'); | ||
| applyPlatform('mobile'); | ||
| startBlobAnimation(); | ||
|
|
||
| // Custom color picker initialization | ||
| (function initCustomPicker() { | ||
| const wrap = document.getElementById('custom-picker-wrap'); | ||
| const trigger = document.getElementById('custom-picker-trigger'); | ||
| const panel = document.getElementById('custom-picker-panel'); | ||
| const swatch = document.getElementById('cp-swatch'); | ||
| const hexInput = document.getElementById('cp-hex'); | ||
| const hueSlider = document.getElementById('cp-hue'); | ||
| const satSlider = document.getElementById('cp-sat'); | ||
| const litSlider = document.getElementById('cp-lit'); | ||
|
|
||
| if (!wrap) return; | ||
|
|
||
| function hslToHex(h, s, l) { | ||
| s /= 100; l /= 100; | ||
| const a = s * Math.min(l, 1 - l); | ||
| const f = n => { | ||
| const k = (n + h / 30) % 12; | ||
| return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); | ||
| }; | ||
| return '#' + [f(0), f(8), f(4)].map(x => | ||
| Math.round(x * 255).toString(16).padStart(2, '0') | ||
| ).join(''); | ||
| } | ||
|
|
||
| function updateFromSliders() { | ||
| const h = +hueSlider.value, s = +satSlider.value, l = +litSlider.value; | ||
| const hex = hslToHex(h, s, l); | ||
| swatch.style.background = hex; | ||
| hexInput.value = hex; | ||
| trigger.style.background = hex; | ||
| trigger.classList.add('active'); | ||
| satSlider.style.background = `linear-gradient(to right, hsl(${h},0%,${l}%), hsl(${h},100%,${l}%))`; | ||
| litSlider.style.background = `linear-gradient(to right, hsl(${h},${s}%,10%), hsl(${h},${s}%,50%), hsl(${h},${s}%,90%))`; | ||
| applyCustomTheme(hex); | ||
| } | ||
|
|
||
| trigger.addEventListener('click', (e) => { | ||
| e.stopPropagation(); | ||
| panel.classList.toggle('open'); | ||
| }); | ||
|
|
||
| document.addEventListener('click', (e) => { | ||
| if (!wrap.contains(e.target)) panel.classList.remove('open'); | ||
| }); | ||
|
|
||
| hueSlider.addEventListener('input', updateFromSliders); | ||
| satSlider.addEventListener('input', updateFromSliders); | ||
| litSlider.addEventListener('input', updateFromSliders); | ||
|
|
||
| hexInput.addEventListener('input', (e) => { | ||
| const val = e.target.value; | ||
| if (/^#[0-9a-fA-F]{6}$/.test(val)) { | ||
| swatch.style.background = val; | ||
| trigger.style.background = val; | ||
| trigger.classList.add('active'); | ||
| applyCustomTheme(val); | ||
| } | ||
|
Comment on lines
+340
to
+347
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hex input path does not sync slider positions. When a valid hex is typed, Line 346 updates theme but leaves H/S/L sliders unchanged, so the next slider move can jump to an unrelated color. 🔧 Suggested approach+ function hexToHsl(hex) {
+ const { r, g, b } = hexToRgb(hex);
+ const rn = r / 255, gn = g / 255, bn = b / 255;
+ const max = Math.max(rn, gn, bn), min = Math.min(rn, gn, bn);
+ const d = max - min;
+ let h = 0;
+ const l = (max + min) / 2;
+ const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
+ if (d !== 0) {
+ if (max === rn) h = 60 * (((gn - bn) / d) % 6);
+ else if (max === gn) h = 60 * ((bn - rn) / d + 2);
+ else h = 60 * ((rn - gn) / d + 4);
+ }
+ if (h < 0) h += 360;
+ return { h: Math.round(h), s: Math.round(s * 100), l: Math.round(l * 100) };
+ }
@@
hexInput.addEventListener('input', (e) => {
const val = e.target.value;
if (/^#[0-9a-fA-F]{6}$/.test(val)) {
+ const { h, s, l } = hexToHsl(val);
+ hueSlider.value = h;
+ satSlider.value = s;
+ litSlider.value = l;
swatch.style.background = val;
trigger.style.background = val;
trigger.classList.add('active');
applyCustomTheme(val);
+ satSlider.style.background = `linear-gradient(to right, hsl(${h},0%,${l}%), hsl(${h},100%,${l}%))`;
+ litSlider.style.background = `linear-gradient(to right, hsl(${h},${s}%,10%), hsl(${h},${s}%,50%), hsl(${h},${s}%,90%))`;
}
});🤖 Prompt for AI Agents |
||
| }); | ||
|
|
||
| updateFromSliders(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Calling Useful? React with 👍 / 👎. |
||
| })(); | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -34,7 +34,24 @@ <h1>GitHub Social <span>Preview</span></h1> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="theme-dot" data-theme="orange"></div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="theme-dot" data-theme="red"></div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="theme-dot" data-theme="cyan"></div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <input type="color" id="custom-color-picker" value="#58a6ff" aria-label="Pick custom theme color"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="color-picker-wrap" id="custom-picker-wrap"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="theme-dot color-picker-trigger" id="custom-picker-trigger" title="Custom color"></div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This new trigger reuses the Useful? React with 👍 / 👎. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <input type="color" id="custom-color-picker" value="#58a6ff" aria-label="Pick custom theme color"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="color-picker-panel" id="custom-picker-panel"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="cp-preview-row"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="cp-swatch" id="cp-swatch"></div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <input class="cp-hex-input" id="cp-hex" type="text" maxlength="7" value="#58a6ff" spellcheck="false"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="cp-sliders"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <label class="cp-label">Hue</label> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <input class="cp-range cp-hue" id="cp-hue" type="range" min="0" max="360" value="213"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <label class="cp-label">Saturation</label> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <input class="cp-range cp-sat" id="cp-sat" type="range" min="0" max="100" value="100"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <label class="cp-label">Lightness</label> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <input class="cp-range cp-lit" id="cp-lit" type="range" min="10" max="90" value="61"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify semantic trigger + control associations for the custom picker.
rg -n 'id="custom-picker-trigger"|aria-controls="custom-picker-panel"|aria-expanded=|for="cp-(hue|sat|lit)"|id="cp-(hue|sat|lit)"|id="cp-hex"' index.htmlRepository: readme-SVG/github-social-preview-generator Length of output: 653 🏁 Script executed: # Search for JavaScript handling of the custom-picker-trigger
rg -A 10 "custom-picker-trigger" --type jsRepository: readme-SVG/github-social-preview-generator Length of output: 750 🏁 Script executed: # Check for CSS that hides the native color input
rg -n "custom-color-picker|color-picker-panel" --type css -A 3Repository: readme-SVG/github-social-preview-generator Length of output: 590 🏁 Script executed: # Check if there's any keyboard event handling or ARIA updates in JS
rg -n "addEventListener|keydown|keypress|keyup|aria-expanded" --type js | head -30Repository: readme-SVG/github-social-preview-generator Length of output: 1183 🏁 Script executed: # Get the full trigger click handler to see if there's keyboard support or focus management
rg -A 5 "trigger.addEventListener\('click'" assets/js/app.jsRepository: readme-SVG/github-social-preview-generator Length of output: 258 🏁 Script executed: # Check if there's any focus management or keyboard event listeners elsewhere
rg -B 2 -A 5 "custom-picker-trigger" assets/js/app.js | head -50Repository: readme-SVG/github-social-preview-generator Length of output: 543 🏁 Script executed: # Verify the label structure in HTML (check if labels are inside or outside the inputs)
sed -n '45,51p' index.htmlRepository: readme-SVG/github-social-preview-generator Length of output: 627 Custom picker trigger is not keyboard-accessible. The trigger on line 38 uses a ♿ Proposed markup fix- <div class="theme-dot color-picker-trigger" id="custom-picker-trigger" title="Custom color"></div>
+ <button
+ type="button"
+ class="theme-dot color-picker-trigger"
+ id="custom-picker-trigger"
+ title="Custom color"
+ aria-label="Custom color picker"
+ aria-controls="custom-picker-panel"
+ aria-expanded="false"
+ ></button>
@@
- <input class="cp-hex-input" id="cp-hex" type="text" maxlength="7" value="#58a6ff" spellcheck="false">
+ <input class="cp-hex-input" id="cp-hex" type="text" maxlength="7" value="#58a6ff" spellcheck="false" aria-label="Hex color value">
@@
- <label class="cp-label">Hue</label>
+ <label class="cp-label" for="cp-hue">Hue</label>
@@
- <label class="cp-label">Saturation</label>
+ <label class="cp-label" for="cp-sat">Saturation</label>
@@
- <label class="cp-label">Lightness</label>
+ <label class="cp-label" for="cp-lit">Lightness</label>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="template-row"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialization force-switches the app into custom theme mode.
Line 350 calls
updateFromSliders(), and Line 324 then callsapplyCustomTheme(hex). This overrides the default/preset theme state on load.🐛 Proposed fix
Also applies to: 350-350
🤖 Prompt for AI Agents