From 7d85450fd00be40caa6ebfd3d0aff8f23eda2b7f Mon Sep 17 00:00:00 2001 From: Hebilicious Date: Thu, 24 Sep 2026 17:19:53 +0700 Subject: [PATCH] docs(readme): add an output formats section The README described the generated CSS in detail and mentioned the TypeScript output in one Quick Start step, so it was easy to read CSS Forge as a CSS-only tool. It now has an Output Formats section that covers every generated artifact. The section lists the CSS, TypeScript, JSON, and Style Dictionary outputs with their mode, flag, and default path, documents the key / value / variable shape of a token, and shows importing a token value as a color string in TypeScript or reading the same tree from JSON. It also records which tokens carry final values and which keep var(--token), which decides whether a consumer outside the browser can use them. The docs site gains the matching guide/output-formats page, wired into the sidebar, the sync task outputs, and the agent routing index. --- .changeset/output-formats-section.md | 12 +++ README.md | 111 +++++++++++++++++++++++++++ packages/cssforge/README.md | 111 +++++++++++++++++++++++++++ packages/docs/.vitepress/config.ts | 1 + packages/docs/agents.md | 1 + packages/docs/moon.yml | 1 + packages/docs/scripts/sync-readme.ts | 9 +++ 7 files changed, 246 insertions(+) create mode 100644 .changeset/output-formats-section.md diff --git a/.changeset/output-formats-section.md b/.changeset/output-formats-section.md new file mode 100644 index 0000000..49943ca --- /dev/null +++ b/.changeset/output-formats-section.md @@ -0,0 +1,12 @@ +--- +"@hebilicious/cssforge": patch +--- + +Document the generated output formats and how to consume them outside CSS. + +A new README section lists the CSS, TypeScript, JSON, and Style Dictionary outputs with +their modes, flags, and default paths, and documents the `key` / `value` / `variable` shape +of a generated token. It shows importing a token value as a color string in TypeScript, that +palette, spacing, and typography tokens hold final values while theme, gradient, and +primitive tokens keep `var(--token)`, and that the JSON output carries the same tree for +non-TypeScript consumers. The docs site gains the matching `guide/output-formats` page. diff --git a/README.md b/README.md index 54ae78b..a8f3a05 100644 --- a/README.md +++ b/README.md @@ -274,6 +274,117 @@ file; set `write` and import the written file with `layer(cssforge)` to keep the The CLI stays the integration path for everything else: Deno and JSR, Style Dictionary, CI steps, and tools without a bundler. +## Output Formats + +CSS Forge writes more than CSS. One run emits the same tokens as CSS, TypeScript, JSON and +Style Dictionary JSON, so values can be imported directly in TypeScript or read from other +tools. + +| Format | Mode | Default path | Flag | Use it for | +| --- | --- | --- | --- | --- | +| CSS custom properties | `css` | `./.cssforge/output.css` | `--css` | Stylesheets, `var(--token)` | +| TypeScript module | `ts` | `./.cssforge/output.ts` | `--ts` | Importing token values into TS/JS | +| JSON | `json` | `./.cssforge/output.json` | `--json` | Any tool that reads JSON | +| Style Dictionary tokens | `style-dictionary` | `./.cssforge/tokens.sd.json` | `--style-dictionary` | Style Dictionary and compatible tools | + +`--mode all` is the default and writes all four files. Every other mode writes one format, so +run the command once per mode. Style Dictionary has its own section, +[Style Dictionary JSON](#style-dictionary-json). + +### Token objects in TypeScript and JSON + +The TypeScript and JSON outputs hold the same nested tree. Every leaf is one token: + +```json +{ + "palette": { + "coral": { + "100": { + "key": "--palette-coral-100", + "value": "oklch(73.511% 0.16799 40.24666)", + "variable": "--palette-coral-100: oklch(73.511% 0.16799 40.24666);" + } + } + } +} +``` + +| Field | Contains | Use it for | +| --- | --- | --- | +| `key` | The CSS custom property, such as `--palette-coral-100` | Building a `var()` string, or looking a token up by name | +| `value` | The CSS value, such as `oklch(...)`, `0.5rem`, or `clamp(...)` | Passing a color, a length, or a font size to anything that accepts CSS | +| `variable` | The full declaration, such as `--palette-coral-100: oklch(...);` | Injecting a declaration into a style tag or a shadow root | + +A level with one child is collapsed, so `palette: { value: { coral: ... } }` becomes +`cssForge.palette.coral`. Numeric and `@` keys stay strings: +`cssForge.spacing.custom.size["2"]`, `cssForge.typography_fluid["arial@m"]`. + +### Import color strings in TypeScript + +The TypeScript output is a typed module. Put it in your source tree: + +```bash +cssforge --mode ts --ts ./src/design-tokens.ts +``` + +```typescript +import { cssForge } from "./design-tokens.ts"; + +const coral = cssForge.palette.coral["100"].value; // "oklch(73.511% 0.16799 40.24666)" + +// The string is the value: pass it to an SVG fill, a chart series, or a canvas call. +const iconFill = coral; + +// The declaration moves a token into a style tag or a shadow root. +const injected = `:root { ${cssForge.spacing.custom.size["2"].variable} }`; + +export const card = { + backgroundColor: coral, + padding: cssForge.spacing.custom.size["2"].value, // "0.5rem" + fontSize: cssForge.typography_fluid["arial@m"].value, // "clamp(0.875rem, ...)" +}; + +export { iconFill, injected }; +``` + +The module is generated `as const`, so every path is typed and autocompleted, and a typo fails +type checking. Importing it needs `"allowImportingTsExtensions": true` with `"noEmit": true`, +the compiler options the Quick Start documents. + +### Read the tokens from other languages + +The JSON output is the same tree without the `as const` wrapper: + +```bash +cssforge --mode json --json ./src/design-tokens.json +``` + +```javascript +import tokens from "./design-tokens.json" with { type: "json" }; + +const coral = tokens.palette.coral["100"].value; // "oklch(73.511% 0.16799 40.24666)" +``` + +### Values are CSS strings + +Palette, spacing and typography tokens hold final values, because CSS Forge converts colors to +OKLCH and computes fluid scales at build time. Theme, gradient and primitive tokens keep their +`var(--other-token)` reference, because only the CSS cascade knows which value is active: + +| Token | `value` | +| --- | --- | +| Palette, spacing, typography | The final value, such as `oklch(...)`, `0.5rem`, or `clamp(...)` | +| Theme, gradient, primitive | `var(--token)`, resolved by the browser at paint time | + +```typescript +const themed = { + color: cssForge.theme.light.background.primary.value, // "var(--palette-coral-100)" + borderColor: cssForge.palette.coral["100"].value, // "oklch(73.511% 0.16799 40.24666)" +}; +``` + +Both are valid CSS. The first follows the active theme; the second is a snapshot of one theme. + ## Configuration ### Colors diff --git a/packages/cssforge/README.md b/packages/cssforge/README.md index 54ae78b..a8f3a05 100644 --- a/packages/cssforge/README.md +++ b/packages/cssforge/README.md @@ -274,6 +274,117 @@ file; set `write` and import the written file with `layer(cssforge)` to keep the The CLI stays the integration path for everything else: Deno and JSR, Style Dictionary, CI steps, and tools without a bundler. +## Output Formats + +CSS Forge writes more than CSS. One run emits the same tokens as CSS, TypeScript, JSON and +Style Dictionary JSON, so values can be imported directly in TypeScript or read from other +tools. + +| Format | Mode | Default path | Flag | Use it for | +| --- | --- | --- | --- | --- | +| CSS custom properties | `css` | `./.cssforge/output.css` | `--css` | Stylesheets, `var(--token)` | +| TypeScript module | `ts` | `./.cssforge/output.ts` | `--ts` | Importing token values into TS/JS | +| JSON | `json` | `./.cssforge/output.json` | `--json` | Any tool that reads JSON | +| Style Dictionary tokens | `style-dictionary` | `./.cssforge/tokens.sd.json` | `--style-dictionary` | Style Dictionary and compatible tools | + +`--mode all` is the default and writes all four files. Every other mode writes one format, so +run the command once per mode. Style Dictionary has its own section, +[Style Dictionary JSON](#style-dictionary-json). + +### Token objects in TypeScript and JSON + +The TypeScript and JSON outputs hold the same nested tree. Every leaf is one token: + +```json +{ + "palette": { + "coral": { + "100": { + "key": "--palette-coral-100", + "value": "oklch(73.511% 0.16799 40.24666)", + "variable": "--palette-coral-100: oklch(73.511% 0.16799 40.24666);" + } + } + } +} +``` + +| Field | Contains | Use it for | +| --- | --- | --- | +| `key` | The CSS custom property, such as `--palette-coral-100` | Building a `var()` string, or looking a token up by name | +| `value` | The CSS value, such as `oklch(...)`, `0.5rem`, or `clamp(...)` | Passing a color, a length, or a font size to anything that accepts CSS | +| `variable` | The full declaration, such as `--palette-coral-100: oklch(...);` | Injecting a declaration into a style tag or a shadow root | + +A level with one child is collapsed, so `palette: { value: { coral: ... } }` becomes +`cssForge.palette.coral`. Numeric and `@` keys stay strings: +`cssForge.spacing.custom.size["2"]`, `cssForge.typography_fluid["arial@m"]`. + +### Import color strings in TypeScript + +The TypeScript output is a typed module. Put it in your source tree: + +```bash +cssforge --mode ts --ts ./src/design-tokens.ts +``` + +```typescript +import { cssForge } from "./design-tokens.ts"; + +const coral = cssForge.palette.coral["100"].value; // "oklch(73.511% 0.16799 40.24666)" + +// The string is the value: pass it to an SVG fill, a chart series, or a canvas call. +const iconFill = coral; + +// The declaration moves a token into a style tag or a shadow root. +const injected = `:root { ${cssForge.spacing.custom.size["2"].variable} }`; + +export const card = { + backgroundColor: coral, + padding: cssForge.spacing.custom.size["2"].value, // "0.5rem" + fontSize: cssForge.typography_fluid["arial@m"].value, // "clamp(0.875rem, ...)" +}; + +export { iconFill, injected }; +``` + +The module is generated `as const`, so every path is typed and autocompleted, and a typo fails +type checking. Importing it needs `"allowImportingTsExtensions": true` with `"noEmit": true`, +the compiler options the Quick Start documents. + +### Read the tokens from other languages + +The JSON output is the same tree without the `as const` wrapper: + +```bash +cssforge --mode json --json ./src/design-tokens.json +``` + +```javascript +import tokens from "./design-tokens.json" with { type: "json" }; + +const coral = tokens.palette.coral["100"].value; // "oklch(73.511% 0.16799 40.24666)" +``` + +### Values are CSS strings + +Palette, spacing and typography tokens hold final values, because CSS Forge converts colors to +OKLCH and computes fluid scales at build time. Theme, gradient and primitive tokens keep their +`var(--other-token)` reference, because only the CSS cascade knows which value is active: + +| Token | `value` | +| --- | --- | +| Palette, spacing, typography | The final value, such as `oklch(...)`, `0.5rem`, or `clamp(...)` | +| Theme, gradient, primitive | `var(--token)`, resolved by the browser at paint time | + +```typescript +const themed = { + color: cssForge.theme.light.background.primary.value, // "var(--palette-coral-100)" + borderColor: cssForge.palette.coral["100"].value, // "oklch(73.511% 0.16799 40.24666)" +}; +``` + +Both are valid CSS. The first follows the active theme; the second is a snapshot of one theme. + ## Configuration ### Colors diff --git a/packages/docs/.vitepress/config.ts b/packages/docs/.vitepress/config.ts index 4b4b113..abc1bc3 100644 --- a/packages/docs/.vitepress/config.ts +++ b/packages/docs/.vitepress/config.ts @@ -55,6 +55,7 @@ export default defineConfig({ { text: "Bundler plugin", link: "/guide/bundlers" }, { text: "Configuration", link: "/guide/configuration" }, { text: "CLI and API", link: "/guide/usage" }, + { text: "Output formats", link: "/guide/output-formats" }, { text: "Style Dictionary JSON", link: "/guide/style-dictionary", diff --git a/packages/docs/agents.md b/packages/docs/agents.md index 269d990..5f1e273 100644 --- a/packages/docs/agents.md +++ b/packages/docs/agents.md @@ -16,6 +16,7 @@ The compact machine-readable route index is available at [`/llms.txt`](/llms.txt - **Understand references and config structure:** [Configuration](/guide/configuration) - **Configure a token family:** [Colors](/tokens/colors), [Spacing](/tokens/spacing), [Typography](/tokens/typography), or [Primitives](/tokens/primitives) - **Run the CLI or call the API:** [Using CSS Forge](/guide/usage) +- **Read or import the generated CSS, TS, or JSON:** [Output formats](/guide/output-formats) - **Integrate with a framework:** [Examples](/guide/examples) ## Repository sources of truth diff --git a/packages/docs/moon.yml b/packages/docs/moon.yml index 1405dba..cd3dfe8 100644 --- a/packages/docs/moon.yml +++ b/packages/docs/moon.yml @@ -19,6 +19,7 @@ tasks: - "guide/bundlers.md" - "guide/configuration.md" - "guide/usage.md" + - "guide/output-formats.md" - "guide/style-dictionary.md" - "guide/examples.md" - "tokens/colors.md" diff --git a/packages/docs/scripts/sync-readme.ts b/packages/docs/scripts/sync-readme.ts index 86546cf..da07d48 100644 --- a/packages/docs/scripts/sync-readme.ts +++ b/packages/docs/scripts/sync-readme.ts @@ -167,6 +167,15 @@ const pages: GeneratedPage[] = [ renderSection(requireSection(readmeSections.sections, "Best Practices")), ].join("\n\n"), }, + { + path: "guide/output-formats.md", + title: "Output formats", + description: + "Use the generated CSS, TypeScript, JSON, and Style Dictionary outputs.", + content: renderTopLevelPage( + requireSection(readmeSections.sections, "Output Formats"), + ), + }, { path: "guide/style-dictionary.md", title: "Style Dictionary JSON",