mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
- General infrastructure to support palette tweaking - Hue shifts per color scale (UI, permalinks, dynamic code snippets) - Scale overall chroma up/down (UI, permalinks, dynamic code snippets) - Update contrast ratio tables (styling for contrast up/down/fail could use improvement, but it's a starting point) - Make sure it works with Turbo (i.e. things don't break when we navigate to another page)
153 lines
4.6 KiB
JavaScript
153 lines
4.6 KiB
JavaScript
import Prism from '/assets/scripts/prism.js';
|
|
import { cdnUrl, getThemeCode, Permalink } from '/assets/scripts/tweak.js';
|
|
await Promise.all(['wa-select', 'wa-option', 'wa-details'].map(tag => customElements.whenDefined(tag)));
|
|
|
|
const domChange = document.startViewTransition ? document.startViewTransition.bind(document) : fn => fn();
|
|
|
|
let selects, data, codeSnippets;
|
|
|
|
let computed = {
|
|
get isRemixed() {
|
|
return Object.values(data.params).filter(Boolean).length > 0;
|
|
},
|
|
get palette() {
|
|
return data.params.palette || data.defaultParams.palette;
|
|
},
|
|
get brand() {
|
|
return data.params.brand || data.defaultParams.brand;
|
|
},
|
|
};
|
|
|
|
function selectsChanged(event) {
|
|
data.params[event.target.name] = event.target.value;
|
|
render(event.target.name);
|
|
}
|
|
|
|
function init() {
|
|
selects = Object.fromEntries(
|
|
[...document.querySelectorAll('#mix_and_match wa-select')].map(select => [select.getAttribute('name'), select]),
|
|
);
|
|
|
|
codeSnippets = document.querySelector('#usage ~ wa-tab-group.import-stylesheet-code:first-of-type');
|
|
codeSnippets = {
|
|
html: codeSnippets.querySelector('code.language-html'),
|
|
css: codeSnippets.querySelector('code.language-css'),
|
|
};
|
|
|
|
data = {
|
|
baseTheme: wa_data.baseTheme,
|
|
themes: wa_data.themes,
|
|
palettes: wa_data.palettes,
|
|
defaultParams: {
|
|
colors: '',
|
|
get palette() {
|
|
let colors = data.params.colors || data.baseTheme;
|
|
return data.themes[colors].palette;
|
|
},
|
|
get brand() {
|
|
let colors = data.params.colors || data.baseTheme;
|
|
return data.themes[colors].brand;
|
|
},
|
|
typography: '',
|
|
},
|
|
params: { colors: '', palette: '', brand: '', typography: '' },
|
|
urlParams: new Permalink(),
|
|
};
|
|
|
|
data.urlParams.mapObject(data.params);
|
|
data.urlParams.writeTo(data.params);
|
|
|
|
if (computed.isRemixed) {
|
|
// Start with the remixing UI open if the theme has been remixed
|
|
mix_and_match.setAttribute('open', '');
|
|
mix_and_match.open = true;
|
|
}
|
|
|
|
for (let name in selects) {
|
|
selects[name].addEventListener('change', selectsChanged);
|
|
}
|
|
|
|
Promise.all(Object.values(selects).map(select => select.updateComplete)).then(() => render());
|
|
|
|
return { selects, codeSnippets, data, computed, render };
|
|
}
|
|
|
|
globalThis.remixApp = init();
|
|
|
|
// Async load CSS for other themes *before* current theme stylesheet
|
|
let themeStylesheet = document.querySelector('#theme-stylesheet');
|
|
|
|
for (const theme in data.themes) {
|
|
themeStylesheet.insertAdjacentHTML(
|
|
'beforebegin',
|
|
`<link rel="preload" as="style" href="/dist/styles/themes/${theme}/color.css" onload="this.rel = 'stylesheet'" />
|
|
<link rel="preload" as="style" href="/dist/styles/themes/${theme}/typography.css" onload="this.rel = 'stylesheet'" />`,
|
|
);
|
|
}
|
|
|
|
for (const palette in data.palettes) {
|
|
themeStylesheet.insertAdjacentHTML(
|
|
'beforebegin',
|
|
`<link rel="preload" as="style" href="/dist/styles/color/${palette}.css" onload="this.rel = 'stylesheet'" />`,
|
|
);
|
|
}
|
|
|
|
function setDefault(select, value) {
|
|
let oldDefaultOption = select.querySelector(`wa-option[value=""]:not([data-id="${value}"])`);
|
|
let newDefaultOption = select.querySelector(`wa-option[value="${value}"]`);
|
|
|
|
if (oldDefaultOption) {
|
|
oldDefaultOption.value = oldDefaultOption.dataset.id;
|
|
}
|
|
|
|
if (newDefaultOption) {
|
|
newDefaultOption.dataset.id ??= newDefaultOption.value;
|
|
newDefaultOption.value = '';
|
|
}
|
|
}
|
|
|
|
function render(changedAspect) {
|
|
let url = new URL(demo.src);
|
|
|
|
if (!changedAspect || changedAspect === 'colors') {
|
|
// Update the default palette when the theme colors change to the default palette of that theme
|
|
setDefault(selects.palette, data.defaultParams.palette);
|
|
setDefault(selects.brand, data.defaultParams.brand);
|
|
}
|
|
|
|
let brand = data.params.brand || data.defaultParams.brand;
|
|
selects.brand.style.setProperty('--color', `var(--wa-color-${brand})`);
|
|
selects.brand.className = `wa-palette-${computed.palette}`;
|
|
|
|
for (let aspect in data.params) {
|
|
let value = data.params[aspect];
|
|
selects[aspect].value = value;
|
|
}
|
|
|
|
data.urlParams.readFrom(data.params);
|
|
|
|
// Update demo URL
|
|
domChange(() => {
|
|
url.search = data.urlParams;
|
|
demo.src = url;
|
|
return new Promise(resolve => (demo.onload = resolve));
|
|
});
|
|
|
|
// Update page URL
|
|
data.urlParams.updateLocation();
|
|
|
|
// Update code snippets
|
|
for (let language in codeSnippets) {
|
|
let codeSnippet = codeSnippets[language];
|
|
let copyButton = codeSnippet.previousElementSibling;
|
|
let code = getThemeCode(data.baseTheme, data.params, { language, cdnUrl });
|
|
codeSnippet.textContent = code;
|
|
copyButton.value = code;
|
|
Prism.highlightElement(codeSnippet);
|
|
}
|
|
}
|
|
|
|
addEventListener('turbo:render', event => {
|
|
remixApp = init();
|
|
});
|