From 5f294dd858841cda16f331015b2c185242d8dd2a Mon Sep 17 00:00:00 2001 From: Hebilicious Date: Tue, 23 Sep 2025 22:16:12 +0700 Subject: [PATCH 1/6] fix: update reserved keywords --- .changeset/orange-pianos-open.md | 5 ++++ src/helpers.ts | 3 +- tests/colors.test.ts | 51 ++++++++++++++++++++++++++++---- tests/spacing.test.ts | 48 ++++++++++++++++++++++++++++-- tests/typography.test.ts | 30 +++++++++++++++---- 5 files changed, 122 insertions(+), 15 deletions(-) create mode 100644 .changeset/orange-pianos-open.md diff --git a/.changeset/orange-pianos-open.md b/.changeset/orange-pianos-open.md new file mode 100644 index 0000000..732a58f --- /dev/null +++ b/.changeset/orange-pianos-open.md @@ -0,0 +1,5 @@ +--- +"@hebilicious/cssforge": patch +--- + +fix: update reserved keywords diff --git a/src/helpers.ts b/src/helpers.ts index 6174a4d..2a8e7c7 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -4,7 +4,8 @@ const reservedKeyWords = [ "typography", "typography_fluid", "theme", - "color", + "gradients", + "palette", ]; /** * Validates a name to ensure it doesn't contain invalid characters. diff --git a/tests/colors.test.ts b/tests/colors.test.ts index 4d430af..e7c3309 100644 --- a/tests/colors.test.ts +++ b/tests/colors.test.ts @@ -1,6 +1,8 @@ import { assertEquals } from "@std/assert"; import { defineConfig, processColors } from "../src/mod.ts"; import { getLines } from "./helpers.ts"; +import { resolve } from "node:path"; +import { assert } from "node:console"; Deno.test("processColors - converts hex to oklch", () => { const config = defineConfig({ @@ -16,7 +18,7 @@ Deno.test("processColors - converts hex to oklch", () => { }, }); - const { css } = processColors(config.colors); + const { css, resolveMap } = processColors(config.colors); const lines = getLines(css); assertEquals( lines[1].trim(), @@ -26,6 +28,10 @@ Deno.test("processColors - converts hex to oklch", () => { lines[2].trim(), "--palette-coral-200: oklch(69.622% 0.19552 32.32143);", ); + assertEquals(Array.from(resolveMap.keys()), [ + "palette.value.coral.100", + "palette.value.coral.200", + ]); }); Deno.test("processColors - handles different color formats", () => { @@ -45,7 +51,7 @@ Deno.test("processColors - handles different color formats", () => { }, } as const, ); - const { css } = processColors(config.colors); + const { css, resolveMap } = processColors(config.colors); const lines = getLines(css); assertEquals( @@ -61,6 +67,13 @@ Deno.test("processColors - handles different color formats", () => { lines[4].trim(), "--palette-brand-default: oklch(62.796% 0.25768 29.23388);", ); + + assertEquals(Array.from(resolveMap.keys()), [ + "palette.value.brand.200", + "palette.value.brand.300", + "palette.value.brand.400", + "palette.value.brand.default", + ]); }); Deno.test("processColors - handles string values", () => { @@ -76,7 +89,7 @@ Deno.test("processColors - handles string values", () => { }, }, }); - const { css } = processColors(config.colors); + const { css, resolveMap } = processColors(config.colors); const lines = getLines(css); assertEquals( lines[1].trim(), @@ -86,6 +99,10 @@ Deno.test("processColors - handles string values", () => { lines[2].trim(), "--palette-simple-black: oklch(0% 0 0);", ); + assertEquals(Array.from(resolveMap.keys()), [ + "palette.value.simple.white", + "palette.value.simple.black", + ]); }); Deno.test("processColors - handles themes", () => { @@ -117,7 +134,7 @@ Deno.test("processColors - handles themes", () => { }, }, }); - const { css } = processColors(config.colors); + const { css, resolveMap } = processColors(config.colors); const lines = getLines(css); assertEquals( lines[5].trim(), @@ -127,6 +144,12 @@ Deno.test("processColors - handles themes", () => { lines[6].trim(), "--theme-light-background-secondary: var(--palette-simple-black);", ); + assertEquals(Array.from(resolveMap.keys()), [ + "palette.value.simple.white", + "palette.value.simple.black", + "theme.value.light.background.primary", + "theme.value.light.background.secondary", + ]); }); Deno.test("processColors - handles transparency", () => { @@ -142,7 +165,7 @@ Deno.test("processColors - handles transparency", () => { }, }, }); - const { css } = processColors(config.colors); + const { css, resolveMap } = processColors(config.colors); const lines = getLines(css); assertEquals( lines[1], @@ -152,6 +175,10 @@ Deno.test("processColors - handles transparency", () => { lines[2], "--palette-alpha-softGray2: oklch(14.48% 0 0 / 24%);", ); + assertEquals(Array.from(resolveMap.keys()), [ + "palette.value.alpha.softGray1", + "palette.value.alpha.softGray2", + ]); }); Deno.test("processColors - generates gradient with color variables", () => { @@ -197,6 +224,13 @@ Deno.test("processColors - generates gradient with color variables", () => { ].join("\n"); assertEquals(lines.at(-1), expected); + assertEquals(Array.from(result.resolveMap.keys()), [ + "palette.value.coral.50", + "palette.value.coral.90", + "palette.value.coral.100", + "palette.value.indigo.100", + "gradients.value.orangeGradient.primary", + ]); }); Deno.test("processColors - handles themes referencing gradients", () => { @@ -241,11 +275,16 @@ Deno.test("processColors - handles themes referencing gradients", () => { }, }); - const { css } = processColors(config.colors); + const { css, resolveMap } = processColors(config.colors); const lines = getLines(css); const lastLine = lines.pop(); assertEquals( lastLine, "--theme-light-background-primary: var(--gradients-orangeGradient-primary);", ); + assertEquals(Array.from(resolveMap.keys()), [ + "palette.value.coral.50", + "gradients.value.orangeGradient.primary", + "theme.value.light.background.primary", + ]); }); diff --git a/tests/spacing.test.ts b/tests/spacing.test.ts index 64cd9c5..ccad980 100644 --- a/tests/spacing.test.ts +++ b/tests/spacing.test.ts @@ -21,6 +21,13 @@ Deno.test("processSpacing - generates correct spacing scale", () => { "--spacing-size-s: 1rem;", ].join("\n"); assertEquals(result.css, expected); + + assertEquals(Array.from(result.resolveMap.keys()), [ + "spacing.custom.size.value.1", + "spacing.custom.size.value.2", + "spacing.custom.size.value.3", + "spacing.custom.size.value.s", + ]); }); // Test with string keys @@ -49,6 +56,13 @@ Deno.test("processSpacing - handles settings", () => { ].join("\n"); assertEquals(result.css, expected); + + assertEquals(Array.from(result.resolveMap.keys()), [ + "spacing.custom.size.value.1", + "spacing.custom.size.value.2", + "spacing.custom.scale.value.md", + "spacing.custom.scale.value.lg", + ]); }); Deno.test("processSpacing - generates fluid spacing (prefix)", () => { @@ -71,7 +85,7 @@ Deno.test("processSpacing - generates fluid spacing (prefix)", () => { }, }); - const { css } = processSpacing(config.spacing); + const { css, resolveMap } = processSpacing(config.spacing); const expected = [ "--spacing_fluid-base-foo-xs: clamp(0rem, 0rem + 0vw, 0rem);", "--spacing_fluid-base-foo-s: clamp(0.25rem, -0.1667rem + 2.0833vw, 1.5rem);", @@ -83,6 +97,17 @@ Deno.test("processSpacing - generates fluid spacing (prefix)", () => { "--spacing_fluid-base-foo-m-l: clamp(0.25rem, -0.6667rem + 4.5833vw, 3rem);", ].join("\n"); assertEquals(css, expected); + + assertEquals(Array.from(resolveMap.keys()), [ + "spacing_fluid.base@xs", + "spacing_fluid.base@s", + "spacing_fluid.base@m", + "spacing_fluid.base@l", + "spacing_fluid.base@xs-l", + "spacing_fluid.base@xs-s", + "spacing_fluid.base@s-m", + "spacing_fluid.base@m-l", + ]); }); Deno.test("processSpacing - fluid without prefix falls back to scale name", () => { @@ -102,7 +127,7 @@ Deno.test("processSpacing - fluid without prefix falls back to scale name", () = }, }, }); - const { css } = processSpacing(config.spacing); + const { css, resolveMap } = processSpacing(config.spacing); const expected = [ "--spacing_fluid-rhythm-xs: clamp(0rem, 0rem + 0vw, 0rem);", "--spacing_fluid-rhythm-s: clamp(0.125rem, -0.25rem + 1.875vw, 1.25rem);", @@ -111,6 +136,14 @@ Deno.test("processSpacing - fluid without prefix falls back to scale name", () = "--spacing_fluid-rhythm-s-m: clamp(0.125rem, -0.25rem + 1.875vw, 1.25rem);", ].join("\n"); assertEquals(css, expected); + + assertEquals(Array.from(resolveMap.keys()), [ + "spacing_fluid.rhythm@xs", + "spacing_fluid.rhythm@s", + "spacing_fluid.rhythm@m", + "spacing_fluid.rhythm@xs-s", + "spacing_fluid.rhythm@s-m", + ]); }); Deno.test("processSpacing - combines fluid and custom spacing", () => { @@ -137,7 +170,7 @@ Deno.test("processSpacing - combines fluid and custom spacing", () => { }, }, }); - const { css } = processSpacing(config.spacing!); + const { css, resolveMap } = processSpacing(config.spacing!); const expected = [ "--spacing_fluid-base-flux-xs: clamp(0rem, 0rem + 0vw, 0rem);", "--spacing_fluid-base-flux-s: clamp(0.25rem, -0.1667rem + 2.0833vw, 1.5rem);", @@ -148,4 +181,13 @@ Deno.test("processSpacing - combines fluid and custom spacing", () => { "--spacing-gap-2: 8px;", ].join("\n"); assertEquals(css, expected); + assertEquals(Array.from(resolveMap.keys()), [ + "spacing_fluid.base@xs", + "spacing_fluid.base@s", + "spacing_fluid.base@m", + "spacing_fluid.base@xs-s", + "spacing_fluid.base@s-m", + "spacing.custom.gap.value.1", + "spacing.custom.gap.value.2", + ]); }); diff --git a/tests/typography.test.ts b/tests/typography.test.ts index 48ac2b8..04a19b0 100644 --- a/tests/typography.test.ts +++ b/tests/typography.test.ts @@ -44,6 +44,11 @@ Deno.test("processTypography - generates correct CSS variables", () => { "--typography_fluid-arial-xl: clamp(1.3672rem, 1.3111rem + 0.2803vw, 1.5625rem);", ); + assertEquals( + Array.from(result.resolveMap.keys()), + expectedSizes.map((size) => `typography_fluid.arial@${size}`), + ); + // Test that we have all the expected size variables expectedSizes.forEach((size) => { const hasSize = lines.some((line) => @@ -107,10 +112,15 @@ Deno.test("typography - can handle custom labels and prefixes", () => { // Test a specific value for precision const xlLine = lines.find((line) => line.includes("--typography_fluid-arial-text-xl:")); assertEquals( - xlLine?.trim(), + xlLine, "--typography_fluid-arial-text-xl: clamp(1.3672rem, 1.3111rem + 0.2803vw, 1.5625rem);", ); + assertEquals( + Array.from(result.resolveMap.keys()), + expectedSizes.toReversed().map((size) => `typography_fluid.arial@${size}`), + ); + // Test that we have all the expected size variables expectedSizes.forEach((size) => { const hasSize = lines.some((line) => @@ -149,12 +159,22 @@ Deno.test("processTypography - can process weights", () => { const lines = getLines(result.css); assertEquals(lines.length, positiveSteps + negativeSteps + 1 + 1); // 1 for base size and 1 for weight + assertEquals( + Array.from(result.resolveMap.keys()), + [ + "typography_fluid.arial@2xl", + "typography_fluid.arial@xl", + "typography_fluid.arial@l", + "typography_fluid.arial@m", + "typography_fluid.arial@s", + "typography_fluid.arial@xs", + "typography_fluid.arial@2xs", + "typography.weight.arial.value.regular", + ], + ); // Test that we have the weight variable const xlLine = lines.find((line) => line.includes("--typography-weight-arial-regular:") ); - assertEquals( - xlLine?.trim(), - "--typography-weight-arial-regular: 500;", - ); + assertEquals(xlLine, "--typography-weight-arial-regular: 500;"); }); From d2bd2f9c557e6e8c58004cbebc5038f1fbb0f54e Mon Sep 17 00:00:00 2001 From: Hebilicious Date: Tue, 23 Sep 2025 22:21:00 +0700 Subject: [PATCH 2/6] chore: useless imports --- tests/colors.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/colors.test.ts b/tests/colors.test.ts index e7c3309..14688a7 100644 --- a/tests/colors.test.ts +++ b/tests/colors.test.ts @@ -1,8 +1,6 @@ import { assertEquals } from "@std/assert"; import { defineConfig, processColors } from "../src/mod.ts"; import { getLines } from "./helpers.ts"; -import { resolve } from "node:path"; -import { assert } from "node:console"; Deno.test("processColors - converts hex to oklch", () => { const config = defineConfig({ From 297e29df59b240b392a63aa0a7c16220cb43c63f Mon Sep 17 00:00:00 2001 From: Hebilicious Date: Tue, 23 Sep 2025 22:22:25 +0700 Subject: [PATCH 3/6] chore: fix readme --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 33071d2..e6b40fb 100644 --- a/README.md +++ b/README.md @@ -871,13 +871,15 @@ const css = generateCSS(config); Check out our examples: -- [Basic Setup](./examples/basic) +- [Basic Setup](./example/basic) - [] Tailwind ## TODO -- [] Custom Media Queries https://www.w3.org/TR/mediaqueries-5/#at-ruledef-custom-media -- [] Line Height +- [] Module: Custom Media Queries https://www.w3.org/TR/mediaqueries-5/#at-ruledef-custom-media +- [] Typography : Line Height +- [] Stable schema spec +- [] VSCode Extension - [] Bundlers Plugin (Vite, Rollup, Webpack ...) - [] Nuxt Module From c9740c842d032d9e1ae8a4f32a74bdd3674503d3 Mon Sep 17 00:00:00 2001 From: Hebilicious Date: Tue, 23 Sep 2025 22:29:16 +0700 Subject: [PATCH 4/6] chore: readme --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e6b40fb..4bedbc8 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,16 @@ ## Why CSS forge is library that leverages modern CSS features and conventions to help you -generate CSS custom properties (css variables). At the core of CSSforge is the schema : A -serializable configuration object. CSSforge has 0 runtime and generate at build time raw -CSS, Typescript or JSON. This intentionally keeps things simple and flexible, and allows -you to integrate it with any framework or CSS workflow. CSSforge will try to integrate -with design tools such as Figma, cooors etc in the future. +generate CSS custom properties (css variables). + +At the core of CSSforge is the schema : A serializable configuration object. + +CSSforge has 0 runtime and generate at build time raw CSS, Typescript or JSON. + +This intentionally keeps things simple and flexible, and allows you to integrate it with +any framework or CSS workflow. + +CSSforge will try to integratewith design tools such as Figma, cooors etc in the future. ## Features @@ -876,7 +881,8 @@ Check out our examples: ## TODO -- [] Module: Custom Media Queries https://www.w3.org/TR/mediaqueries-5/#at-ruledef-custom-media +- [] Module: Custom Media Queries + https://www.w3.org/TR/mediaqueries-5/#at-ruledef-custom-media - [] Typography : Line Height - [] Stable schema spec - [] VSCode Extension From 7be222d0952e198922564d66153f23370fab7ce9 Mon Sep 17 00:00:00 2001 From: Hebilicious Date: Tue, 23 Sep 2025 22:30:32 +0700 Subject: [PATCH 5/6] chore: fmt --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bedbc8..181a037 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ CSSforge has 0 runtime and generate at build time raw CSS, Typescript or JSON. This intentionally keeps things simple and flexible, and allows you to integrate it with any framework or CSS workflow. -CSSforge will try to integratewith design tools such as Figma, cooors etc in the future. +In the future, CSSforge will try to integrate with popular design tools such as Figma. ## Features From a5ac043454025e4e3ccd67f5491c3a339efaa83f Mon Sep 17 00:00:00 2001 From: Hebilicious Date: Tue, 23 Sep 2025 22:31:26 +0700 Subject: [PATCH 6/6] chore: fmt --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 181a037..07e3e35 100644 --- a/README.md +++ b/README.md @@ -877,17 +877,17 @@ const css = generateCSS(config); Check out our examples: - [Basic Setup](./example/basic) -- [] Tailwind +- [ ] Tailwind ## TODO -- [] Module: Custom Media Queries - https://www.w3.org/TR/mediaqueries-5/#at-ruledef-custom-media -- [] Typography : Line Height -- [] Stable schema spec -- [] VSCode Extension -- [] Bundlers Plugin (Vite, Rollup, Webpack ...) -- [] Nuxt Module +- [ ] Module: + [Custom Media Queries](https://www.w3.org/TR/mediaqueries-5/#at-ruledef-custom-media) +- [ ] Typography : Line Height +- [ ] Stable schema spec +- [ ] VSCode Extension +- [ ] Bundlers Plugin (Vite, Rollup, Webpack ...) +- [ ] Nuxt Module ## License