mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:10:42 +00:00
Update & refactor dark mode (#4114)
## Description: - The renderer no longer knows what "dark mode" is. `RenderSettings.dayNight.mode` (`"light" | "dark"`) is gone — passes read neutral values (`lighting.ambient: number`, `lighting.enabled: boolean`). - `render-settings.json` holds the light-mode baseline. Dark mode is just another override layer, applied the same way as graphics settings (`darkNames`, `classicIcons`, etc.). - New `src/client/render/gl/RenderOverrides.ts` exposes two in-place mutators with matching shapes: - `applyGraphicsOverrides(settings, overrides)` — replaces the old `generateRenderSettings` - `applyDarkModeOverride(settings, isDark)` - `ClientGameRunner` regenerates the live settings each time the user setting changes via `deepAssign(live, createRenderSettings())` + the override chain. No per-slice copy list, no intermediate object — adding a new override that touches a new section just works. - Renamed `dayNight` → `lighting`; collapsed `nightAmbient`/`dayAmbient` into single `ambient`; renamed `enableLightCompositing` → `enabled`. - Bumped dark-mode ambient from 0.15 → 0.35 so terrain stays readable. <img width="1250" height="846" alt="Screenshot 2026-06-02 at 11 47 28 AM" src="https://github.com/user-attachments/assets/b41e8ffb-6011-4ba0-9e1f-c2a21ff90794" /> ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory ## Please put your Discord username so you can be contacted if a bug or regression is found: evan
This commit is contained in:
@@ -69,8 +69,11 @@ import { createCanvas } from "./Utils";
|
||||
import { WebGLFrameBuilder } from "./WebGLFrameBuilder";
|
||||
import { createRenderer, GameRenderer } from "./hud/GameRenderer";
|
||||
import {
|
||||
applyDarkModeOverride,
|
||||
applyGraphicsOverrides,
|
||||
createDebugGui,
|
||||
generateRenderSettings,
|
||||
createRenderSettings,
|
||||
deepAssign,
|
||||
GameView as WebGLGameView,
|
||||
} from "./render/gl";
|
||||
import { ALL_UNIT_TYPES, UnitState } from "./render/types";
|
||||
@@ -474,18 +477,6 @@ async function createClientGame(
|
||||
config,
|
||||
);
|
||||
|
||||
// Bind the WebGL renderer's day/night mode to the existing darkMode
|
||||
// UserSetting so the in-game map matches the rest of the UI. Initial
|
||||
// apply + live updates via the per-key settings-changed event.
|
||||
const applyDayNightMode = (isDark: boolean): void => {
|
||||
view.getSettings().dayNight.mode = isDark ? "dark" : "light";
|
||||
};
|
||||
applyDayNightMode(userSettings.darkMode());
|
||||
globalThis.addEventListener(
|
||||
`${USER_SETTINGS_CHANGED_EVENT}:${DARK_MODE_KEY}`,
|
||||
(e) => applyDayNightMode((e as CustomEvent<string>).detail === "true"),
|
||||
);
|
||||
|
||||
view.setShowPatterns(userSettings.territoryPatterns());
|
||||
globalThis.addEventListener(
|
||||
`${USER_SETTINGS_CHANGED_EVENT}:settings.territoryPatterns`,
|
||||
@@ -493,18 +484,21 @@ async function createClientGame(
|
||||
);
|
||||
|
||||
const graphicsListenerAbort = new AbortController();
|
||||
const applyGraphicsOverrides = (): void => {
|
||||
const generated = generateRenderSettings(
|
||||
userSettings.graphicsOverrides(),
|
||||
);
|
||||
const regenerateRenderSettings = (): void => {
|
||||
const live = view.getSettings();
|
||||
Object.assign(live.name, generated.name);
|
||||
Object.assign(live.structure, generated.structure);
|
||||
deepAssign(live, createRenderSettings());
|
||||
applyGraphicsOverrides(live, userSettings.graphicsOverrides());
|
||||
applyDarkModeOverride(live, userSettings.darkMode());
|
||||
};
|
||||
applyGraphicsOverrides();
|
||||
regenerateRenderSettings();
|
||||
globalThis.addEventListener(
|
||||
`${USER_SETTINGS_CHANGED_EVENT}:${GRAPHICS_KEY}`,
|
||||
applyGraphicsOverrides,
|
||||
regenerateRenderSettings,
|
||||
{ signal: graphicsListenerAbort.signal },
|
||||
);
|
||||
globalThis.addEventListener(
|
||||
`${USER_SETTINGS_CHANGED_EVENT}:${DARK_MODE_KEY}`,
|
||||
regenerateRenderSettings,
|
||||
{ signal: graphicsListenerAbort.signal },
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { GraphicsOverrides } from "./GraphicsOverrides";
|
||||
import type { RenderSettings } from "./RenderSettings";
|
||||
|
||||
const DARK_AMBIENT = 0.35;
|
||||
|
||||
export function applyGraphicsOverrides(
|
||||
settings: RenderSettings,
|
||||
overrides: GraphicsOverrides,
|
||||
): void {
|
||||
if (overrides.name?.nameScaleFactor !== undefined) {
|
||||
settings.name.nameScaleFactor = overrides.name.nameScaleFactor;
|
||||
}
|
||||
if (overrides.name?.cullThreshold !== undefined) {
|
||||
settings.name.cullThreshold = overrides.name.cullThreshold;
|
||||
}
|
||||
if (overrides.structure?.classicIcons === true) {
|
||||
// Classic look: lighter player-colored shape behind a dark icon glyph,
|
||||
// with a touch of translucency.
|
||||
settings.structure.borderDarken = 0.7;
|
||||
settings.structure.fillDarken = 1.0;
|
||||
settings.structure.iconR = 0;
|
||||
settings.structure.iconG = 0;
|
||||
settings.structure.iconB = 0;
|
||||
settings.structure.iconAlpha = 0.75;
|
||||
}
|
||||
if (overrides.name?.darkNames !== undefined) {
|
||||
const dark = overrides.name.darkNames;
|
||||
// Dark: black fill + player-colored outline. Force outline RGB to black
|
||||
// so the shader's defaultFill ramp (mix(uOutlineColor, black, fillT))
|
||||
// collapses to pure black regardless of ambient.
|
||||
// Colored: player-colored fill + white outline (defaults from JSON).
|
||||
settings.name.fillUsePlayerColor = !dark;
|
||||
settings.name.outlineUsePlayerColor = dark;
|
||||
const channel = dark ? 0 : 1;
|
||||
settings.name.outlineR = channel;
|
||||
settings.name.outlineG = channel;
|
||||
settings.name.outlineB = channel;
|
||||
}
|
||||
}
|
||||
|
||||
export function applyDarkModeOverride(
|
||||
settings: RenderSettings,
|
||||
isDark: boolean,
|
||||
): void {
|
||||
if (!isDark) return;
|
||||
settings.lighting.ambient = DARK_AMBIENT;
|
||||
settings.lighting.enabled = true;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import { GraphicsOverrides } from "./GraphicsOverrides";
|
||||
import defaults from "./render-settings.json";
|
||||
|
||||
export interface RenderSettings {
|
||||
@@ -47,10 +46,9 @@ export interface RenderSettings {
|
||||
particleStrength: number;
|
||||
particleFreshScale: number;
|
||||
};
|
||||
dayNight: {
|
||||
mode: "light" | "dark";
|
||||
nightAmbient: number;
|
||||
dayAmbient: number;
|
||||
lighting: {
|
||||
ambient: number;
|
||||
enabled: boolean;
|
||||
falloffPower: number;
|
||||
falloutLightR: number;
|
||||
falloutLightG: number;
|
||||
@@ -296,46 +294,6 @@ export function createRenderSettings(): RenderSettings {
|
||||
return JSON.parse(JSON.stringify(defaults)) as RenderSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a fresh RenderSettings by layering user overrides on top of the
|
||||
* render-settings.json defaults. Pure — does not mutate any input.
|
||||
*/
|
||||
export function generateRenderSettings(
|
||||
overrides: GraphicsOverrides,
|
||||
): RenderSettings {
|
||||
const settings = createRenderSettings();
|
||||
if (overrides.name?.nameScaleFactor !== undefined) {
|
||||
settings.name.nameScaleFactor = overrides.name.nameScaleFactor;
|
||||
}
|
||||
if (overrides.name?.cullThreshold !== undefined) {
|
||||
settings.name.cullThreshold = overrides.name.cullThreshold;
|
||||
}
|
||||
if (overrides.structure?.classicIcons === true) {
|
||||
// Classic look: lighter player-colored shape behind a dark icon glyph,
|
||||
// with a touch of translucency.
|
||||
settings.structure.borderDarken = 0.7;
|
||||
settings.structure.fillDarken = 1.0;
|
||||
settings.structure.iconR = 0;
|
||||
settings.structure.iconG = 0;
|
||||
settings.structure.iconB = 0;
|
||||
settings.structure.iconAlpha = 0.75;
|
||||
}
|
||||
if (overrides.name?.darkNames !== undefined) {
|
||||
const dark = overrides.name.darkNames;
|
||||
// Dark: black fill + player-colored outline. Force outline RGB to black
|
||||
// so the shader's defaultFill ramp (mix(uOutlineColor, black, fillT))
|
||||
// collapses to pure black regardless of ambient.
|
||||
// Colored: player-colored fill + white outline (defaults from JSON).
|
||||
settings.name.fillUsePlayerColor = !dark;
|
||||
settings.name.outlineUsePlayerColor = dark;
|
||||
const channel = dark ? 0 : 1;
|
||||
settings.name.outlineR = channel;
|
||||
settings.name.outlineG = channel;
|
||||
settings.name.outlineB = channel;
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
/** Dump current settings to a downloadable JSON file. */
|
||||
export function dumpSettings(settings: RenderSettings): void {
|
||||
const json = JSON.stringify(settings, null, 2);
|
||||
|
||||
@@ -1208,9 +1208,9 @@ export class GPURenderer {
|
||||
const zoom = this.camera.zoom;
|
||||
const cw = this.canvas.width;
|
||||
const ch = this.canvas.height;
|
||||
const nightActive = this.isNightActive();
|
||||
const compositingActive = this.isLightCompositingActive();
|
||||
|
||||
if (nightActive) {
|
||||
if (compositingActive) {
|
||||
this.resizeSceneTargetIfNeeded(cw, ch);
|
||||
const sceneTex = toTarget(this.gl, this.sceneTarget, () =>
|
||||
this.drawBaseLayer(cam),
|
||||
@@ -1226,8 +1226,8 @@ export class GPURenderer {
|
||||
this.renderOverlays(cam, zoom);
|
||||
}
|
||||
|
||||
private isNightActive(): boolean {
|
||||
return this.settings.dayNight.mode === "dark";
|
||||
private isLightCompositingActive(): boolean {
|
||||
return this.settings.lighting.enabled;
|
||||
}
|
||||
|
||||
private resizeSceneTargetIfNeeded(cw: number, ch: number): void {
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { RenderSettings } from "../RenderSettings";
|
||||
import type { DebugNode } from "./Folder";
|
||||
import { folder } from "./Folder";
|
||||
import { color } from "./props/Color";
|
||||
import { select } from "./props/Select";
|
||||
import { slider } from "./props/Slider";
|
||||
import { toggle } from "./props/Toggle";
|
||||
|
||||
@@ -90,30 +89,29 @@ export function buildTree(s: RenderSettings, d: RenderSettings): DebugNode[] {
|
||||
slider(s.falloutBloom, "particleFreshScale", d.falloutBloom, 0, 1, 0.01),
|
||||
]),
|
||||
|
||||
folder("Day / Night", [
|
||||
select(s.dayNight, "mode", d.dayNight, ["light", "dark"], "Mode"),
|
||||
slider(s.dayNight, "nightAmbient", d.dayNight, 0, 1, 0.01),
|
||||
slider(s.dayNight, "dayAmbient", d.dayNight, 0, 1, 0.01),
|
||||
slider(s.dayNight, "falloffPower", d.dayNight, 0.5, 5, 0.1),
|
||||
slider(s.dayNight, "falloutLightIntensity", d.dayNight, 0, 20, 0.1),
|
||||
slider(s.dayNight, "falloutLightThreshold", d.dayNight, 0, 0.5, 0.001),
|
||||
slider(s.dayNight, "blurZoomDivisor", d.dayNight, 1, 20, 0.5),
|
||||
slider(s.dayNight, "lightRadiusMultiplier", d.dayNight, 0.1, 5, 0.1),
|
||||
folder("Lighting", [
|
||||
toggle(s.lighting, "enabled", d.lighting),
|
||||
slider(s.lighting, "ambient", d.lighting, 0, 1, 0.01),
|
||||
slider(s.lighting, "falloffPower", d.lighting, 0.5, 5, 0.1),
|
||||
slider(s.lighting, "falloutLightIntensity", d.lighting, 0, 20, 0.1),
|
||||
slider(s.lighting, "falloutLightThreshold", d.lighting, 0, 0.5, 0.001),
|
||||
slider(s.lighting, "blurZoomDivisor", d.lighting, 1, 20, 0.5),
|
||||
slider(s.lighting, "lightRadiusMultiplier", d.lighting, 0.1, 5, 0.1),
|
||||
color(
|
||||
s.dayNight,
|
||||
s.lighting,
|
||||
"falloutLightR",
|
||||
"falloutLightG",
|
||||
"falloutLightB",
|
||||
d.dayNight,
|
||||
d.lighting,
|
||||
"Fallout Light Color",
|
||||
),
|
||||
slider(s.dayNight, "emberLightIntensity", d.dayNight, 0, 20, 0.1),
|
||||
slider(s.lighting, "emberLightIntensity", d.lighting, 0, 20, 0.1),
|
||||
color(
|
||||
s.dayNight,
|
||||
s.lighting,
|
||||
"emberLightR",
|
||||
"emberLightG",
|
||||
"emberLightB",
|
||||
d.dayNight,
|
||||
d.lighting,
|
||||
"Ember Light Color",
|
||||
),
|
||||
]),
|
||||
|
||||
@@ -13,10 +13,10 @@ export { GraphicsOverridesSchema } from "./GraphicsOverrides";
|
||||
export type { GraphicsOverrides } from "./GraphicsOverrides";
|
||||
export type { SpawnCenter } from "./passes/SpawnOverlayPass";
|
||||
export {
|
||||
createRenderSettings,
|
||||
dumpSettings,
|
||||
generateRenderSettings,
|
||||
} from "./RenderSettings";
|
||||
applyDarkModeOverride,
|
||||
applyGraphicsOverrides,
|
||||
} from "./RenderOverrides";
|
||||
export { createRenderSettings, dumpSettings } from "./RenderSettings";
|
||||
export type { RenderSettings } from "./RenderSettings";
|
||||
export { deepAssign, deepDiff } from "./SettingsUtils";
|
||||
export { buildTerrainRGBA, getPaletteSize } from "./utils/ColorUtils";
|
||||
|
||||
@@ -192,7 +192,7 @@ export class FalloutLightPass {
|
||||
tick: number,
|
||||
): void {
|
||||
const gl = this.gl;
|
||||
const dn = this.settings.dayNight;
|
||||
const dn = this.settings.lighting;
|
||||
const fb = this.settings.falloutBloom;
|
||||
|
||||
// Step 1: Extract fallout light in tile space
|
||||
|
||||
@@ -166,7 +166,7 @@ export class LightmapPass {
|
||||
const zoom = Math.abs(cameraMatrix[0]);
|
||||
const mapSize = Math.max(this.mapW, this.mapH);
|
||||
const blurScale = Math.min(
|
||||
(zoom * mapSize) / this.settings.dayNight.blurZoomDivisor,
|
||||
(zoom * mapSize) / this.settings.lighting.blurZoomDivisor,
|
||||
1.0,
|
||||
);
|
||||
|
||||
|
||||
@@ -47,8 +47,7 @@ export class NightCompositePass {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
getAmbient(): number {
|
||||
const dn = this.settings.dayNight;
|
||||
return dn.mode === "dark" ? dn.nightAmbient : dn.dayAmbient;
|
||||
return this.settings.lighting.ambient;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -207,7 +207,7 @@ export class PointLightPass {
|
||||
if (this.lightCount === 0) return;
|
||||
|
||||
const gl = this.gl;
|
||||
const dn = this.settings.dayNight;
|
||||
const dn = this.settings.lighting;
|
||||
|
||||
gl.useProgram(this.lightProg);
|
||||
gl.uniformMatrix3fv(this.uLightCam, false, cameraMatrix);
|
||||
|
||||
@@ -44,10 +44,9 @@
|
||||
"particleStrength": 1,
|
||||
"particleFreshScale": 0.2
|
||||
},
|
||||
"dayNight": {
|
||||
"mode": "light",
|
||||
"nightAmbient": 0.15,
|
||||
"dayAmbient": 1,
|
||||
"lighting": {
|
||||
"ambient": 1,
|
||||
"enabled": false,
|
||||
"falloffPower": 2,
|
||||
"falloutLightR": 0.15,
|
||||
"falloutLightG": 0.95,
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { GraphicsOverridesSchema } from "../src/client/render/gl/GraphicsOverrides";
|
||||
import {
|
||||
createRenderSettings,
|
||||
generateRenderSettings,
|
||||
} from "../src/client/render/gl/RenderSettings";
|
||||
GraphicsOverrides,
|
||||
GraphicsOverridesSchema,
|
||||
} from "../src/client/render/gl/GraphicsOverrides";
|
||||
import { applyGraphicsOverrides } from "../src/client/render/gl/RenderOverrides";
|
||||
import { createRenderSettings } from "../src/client/render/gl/RenderSettings";
|
||||
|
||||
function gen(overrides: GraphicsOverrides) {
|
||||
const settings = createRenderSettings();
|
||||
applyGraphicsOverrides(settings, overrides);
|
||||
return settings;
|
||||
}
|
||||
|
||||
describe("GraphicsOverridesSchema", () => {
|
||||
test("accepts empty object", () => {
|
||||
@@ -51,16 +58,16 @@ describe("GraphicsOverridesSchema", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("generateRenderSettings", () => {
|
||||
describe("applyGraphicsOverrides", () => {
|
||||
test("with empty overrides matches createRenderSettings defaults", () => {
|
||||
const fromGen = generateRenderSettings({});
|
||||
const fromGen = gen({});
|
||||
const fromCreate = createRenderSettings();
|
||||
expect(fromGen).toEqual(fromCreate);
|
||||
});
|
||||
|
||||
test("returns a fresh object each call (no shared mutation)", () => {
|
||||
const a = generateRenderSettings({});
|
||||
const b = generateRenderSettings({});
|
||||
const a = gen({});
|
||||
const b = gen({});
|
||||
expect(a).not.toBe(b);
|
||||
expect(a.name).not.toBe(b.name);
|
||||
a.name.nameScaleFactor = 999;
|
||||
@@ -70,27 +77,24 @@ describe("generateRenderSettings", () => {
|
||||
test("does not mutate the overrides input", () => {
|
||||
const overrides = { name: { darkNames: true as const } };
|
||||
const snapshot = JSON.parse(JSON.stringify(overrides));
|
||||
generateRenderSettings(overrides);
|
||||
gen(overrides);
|
||||
expect(overrides).toEqual(snapshot);
|
||||
});
|
||||
|
||||
test("applies nameScaleFactor override", () => {
|
||||
const settings = generateRenderSettings({ name: { nameScaleFactor: 1.3 } });
|
||||
const settings = gen({ name: { nameScaleFactor: 1.3 } });
|
||||
expect(settings.name.nameScaleFactor).toBe(1.3);
|
||||
});
|
||||
|
||||
test("applies cullThreshold override (including 0)", () => {
|
||||
expect(
|
||||
generateRenderSettings({ name: { cullThreshold: 0.03 } }).name
|
||||
.cullThreshold,
|
||||
).toBe(0.03);
|
||||
expect(
|
||||
generateRenderSettings({ name: { cullThreshold: 0 } }).name.cullThreshold,
|
||||
).toBe(0);
|
||||
expect(gen({ name: { cullThreshold: 0.03 } }).name.cullThreshold).toBe(
|
||||
0.03,
|
||||
);
|
||||
expect(gen({ name: { cullThreshold: 0 } }).name.cullThreshold).toBe(0);
|
||||
});
|
||||
|
||||
test("darkNames=true → black fill + player-colored outline + outline RGB 0", () => {
|
||||
const s = generateRenderSettings({ name: { darkNames: true } }).name;
|
||||
const s = gen({ name: { darkNames: true } }).name;
|
||||
expect(s.fillUsePlayerColor).toBe(false);
|
||||
expect(s.outlineUsePlayerColor).toBe(true);
|
||||
expect(s.outlineR).toBe(0);
|
||||
@@ -99,7 +103,7 @@ describe("generateRenderSettings", () => {
|
||||
});
|
||||
|
||||
test("darkNames=false → player-colored fill + white outline + outline RGB 1", () => {
|
||||
const s = generateRenderSettings({ name: { darkNames: false } }).name;
|
||||
const s = gen({ name: { darkNames: false } }).name;
|
||||
expect(s.fillUsePlayerColor).toBe(true);
|
||||
expect(s.outlineUsePlayerColor).toBe(false);
|
||||
expect(s.outlineR).toBe(1);
|
||||
@@ -109,13 +113,13 @@ describe("generateRenderSettings", () => {
|
||||
|
||||
test("only-darkNames override leaves nameScale/cull at defaults", () => {
|
||||
const defaults = createRenderSettings().name;
|
||||
const s = generateRenderSettings({ name: { darkNames: true } }).name;
|
||||
const s = gen({ name: { darkNames: true } }).name;
|
||||
expect(s.nameScaleFactor).toBe(defaults.nameScaleFactor);
|
||||
expect(s.cullThreshold).toBe(defaults.cullThreshold);
|
||||
});
|
||||
|
||||
test("combined overrides all apply together", () => {
|
||||
const s = generateRenderSettings({
|
||||
const s = gen({
|
||||
name: { nameScaleFactor: 0.9, cullThreshold: 0.01, darkNames: true },
|
||||
}).name;
|
||||
expect(s.nameScaleFactor).toBe(0.9);
|
||||
@@ -127,16 +131,16 @@ describe("generateRenderSettings", () => {
|
||||
|
||||
test("settings outside the name slice are untouched by name overrides", () => {
|
||||
const defaults = createRenderSettings();
|
||||
const s = generateRenderSettings({
|
||||
const s = gen({
|
||||
name: { nameScaleFactor: 0.6, darkNames: true },
|
||||
});
|
||||
expect(s.passEnabled).toEqual(defaults.passEnabled);
|
||||
expect(s.dayNight).toEqual(defaults.dayNight);
|
||||
expect(s.lighting).toEqual(defaults.lighting);
|
||||
expect(s.structure).toEqual(defaults.structure);
|
||||
});
|
||||
|
||||
test("classicIcons=true → light shape + dark icon + 0.75 alpha", () => {
|
||||
const s = generateRenderSettings({
|
||||
const s = gen({
|
||||
structure: { classicIcons: true },
|
||||
}).structure;
|
||||
// Shape (circle behind) is mostly player color, lightly darkened.
|
||||
@@ -152,14 +156,14 @@ describe("generateRenderSettings", () => {
|
||||
|
||||
test("classicIcons=false or absent → keeps render-settings.json defaults (fully opaque)", () => {
|
||||
const defaults = createRenderSettings().structure;
|
||||
const off = generateRenderSettings({
|
||||
const off = gen({
|
||||
structure: { classicIcons: false },
|
||||
}).structure;
|
||||
expect(off.borderDarken).toBe(defaults.borderDarken);
|
||||
expect(off.fillDarken).toBe(defaults.fillDarken);
|
||||
expect(off.iconR).toBe(defaults.iconR);
|
||||
expect(off.iconAlpha).toBe(1);
|
||||
const absent = generateRenderSettings({ structure: {} }).structure;
|
||||
const absent = gen({ structure: {} }).structure;
|
||||
expect(absent.borderDarken).toBe(defaults.borderDarken);
|
||||
expect(absent.fillDarken).toBe(defaults.fillDarken);
|
||||
expect(absent.iconR).toBe(defaults.iconR);
|
||||
@@ -167,7 +171,7 @@ describe("generateRenderSettings", () => {
|
||||
});
|
||||
|
||||
test("classicIcons + name overrides compose independently", () => {
|
||||
const s = generateRenderSettings({
|
||||
const s = gen({
|
||||
name: { darkNames: true, nameScaleFactor: 0.9 },
|
||||
structure: { classicIcons: true },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user