Retrospring/app/javascript/retrospring/controllers/theme_controller.ts

80 lines
1.8 KiB
TypeScript

import { Controller } from '@hotwired/stimulus';
import Coloris from '@melloware/coloris';
import {
THEME_MAPPING,
getColorForKey,
getHexColorFromThemeValue,
getIntegerFromHexColor
} from 'utilities/theme';
export default class extends Controller {
static targets = ['color'];
declare readonly colorTargets: HTMLInputElement[];
previewStyle = null;
previewTimeout = null;
setupPreviewElement(): void {
this.previewStyle = document.createElement('style');
this.previewStyle.setAttribute('data-preview-style', '');
document.body.appendChild(this.previewStyle);
}
convertColors(): void {
this.colorTargets.forEach((color) => {
color.value = `#${getHexColorFromThemeValue(color.value)}`;
});
}
connect(): void {
this.setupPreviewElement();
this.convertColors();
Coloris.init();
Coloris({
el: '.color',
wrap: false,
formatToggle: false,
alpha: false
});
}
updatePreview(): void {
clearTimeout(this.previewTimeout);
this.previewTimeout = setTimeout(this.previewTheme.bind(this), 1000);
}
previewTheme(): void {
const payload = {};
this.colorTargets.forEach((color) => {
const name = color.name.substring(6, color.name.length - 1);
payload[name] = parseInt(color.value.substr(1, 6), 16);
});
this.generateTheme(payload);
}
generateTheme(payload: Record<string, string>): void {
let body = ":root {\n";
Object.entries(payload).forEach(([key, value]) => {
if (THEME_MAPPING[key]) {
body += `--${THEME_MAPPING[key]}: ${getColorForKey(THEME_MAPPING[key], value)};\n`;
}
});
body += "}";
this.previewStyle.innerHTML = body;
}
submit(): void {
this.colorTargets.forEach((color) => {
color.value = String(getIntegerFromHexColor(color.value));
});
}
}