From 484f3300a70d75d44663b2a10c64be4cd9da097d Mon Sep 17 00:00:00 2001 From: Harsh Singh Date: Sat, 3 Oct 2026 16:44:15 +0530 Subject: [PATCH] Add six copy and paste sections in plain HTML and CSS --- src/__tests__/componentKit.test.ts | 170 +++++++++++++++++++ src/lib/componentKit.ts | 261 +++++++++++++++++++++++++++++ 2 files changed, 431 insertions(+) create mode 100644 src/__tests__/componentKit.test.ts create mode 100644 src/lib/componentKit.ts diff --git a/src/__tests__/componentKit.test.ts b/src/__tests__/componentKit.test.ts new file mode 100644 index 0000000..d61adc0 --- /dev/null +++ b/src/__tests__/componentKit.test.ts @@ -0,0 +1,170 @@ +import { describe, it, expect } from "vitest"; +import { KIT, KIT_BASE, KIT_TOKENS, kitComponent, kitPage, kitStylesheet } from "@/lib/componentKit"; + +/** + * The kits people compare us to (VengeanceUI, Magic UI, Aceternity) all ship React plus a + * motion library; the ones that serve everyone else (HyperUI, daisyUI, Preline) ship + * markup with no behaviour. These have to paste into anything and still work, so the + * tests are mostly about what they must NOT contain. + */ + +describe("the set", () => { + it("ships six sections, each doing a job the others do not", () => { + expect(KIT).toHaveLength(6); + expect(KIT.map((c) => c.id)).toEqual(["hero", "features", "pricing", "faq", "signup", "footer"]); + }); + + it("gives each one a name and a line explaining what it is for", () => { + for (const c of KIT) { + expect(c.name.length, c.id).toBeGreaterThan(2); + expect(c.description.length, c.id).toBeGreaterThan(30); + expect(c.html.trim().length, c.id).toBeGreaterThan(50); + expect(c.css.trim().length, c.id).toBeGreaterThan(30); + } + }); + + it("looks up a section, and misses cleanly", () => { + expect(kitComponent("pricing")?.name).toBe("Pricing"); + expect(kitComponent("nothing")).toBeUndefined(); + }); +}); + +describe("it needs nothing installed", () => { + it("carries no framework, no build step and no script", () => { + for (const c of KIT) { + expect(c.html, `${c.id} uses React`).not.toMatch(/className|onClick=|\{\{|\bjsx\b/); + expect(c.html, `${c.id} ships script`).not.toMatch(/ m[1].split(/\s+/)); + for (const name of classes) { + expect(name.startsWith("sck"), `${c.id} carries a class from somebody else's framework: ${name}`).toBe(true); + } + } + }); + + it("fetches nothing from anywhere, so it works offline and leaks no visitor", () => { + for (const c of KIT) { + expect(c.html, `${c.id} loads something remote`).not.toMatch(/<(?:img|iframe|link|source)\b|@import|url\(https?:/i); + // The signup form posts where its owner tells it to; that is the one outbound thing. + const links = [...c.html.matchAll(/https?:\/\/[^"' ]+/g)].map((m) => m[0]); + for (const link of links) expect(c.id, `${c.id} links out to ${link}`).toBe("signup"); + } + }); + + it("styles itself and nothing else on the page it is pasted into", () => { + for (const c of KIT) { + const selectors = c.css + .replace(/\/\*[\s\S]*?\*\//g, "") + .split("}") + .map((block) => block.split("{")[0].trim()) + .filter(Boolean) + .flatMap((group) => group.split(",")) + .map((one) => one.trim()) + .filter((one) => one && !one.startsWith("@")); + expect(selectors.length, `${c.id} styles nothing`).toBeGreaterThan(0); + for (const selector of selectors) { + // Element selectors are fine inside the block; what matters is that the block + // is the root of every rule, so nothing outside it can be touched. + expect(selector.startsWith(".sck"), `${c.id} restyles the host page with "${selector}"`).toBe(true); + } + } + }); + + it("reads the host page's colours where it has them, with its own as the fallback", () => { + expect(KIT_TOKENS).toContain("--sck-accent"); + for (const c of KIT) { + const colours = [...c.css.matchAll(/(?:color|background)[^;:]*:\s*([^;]+);/g)].map((m) => m[1]); + for (const value of colours) { + const literal = /#[0-9a-f]{3,8}|\brgb|\bhsl/i.test(value) && !value.includes("var("); + expect(literal, `${c.id} hardcodes ${value.trim()}`).toBe(false); + } + } + }); +}); + +describe("the bar from #418", () => { + it("carries copy that could only belong to this business", () => { + const text = KIT.map((c) => c.html.replace(/<[^>]+>/g, " ")).join(" ").toLowerCase(); + for (const banned of ["lorem", "ipsum", "your text here", "placeholder", "coming soon", "awesome", "lands here"]) { + expect(text, `found ${banned}`).not.toContain(banned); + } + // Specifics are what separate written copy from filler. + expect(text).toContain("340 independent cafes"); + expect(text).toContain("09182736"); + }); + + it("wears none of the chrome that makes a page look mass produced", () => { + for (const c of KIT) { + expect(c.css, `${c.id} has a tracked-out caps label`).not.toMatch(/text-transform:\s*uppercase[^}]*letter-spacing/); + expect(c.html, `${c.id} glues an arrow to a button`).not.toMatch(/→|→|→/); + expect(c.html, `${c.id} numbers things that are not a sequence`).not.toMatch(/>\s*0[1-9]\s* { + expect(KIT_BASE).toContain(":focus-visible"); + expect(KIT_BASE).toMatch(/outline:\s*3px/); + }); + + it("labels the one input it has, and posts it over https", () => { + const signup = kitComponent("signup")!; + expect(signup.html).toMatch(/