generated from nhcarrigan/template
fix: apply custom UI font to full app interface
- Set document.body.style.fontFamily directly (belt-and-suspenders alongside the CSS variable) to ensure the font propagates - Use var(--ui-font-family) in .app-container so the main app area respects the custom font (was hardcoded, blocking inheritance) - Rename 'Custom Font' setting to 'Custom Terminal Font' for clarity
This commit is contained in:
@@ -953,9 +953,9 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Custom Font -->
|
<!-- Custom Terminal Font -->
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<span class="block text-sm text-[var(--text-secondary)] mb-2">Custom Font</span>
|
<span class="block text-sm text-[var(--text-secondary)] mb-2">Custom Terminal Font</span>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
@@ -1331,23 +1331,28 @@ describe("config store", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
document.getElementById("hikari-custom-ui-font")?.remove();
|
document.getElementById("hikari-custom-ui-font")?.remove();
|
||||||
document.documentElement.style.removeProperty("--ui-font-family");
|
document.documentElement.style.removeProperty("--ui-font-family");
|
||||||
|
document.body.style.removeProperty("font-family");
|
||||||
readFileMock.mockReset();
|
readFileMock.mockReset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("removes CSS variable when both path and family are null", async () => {
|
it("removes CSS variable and body font-family when both path and family are null", async () => {
|
||||||
document.documentElement.style.setProperty("--ui-font-family", "'SomeFont', sans-serif");
|
document.documentElement.style.setProperty("--ui-font-family", "'SomeFont', sans-serif");
|
||||||
|
document.body.style.setProperty("font-family", "'SomeFont', sans-serif");
|
||||||
await applyCustomUiFont(null, null);
|
await applyCustomUiFont(null, null);
|
||||||
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe("");
|
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe("");
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe("");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("removes CSS variable when both path and family are empty strings", async () => {
|
it("removes CSS variable and body font-family when both path and family are empty strings", async () => {
|
||||||
document.documentElement.style.setProperty("--ui-font-family", "'SomeFont', sans-serif");
|
document.documentElement.style.setProperty("--ui-font-family", "'SomeFont', sans-serif");
|
||||||
|
document.body.style.setProperty("font-family", "'SomeFont', sans-serif");
|
||||||
await applyCustomUiFont("", "");
|
await applyCustomUiFont("", "");
|
||||||
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe("");
|
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe("");
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe("");
|
||||||
expect(document.getElementById("hikari-custom-ui-font")).toBeNull();
|
expect(document.getElementById("hikari-custom-ui-font")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("injects @import for a CSS stylesheet URL", async () => {
|
it("injects @import for a CSS stylesheet URL and applies font to body", async () => {
|
||||||
await applyCustomUiFont("https://fonts.googleapis.com/css2?family=Inter", "Inter");
|
await applyCustomUiFont("https://fonts.googleapis.com/css2?family=Inter", "Inter");
|
||||||
const style = document.getElementById("hikari-custom-ui-font");
|
const style = document.getElementById("hikari-custom-ui-font");
|
||||||
expect(style).not.toBeNull();
|
expect(style).not.toBeNull();
|
||||||
@@ -1357,9 +1362,10 @@ describe("config store", () => {
|
|||||||
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
||||||
"'Inter', sans-serif"
|
"'Inter', sans-serif"
|
||||||
);
|
);
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe('"Inter", sans-serif');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("injects @font-face for a direct font file URL (.woff2)", async () => {
|
it("injects @font-face for a direct font file URL (.woff2) and applies font to body", async () => {
|
||||||
await applyCustomUiFont("https://example.com/fonts/Inter.woff2", "Inter");
|
await applyCustomUiFont("https://example.com/fonts/Inter.woff2", "Inter");
|
||||||
const style = document.getElementById("hikari-custom-ui-font");
|
const style = document.getElementById("hikari-custom-ui-font");
|
||||||
expect(style).not.toBeNull();
|
expect(style).not.toBeNull();
|
||||||
@@ -1368,15 +1374,19 @@ describe("config store", () => {
|
|||||||
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
||||||
"'Inter', sans-serif"
|
"'Inter', sans-serif"
|
||||||
);
|
);
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe('"Inter", sans-serif');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses HikariCustomUiFont as fallback family for direct font URLs when family is empty", async () => {
|
it("uses HikariCustomUiFont as fallback family and applies it to body", async () => {
|
||||||
await applyCustomUiFont("https://example.com/fonts/Inter.woff2", "");
|
await applyCustomUiFont("https://example.com/fonts/Inter.woff2", "");
|
||||||
const style = document.getElementById("hikari-custom-ui-font");
|
const style = document.getElementById("hikari-custom-ui-font");
|
||||||
expect(style?.textContent).toContain("'HikariCustomUiFont'");
|
expect(style?.textContent).toContain("'HikariCustomUiFont'");
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe(
|
||||||
|
'"HikariCustomUiFont", sans-serif'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("reads local file and embeds as data URL", async () => {
|
it("reads local file and embeds as data URL, applies font to body", async () => {
|
||||||
const fakeData = new Uint8Array([104, 101, 108, 108, 111]);
|
const fakeData = new Uint8Array([104, 101, 108, 108, 111]);
|
||||||
readFileMock.mockResolvedValueOnce(fakeData);
|
readFileMock.mockResolvedValueOnce(fakeData);
|
||||||
|
|
||||||
@@ -1388,13 +1398,17 @@ describe("config store", () => {
|
|||||||
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
||||||
"'Inter', sans-serif"
|
"'Inter', sans-serif"
|
||||||
);
|
);
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe('"Inter", sans-serif');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets CSS variable when only family is provided (no path)", async () => {
|
it("sets CSS variable and body font-family when only family is provided (no path)", async () => {
|
||||||
await applyCustomUiFont("", "SystemUiFont");
|
await applyCustomUiFont("", "SystemUiFont");
|
||||||
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
||||||
"'SystemUiFont', sans-serif"
|
"'SystemUiFont', sans-serif"
|
||||||
);
|
);
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe(
|
||||||
|
'"SystemUiFont", sans-serif'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("replaces a previously injected style element", async () => {
|
it("replaces a previously injected style element", async () => {
|
||||||
@@ -1415,6 +1429,7 @@ describe("config store", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
document.getElementById("hikari-custom-ui-font")?.remove();
|
document.getElementById("hikari-custom-ui-font")?.remove();
|
||||||
document.documentElement.style.removeProperty("--ui-font-family");
|
document.documentElement.style.removeProperty("--ui-font-family");
|
||||||
|
document.body.style.removeProperty("font-family");
|
||||||
readFileMock.mockReset();
|
readFileMock.mockReset();
|
||||||
invokeMock.mockResolvedValue(undefined);
|
invokeMock.mockResolvedValue(undefined);
|
||||||
});
|
});
|
||||||
@@ -1435,13 +1450,16 @@ describe("config store", () => {
|
|||||||
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe(
|
||||||
"'Inter', sans-serif"
|
"'Inter', sans-serif"
|
||||||
);
|
);
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe('"Inter", sans-serif');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("clears UI font when called with nulls", async () => {
|
it("clears UI font when called with nulls", async () => {
|
||||||
document.documentElement.style.setProperty("--ui-font-family", "'SomeFont', sans-serif");
|
document.documentElement.style.setProperty("--ui-font-family", "'SomeFont', sans-serif");
|
||||||
|
document.body.style.setProperty("font-family", "'SomeFont', sans-serif");
|
||||||
await configStore.setCustomUiFont(null, null);
|
await configStore.setCustomUiFont(null, null);
|
||||||
|
|
||||||
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe("");
|
expect(document.documentElement.style.getPropertyValue("--ui-font-family")).toBe("");
|
||||||
|
expect(document.body.style.getPropertyValue("font-family")).toBe("");
|
||||||
expect(invokeMock).toHaveBeenCalledWith(
|
expect(invokeMock).toHaveBeenCalledWith(
|
||||||
"save_config",
|
"save_config",
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
|
|||||||
@@ -404,16 +404,19 @@ export async function applyCustomUiFont(path: string | null, family: string | nu
|
|||||||
|
|
||||||
if (!trimmedPath && !trimmedFamily) {
|
if (!trimmedPath && !trimmedFamily) {
|
||||||
document.documentElement.style.removeProperty(cssVar);
|
document.documentElement.style.removeProperty(cssVar);
|
||||||
|
document.body?.style.removeProperty("font-family");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const effectiveFamily = trimmedFamily || fallbackFamily;
|
||||||
|
|
||||||
if (trimmedPath) {
|
if (trimmedPath) {
|
||||||
await applyFontFromSource(trimmedPath, trimmedFamily || fallbackFamily, styleId);
|
await applyFontFromSource(trimmedPath, effectiveFamily, styleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trimmedFamily) {
|
const fontValue = `'${effectiveFamily}', sans-serif`;
|
||||||
document.documentElement.style.setProperty(cssVar, `'${trimmedFamily}', sans-serif`);
|
document.documentElement.style.setProperty(cssVar, fontValue);
|
||||||
}
|
document.body?.style.setProperty("font-family", fontValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { MIN_FONT_SIZE, MAX_FONT_SIZE, DEFAULT_FONT_SIZE };
|
export { MIN_FONT_SIZE, MAX_FONT_SIZE, DEFAULT_FONT_SIZE };
|
||||||
|
|||||||
@@ -602,13 +602,15 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.app-container {
|
.app-container {
|
||||||
font-family:
|
font-family: var(
|
||||||
|
--ui-font-family,
|
||||||
"Inter",
|
"Inter",
|
||||||
-apple-system,
|
-apple-system,
|
||||||
BlinkMacSystemFont,
|
BlinkMacSystemFont,
|
||||||
"Segoe UI",
|
"Segoe UI",
|
||||||
Roboto,
|
Roboto,
|
||||||
sans-serif;
|
sans-serif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.character-panel {
|
.character-panel {
|
||||||
|
|||||||
Reference in New Issue
Block a user