diff --git a/packages/lint/src/rules/fonts.test.ts b/packages/lint/src/rules/fonts.test.ts index 964cecbf5..8a22f53f3 100644 --- a/packages/lint/src/rules/fonts.test.ts +++ b/packages/lint/src/rules/fonts.test.ts @@ -291,5 +291,39 @@ describe("font rules", () => { const findings = await findByCode(html, "font_family_without_font_face"); expect(findings).toHaveLength(0); }); + + it("does not flag the -apple-system / BlinkMacSystemFont system-ui stack", async () => { + const html = `
+ +
`; + const findings = await findByCode(html, "font_family_without_font_face"); + expect(findings).toHaveLength(0); + }); + + it("does not flag a var() font-family indirection it cannot resolve", async () => { + const html = `
+ +
`; + const findings = await findByCode(html, "font_family_without_font_face"); + expect(findings).toHaveLength(0); + }); + + it("does not flag a var() with a quoted fallback font", async () => { + const html = `
+ +
`; + const findings = await findByCode(html, "font_family_without_font_face"); + expect(findings).toHaveLength(0); + }); + + it("still flags a real undeclared font sitting next to a system stack", async () => { + const html = `
+ +
`; + const findings = await findByCode(html, "font_family_without_font_face"); + expect(findings).toHaveLength(1); + expect(findings[0]!.message).toContain("aeonik"); + expect(findings[0]!.message).not.toContain("apple-system"); + }); }); }); diff --git a/packages/lint/src/rules/fonts.ts b/packages/lint/src/rules/fonts.ts index 5ffdd22d7..611fb4a18 100644 --- a/packages/lint/src/rules/fonts.ts +++ b/packages/lint/src/rules/fonts.ts @@ -56,6 +56,22 @@ function extractFontFaceFamilies(styles: Array<{ content: string }>): Set): string[] { const used: string[] = []; const seen = new Set(); @@ -64,13 +80,8 @@ function extractUsedFontFamilies(styles: Array<{ content: string }>): string[] { const withoutFontFace = stripCssComments(style.content).replace(/@font-face\s*\{[^}]*\}/gi, ""); let match: RegExpExecArray | null; while ((match = propRe.exec(withoutFontFace)) !== null) { - const stack = match[1]!; - for (const part of stack.split(",")) { - const name = part - .trim() - .replace(/^['"]|['"]$/g, "") - .trim() - .toLowerCase(); + for (const part of match[1]!.split(",")) { + const name = normalizeUsedFontName(part); if (name && !GENERIC_FAMILIES.has(name) && !seen.has(name)) { seen.add(name); used.push(name);