feat(studio): choose and load Google Fonts in manual design
This commit is contained in:
1 parent
7ef475119a
commit
d5244eab15
12 files changed
+140
-12
No files matched your search
@@ -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"]);
|
||||
});
|
||||
Reference in new issue
Block a user