Implement Style Editor, Preview, and Settings Schema

This commit is contained in:
2026-01-05 20:42:17 +01:00
parent 0dcfe1ce98
commit e7e06ea875
8 changed files with 418 additions and 55 deletions

75
src/lib/utils.ts Normal file
View File

@@ -0,0 +1,75 @@
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
import { OverlaySettings } from "./types";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
export function generateOverlayCSS(settings: OverlaySettings): string {
// Convert backgroundOpacity (0-1) to hex alpha if needed, or use rgba
// Here we assume CSS Injection will be used as a <style> tag or returned by API
const r = parseInt(settings.backgroundColor.slice(1, 3), 16);
const g = parseInt(settings.backgroundColor.slice(3, 5), 16);
const b = parseInt(settings.backgroundColor.slice(5, 7), 16);
const rgbaBackground = `rgba(${r}, ${g}, ${b}, ${settings.backgroundOpacity})`;
return `
:root {
--chat-font-family: ${settings.fontFamily};
--chat-font-size: ${settings.fontSize};
--chat-text-color: ${settings.textColor};
--chat-bg-color: ${rgbaBackground};
--chat-text-shadow: ${settings.textShadow};
--chat-spacing: ${settings.messageSpacing};
}
body {
background-color: transparent;
margin: 0;
padding: 0;
overflow: hidden;
font-family: var(--chat-font-family);
}
.chat-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 1rem;
box-sizing: border-box;
}
.chat-message {
background-color: var(--chat-bg-color);
color: var(--chat-text-color);
text-shadow: var(--chat-text-shadow);
font-size: var(--chat-font-size);
margin-bottom: var(--chat-spacing);
padding: 0.5rem;
border-radius: 4px;
word-wrap: break-word;
animation: fadeIn 0.2s ease-out;
}
.username {
font-weight: bold;
margin-right: 0.5rem;
}
.badges {
display: ${settings.showBadges ? 'inline-flex' : 'none'};
margin-right: 0.25rem;
vertical-align: middle;
gap: 0.25rem;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
`;
}