Refine glass material and environment controls
This commit is contained in:
@@ -2,23 +2,57 @@ import { createAccentVariables, type RgbTuple } from "./accent.js";
|
||||
|
||||
export type NodedcTheme = "dark" | "light";
|
||||
|
||||
export interface NodedcMaterial {
|
||||
/** Base fill used by glass panels, application windows and modals. */
|
||||
panel?: RgbTuple;
|
||||
/** 0–1 alpha for the base glass panel. */
|
||||
panelOpacity?: number;
|
||||
/** Base fill used by text, range and selection fields. */
|
||||
field?: RgbTuple;
|
||||
/** 0–1 alpha for field fill. */
|
||||
fieldOpacity?: number;
|
||||
}
|
||||
|
||||
export interface ApplyThemeOptions {
|
||||
theme?: NodedcTheme;
|
||||
accent?: RgbTuple;
|
||||
material?: NodedcMaterial;
|
||||
}
|
||||
|
||||
function formatRgb([red, green, blue]: RgbTuple): string {
|
||||
return `${red} ${green} ${blue}`;
|
||||
}
|
||||
|
||||
function clampOpacity(value: number): number {
|
||||
return Math.max(0, Math.min(1, value));
|
||||
}
|
||||
|
||||
export function applyNodedcTheme(
|
||||
target: HTMLElement,
|
||||
{ theme = "dark", accent }: ApplyThemeOptions = {},
|
||||
{ theme = "dark", accent, material }: ApplyThemeOptions = {},
|
||||
): void {
|
||||
target.dataset.nodedcTheme = theme;
|
||||
target.dataset.nodedcUi = "true";
|
||||
|
||||
if (!accent) return;
|
||||
const variables = createAccentVariables(accent);
|
||||
Object.entries(variables).forEach(([property, value]) => {
|
||||
target.style.setProperty(property, value);
|
||||
});
|
||||
if (accent) {
|
||||
const variables = createAccentVariables(accent);
|
||||
Object.entries(variables).forEach(([property, value]) => {
|
||||
target.style.setProperty(property, value);
|
||||
});
|
||||
}
|
||||
|
||||
if (!material) return;
|
||||
if (material.panel) target.style.setProperty("--nodedc-panel-material-rgb", formatRgb(material.panel));
|
||||
if (typeof material.panelOpacity === "number" && Number.isFinite(material.panelOpacity)) {
|
||||
const opacity = clampOpacity(material.panelOpacity);
|
||||
target.style.setProperty("--nodedc-panel-material-opacity", String(opacity));
|
||||
target.style.setProperty("--nodedc-panel-material-strong-opacity", String(clampOpacity(opacity + 0.12)));
|
||||
target.style.setProperty("--nodedc-panel-material-soft-opacity", String(clampOpacity(Math.max(0.12, opacity - 0.2))));
|
||||
}
|
||||
if (material.field) target.style.setProperty("--nodedc-field-material-rgb", formatRgb(material.field));
|
||||
if (typeof material.fieldOpacity === "number" && Number.isFinite(material.fieldOpacity)) {
|
||||
target.style.setProperty("--nodedc-field-material-opacity", String(clampOpacity(material.fieldOpacity)));
|
||||
}
|
||||
}
|
||||
|
||||
export function clearNodedcAccent(target: HTMLElement): void {
|
||||
@@ -26,3 +60,13 @@ export function clearNodedcAccent(target: HTMLElement): void {
|
||||
target.style.removeProperty("--nodedc-on-accent-rgb");
|
||||
}
|
||||
|
||||
export function clearNodedcMaterial(target: HTMLElement): void {
|
||||
[
|
||||
"--nodedc-panel-material-rgb",
|
||||
"--nodedc-panel-material-opacity",
|
||||
"--nodedc-panel-material-strong-opacity",
|
||||
"--nodedc-panel-material-soft-opacity",
|
||||
"--nodedc-field-material-rgb",
|
||||
"--nodedc-field-material-opacity",
|
||||
].forEach((property) => target.style.removeProperty(property));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user