diff --git a/package.json b/package.json index 59c38e8..b7a55b6 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/morishxt/windctrl.git" + "url": "git+https://github.com/morishxt/windctrl.git" }, "bugs": { "url": "https://github.com/morishxt/windctrl/issues" @@ -42,8 +42,6 @@ "homepage": "https://github.com/morishxt/windctrl#readme", "scripts": { "test": "vitest", - "test:watch": "vitest --watch", - "test:coverage": "vitest --coverage", "build": "tsc", "dev": "tsc --watch", "format": "prettier --write .", diff --git a/src/index.test.ts b/src/index.test.ts index 84fa89b..027b2c5 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -306,6 +306,19 @@ describe("windctrl", () => { const numberResult = button({ w: 300 }); expect(numberResult.style).toEqual({ width: "300px" }); }); + + it("should resolve style conflicts with last one wins for dynamic styles", () => { + const box = windctrl({ + dynamic: { + w1: () => ({ style: { width: "100px" } }), + w2: () => ({ style: { width: "200px" } }), + }, + }); + + const result = box({ w1: true as any, w2: true as any }); + + expect(result.style).toEqual({ width: "200px" }); + }); }); describe("Scopes", () => { @@ -342,6 +355,23 @@ describe("windctrl", () => { "group-data-[scope=header]/wind-scope:text-sm", ); }); + + it("should prefix every scope class when multiple classes are provided", () => { + const button = windctrl({ + scopes: { + header: "text-sm py-1", + }, + }); + + const result = button({}); + + expect(result.className).toContain( + "group-data-[scope=header]/wind-scope:text-sm", + ); + expect(result.className).toContain( + "group-data-[scope=header]/wind-scope:py-1", + ); + }); }); describe("Priority and Integration", () => { @@ -446,6 +476,34 @@ describe("windctrl", () => { expect(result.className).toContain("text-blue-500"); expect(result.className).not.toContain("text-red-500"); }); + + it("should let Dynamic override Traits when Tailwind classes conflict (via twMerge)", () => { + const button = windctrl({ + traits: { + padded: "p-2", + }, + dynamic: { + p: (val) => (typeof val === "number" ? `p-${val}` : val), + }, + }); + + const result = button({ traits: ["padded"], p: 4 }); + + expect(result.className).toContain("p-4"); + expect(result.className).not.toContain("p-2"); + }); + + it("should let Traits override Base when Tailwind classes conflict (via twMerge)", () => { + const button = windctrl({ + base: "p-1", + traits: { padded: "p-3" }, + }); + + const result = button({ traits: ["padded"] }); + + expect(result.className).toContain("p-3"); + expect(result.className).not.toContain("p-1"); + }); }); describe("Edge cases", () => {