feat(studio): choose and load Google Fonts in manual design
Quality / quality (ubuntu-latest) (push) Failing after 10m7s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
Clintchiz committed 2026-10-19 22:06:46 +05:30
1 parent 7ef475119a
commit d5244eab15
12 files changed
+140 -12

No files matched your search

+28 -2
View File
@@ -113,7 +113,7 @@ test("manual form saves one atomic revision and rejects locked changes without c
const input = win.document.querySelector('[data-manual-token="shape.control"]') as any;
input.value = "12";
(win.document.querySelector('select[data-manual-token="type.heading"]') as any).value =
MANUAL_FONTS.georgia;
"google:Inter";
(win.document.querySelector('[data-manual-token="type.body-size"]') as any).value = "18";
(win.document.querySelector('[data-manual-token="type.body-leading"]') as any).value = "1.8";
(win.document.querySelector('input[type=text][data-manual-color="primary"]') as any).value =
@@ -122,7 +122,8 @@ test("manual form saves one atomic revision and rejects locked changes without c
await Bun.sleep(10);
expect(session.valid.tokens["shape.control"]!.value).toBe("12px");
expect(session.valid.modes!.light!["color.primary"]!.value).toBe("#6336AD");
expect(session.valid.tokens["type.heading"]!.value).toBe(MANUAL_FONTS.georgia);
expect(session.valid.tokens["type.heading"]!.value).toBe('"Inter", sans-serif');
expect(session.valid.googleFonts).toEqual(["Inter"]);
expect(session.valid.tokens["type.body-size"]!.value).toBe("18px");
expect(session.valid.tokens["type.body-leading"]!.value).toBe("1.8");
expect(session.history).toHaveLength(2);
@@ -173,3 +174,28 @@ test("manual typography controls persist in exported recipes and reject invalid
).toThrow();
}
});
test("Google Fonts survive JSON export, compile first, and reject injected URLs", () => {
const source = CORE_DESIGN_SYSTEMS.soft;
const next = manualDesign(source, {
kind: "googleFont",
name: "type.heading",
value: "Playfair Display",
});
expect(source.googleFonts).toBeUndefined();
const portable = JSON.parse(JSON.stringify(next));
expect(validateDesignSystem(portable)).toEqual([]);
const compiled = compileDesignSystem(portable);
expect(
compiled.css.startsWith(
'@import url("https://fonts.googleapis.com/css2?family=Playfair%20Display:wght@400;700&display=swap");',
),
).toBe(true);
expect(compiled.recipeCss.startsWith("@import")).toBe(true);
expect(compiled.css.match(/@import/g)).toHaveLength(1);
expect(
validateDesignSystem({ ...next, googleFonts: ['Inter\";}@import url(https://evil.test)'] }),
).not.toHaveLength(0);
const changed = manualDesign(next, { kind: "googleFont", name: "type.heading", value: "Lora" });
expect(changed.googleFonts).toEqual(["Lora"]);
});