Sanitized mirror from private repository - 2026-04-22 22:02:15 UTC
This commit is contained in:
201
hosts/physical/concord-nuc/homeassistant/www/assist-fix.js
Normal file
201
hosts/physical/concord-nuc/homeassistant/www/assist-fix.js
Normal file
@@ -0,0 +1,201 @@
|
||||
// Assist textfield readability — v5.
|
||||
//
|
||||
// The new ha-input wraps Web Awesome (wa-input). Web Awesome is a separate
|
||||
// component system that renders LIGHT by default unless told to be dark via:
|
||||
// 1) adding the "wa-dark" class on the root / document element, or
|
||||
// 2) setting its own --wa-* CSS color tokens at :root.
|
||||
//
|
||||
// HA's dark theme flag doesn't propagate to it, so we do both: force wa-dark
|
||||
// class on the html element AND override the wa color tokens to match the
|
||||
// active HA theme. Plus inline-style belt-and-suspenders on the actual input.
|
||||
(function () {
|
||||
if (window.__assistFixLoaded) return;
|
||||
window.__assistFixLoaded = true;
|
||||
|
||||
function v(name, fallback) {
|
||||
const x = getComputedStyle(document.documentElement)
|
||||
.getPropertyValue(name).trim();
|
||||
return x || fallback;
|
||||
}
|
||||
|
||||
function applyGlobalTokens() {
|
||||
const fg = v('--primary-text-color', '#e7e9f4');
|
||||
const bg = v('--card-background-color', 'rgba(22, 24, 40, 0.92)');
|
||||
const bgElev = v('--secondary-background-color', 'rgba(30, 32, 50, 0.95)');
|
||||
const muted = v('--secondary-text-color', '#9a9cb8');
|
||||
const border = v('--divider-color', 'rgba(255,255,255,0.20)');
|
||||
const accent = v('--primary-color', '#a78bfa');
|
||||
|
||||
// 1. Force Web Awesome dark mode class on the html element
|
||||
document.documentElement.classList.add('wa-dark');
|
||||
|
||||
// 2. Inject/refresh a <style> with wa-* color tokens mapped to HA theme
|
||||
let el = document.getElementById('assist-fix-wa-tokens');
|
||||
if (!el) {
|
||||
el = document.createElement('style');
|
||||
el.id = 'assist-fix-wa-tokens';
|
||||
document.head.appendChild(el);
|
||||
}
|
||||
el.textContent = `
|
||||
:root, html.wa-dark, .wa-dark {
|
||||
/* Web Awesome text tokens */
|
||||
--wa-color-text: ${fg};
|
||||
--wa-color-text-link: ${accent};
|
||||
--wa-color-text-quiet: ${muted};
|
||||
--wa-color-text-normal: ${fg};
|
||||
--wa-color-on-quiet: ${fg};
|
||||
--wa-color-on-normal: ${fg};
|
||||
/* Surfaces */
|
||||
--wa-color-surface-default: ${bg};
|
||||
--wa-color-surface-raised: ${bgElev};
|
||||
--wa-color-surface-lowered: ${bg};
|
||||
--wa-color-surface-border: ${border};
|
||||
/* Fills (inputs, buttons) */
|
||||
--wa-color-fill-quiet: ${bg};
|
||||
--wa-color-fill-normal: ${bg};
|
||||
--wa-color-fill-loud: ${accent};
|
||||
/* Borders */
|
||||
--wa-color-border-quiet: ${border};
|
||||
--wa-color-border-normal: ${border};
|
||||
--wa-color-border-loud: ${accent};
|
||||
/* Brand (accent) */
|
||||
--wa-color-brand-on-quiet: ${fg};
|
||||
--wa-color-brand-on-normal: ${fg};
|
||||
--wa-color-brand-fill-quiet: ${bg};
|
||||
--wa-color-brand-fill-normal: ${accent};
|
||||
--wa-color-brand-fill-loud: ${accent};
|
||||
--wa-color-brand-border-quiet: ${border};
|
||||
--wa-color-brand-border-normal: ${accent};
|
||||
/* Neutral scale some components read */
|
||||
--wa-color-neutral-fill-quiet: ${bg};
|
||||
--wa-color-neutral-fill-normal: ${bg};
|
||||
--wa-color-neutral-on-quiet: ${fg};
|
||||
--wa-color-neutral-on-normal: ${fg};
|
||||
--wa-color-neutral-border-quiet: ${border};
|
||||
--wa-color-neutral-border-normal: ${border};
|
||||
|
||||
/* Shoelace-inspired fallbacks (some versions) */
|
||||
--sl-color-neutral-0: ${bg};
|
||||
--sl-color-neutral-50: ${bgElev};
|
||||
--sl-color-neutral-100: ${bg};
|
||||
--sl-color-neutral-200: ${border};
|
||||
--sl-color-neutral-500: ${muted};
|
||||
--sl-color-neutral-700: ${fg};
|
||||
--sl-color-neutral-900: ${fg};
|
||||
--sl-color-neutral-1000: ${fg};
|
||||
--sl-input-background-color: ${bg};
|
||||
--sl-input-color: ${fg};
|
||||
--sl-input-border-color: ${border};
|
||||
--sl-input-label-color: ${muted};
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
function patchHaInput(haInput) {
|
||||
if (!haInput || haInput.__assistFixed) return;
|
||||
const sr = haInput.shadowRoot;
|
||||
if (!sr) return;
|
||||
haInput.__assistFixed = true;
|
||||
const fg = v('--primary-text-color', '#e7e9f4');
|
||||
const bg = v('--card-background-color', 'rgba(22, 24, 40, 0.92)');
|
||||
const muted = v('--secondary-text-color', '#9a9cb8');
|
||||
const border = v('--divider-color', 'rgba(255,255,255,0.20)');
|
||||
|
||||
// CSS via exported parts of wa-input
|
||||
const outer = document.createElement('style');
|
||||
outer.textContent = `
|
||||
:host, wa-input { color: ${fg} !important; }
|
||||
wa-input::part(base) {
|
||||
background-color: ${bg} !important;
|
||||
border-color: ${border} !important;
|
||||
color: ${fg} !important;
|
||||
}
|
||||
wa-input::part(input) {
|
||||
color: ${fg} !important;
|
||||
caret-color: ${fg} !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
wa-input::part(label),
|
||||
wa-input::part(form-control-label) {
|
||||
color: ${muted} !important;
|
||||
}
|
||||
wa-input::part(hint) { color: ${muted} !important; }
|
||||
`;
|
||||
sr.appendChild(outer);
|
||||
|
||||
// Inline styles on the wa-input's internals (deepest possible)
|
||||
const wa = sr.querySelector('wa-input');
|
||||
if (wa && wa.shadowRoot) {
|
||||
const innerStyle = document.createElement('style');
|
||||
innerStyle.textContent = `
|
||||
:host { color: ${fg} !important; }
|
||||
.text-field, div[part="base"] {
|
||||
background-color: ${bg} !important;
|
||||
border-color: ${border} !important;
|
||||
}
|
||||
input, input.control {
|
||||
color: ${fg} !important;
|
||||
caret-color: ${fg} !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
input::placeholder { color: ${muted} !important; opacity: 0.7; }
|
||||
label, .label { color: ${muted} !important; }
|
||||
`;
|
||||
wa.shadowRoot.appendChild(innerStyle);
|
||||
|
||||
const input = wa.shadowRoot.querySelector('input');
|
||||
if (input) {
|
||||
input.style.setProperty('color', fg, 'important');
|
||||
input.style.setProperty('caret-color', fg, 'important');
|
||||
input.style.setProperty('background-color', 'transparent', 'important');
|
||||
}
|
||||
const base = wa.shadowRoot.querySelector('[part="base"]');
|
||||
if (base) {
|
||||
base.style.setProperty('background-color', bg, 'important');
|
||||
base.style.setProperty('border-color', border, 'important');
|
||||
base.style.setProperty('color', fg, 'important');
|
||||
}
|
||||
const label = wa.shadowRoot.querySelector('.label, [part~="label"]');
|
||||
if (label) label.style.setProperty('color', muted, 'important');
|
||||
}
|
||||
}
|
||||
|
||||
function walk(root, depth = 0) {
|
||||
if (!root || depth > 12) return 0;
|
||||
let n = 0;
|
||||
try {
|
||||
root.querySelectorAll('ha-input').forEach(el => { patchHaInput(el); n++; });
|
||||
root.querySelectorAll('*').forEach(el => {
|
||||
if (el.shadowRoot) n += walk(el.shadowRoot, depth + 1);
|
||||
});
|
||||
} catch (e) {}
|
||||
return n;
|
||||
}
|
||||
|
||||
applyGlobalTokens();
|
||||
let n = walk(document);
|
||||
console.log('[assist-fix] v5 initial ha-input styled:', n);
|
||||
|
||||
new MutationObserver(() => { applyGlobalTokens(); walk(document); })
|
||||
.observe(document.body || document.documentElement,
|
||||
{ childList: true, subtree: true });
|
||||
|
||||
window.addEventListener('show-dialog', () => {
|
||||
setTimeout(() => {
|
||||
const nn = walk(document);
|
||||
console.log('[assist-fix] v5 after show-dialog ha-input styled:', nn);
|
||||
}, 150);
|
||||
});
|
||||
|
||||
// Re-run tokens whenever theme might change
|
||||
window.addEventListener('theme-changed', applyGlobalTokens);
|
||||
|
||||
let passes = 0;
|
||||
const iv = setInterval(() => {
|
||||
const nn = walk(document);
|
||||
if (nn > n) { console.log('[assist-fix] v5 now styled:', nn); n = nn; }
|
||||
if (++passes > 240) clearInterval(iv);
|
||||
}, 500);
|
||||
|
||||
console.log('[assist-fix] v5 loaded — wa-dark + wa-* tokens + inline');
|
||||
})();
|
||||
18
hosts/physical/concord-nuc/homeassistant/www/fonts-loader.js
Normal file
18
hosts/physical/concord-nuc/homeassistant/www/fonts-loader.js
Normal file
@@ -0,0 +1,18 @@
|
||||
(function() {
|
||||
if (document.getElementById('vish-themed-fonts')) return;
|
||||
var link = document.createElement('link');
|
||||
link.id = 'vish-themed-fonts';
|
||||
link.rel = 'stylesheet';
|
||||
link.href = 'https://fonts.googleapis.com/css2?' +
|
||||
'family=Exo+2:wght@300;400;500;600;700&' +
|
||||
'family=Rajdhani:wght@400;500;600;700&' +
|
||||
'family=Orbitron:wght@500;600;700;900&' +
|
||||
'family=Share+Tech+Mono&' +
|
||||
'family=Cormorant+Garamond:wght@400;500;600;700&' +
|
||||
'family=Playfair+Display:wght@500;600;700&' +
|
||||
'family=Crimson+Text:wght@400;600&' +
|
||||
'family=Noto+Serif+JP:wght@400;500;700&' +
|
||||
'family=Shippori+Mincho:wght@500;600;700&' +
|
||||
'family=Sawarabi+Mincho&display=swap';
|
||||
document.head.appendChild(link);
|
||||
})();
|
||||
Reference in New Issue
Block a user