Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/orange-pianos-open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hebilicious/cssforge": patch
---

fix: update reserved keywords
30 changes: 19 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

In the future, CSSforge will try to integrate with popular design tools such as Figma.

## Features

Expand Down Expand Up @@ -871,15 +876,18 @@ const css = generateCSS(config);

Check out our examples:

- [Basic Setup](./examples/basic)
- [] Tailwind
- [Basic Setup](./example/basic)
- [ ] Tailwind

## TODO

- [] Custom Media Queries https://www.w3.org/TR/mediaqueries-5/#at-ruledef-custom-media
- [] Line Height
- [] 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

Expand Down
3 changes: 2 additions & 1 deletion src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const reservedKeyWords = [
"typography",
"typography_fluid",
"theme",
"color",
"gradients",
"palette",
];
/**
* Validates a name to ensure it doesn't contain invalid characters.
Expand Down
49 changes: 43 additions & 6 deletions tests/colors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,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(),
Expand All @@ -26,6 +26,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", () => {
Expand All @@ -45,7 +49,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(
Expand All @@ -61,6 +65,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", () => {
Expand All @@ -76,7 +87,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(),
Expand All @@ -86,6 +97,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", () => {
Expand Down Expand Up @@ -117,7 +132,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(),
Expand All @@ -127,6 +142,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", () => {
Expand All @@ -142,7 +163,7 @@ Deno.test("processColors - handles transparency", () => {
},
},
});
const { css } = processColors(config.colors);
const { css, resolveMap } = processColors(config.colors);
const lines = getLines(css);
assertEquals(
lines[1],
Expand All @@ -152,6 +173,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", () => {
Expand Down Expand Up @@ -197,6 +222,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", () => {
Expand Down Expand Up @@ -241,11 +273,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",
]);
});
48 changes: 45 additions & 3 deletions tests/spacing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)", () => {
Expand All @@ -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);",
Expand All @@ -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", () => {
Expand All @@ -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);",
Expand All @@ -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", () => {
Expand All @@ -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);",
Expand All @@ -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",
]);
});
30 changes: 25 additions & 5 deletions tests/typography.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down Expand Up @@ -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) =>
Expand Down Expand Up @@ -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;");
});
Loading