Skip to content

Commit fc6181c

Browse files
committed
Add Style Dictionary token output
1 parent b7d5ee3 commit fc6181c

18 files changed

Lines changed: 1283 additions & 46 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hebilicious/cssforge": minor
3+
---
4+
5+
Add Style Dictionary-compatible token JSON output with CSS variable metadata, resolved values, reference paths, and CLI support through `--mode style-dictionary` and `--style-dictionary`.

README.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,17 @@ import { cssForge } from "./.cssforge/output.ts";
179179
export { cssForge };
180180
```
181181

182+
5. Use the Style Dictionary-compatible token JSON in token-aware tools:
183+
184+
CSS Forge can also generate token JSON where each leaf keeps the CSS variable reference
185+
as `value`, the fully resolved value as `$resolvedValue`, and provenance metadata under
186+
`attributes`. This is useful for tools such as Musea that scan component styles for
187+
`var(--token)` usage while still needing resolved values for labels and swatches.
188+
189+
```bash
190+
pnpm run cssforge -- --mode style-dictionary --style-dictionary ./.cssforge/tokens.sd.json
191+
```
192+
182193
## Configuration
183194

184195
### Colors
@@ -1027,19 +1038,25 @@ pnpm run cssforge
10271038
# Watch mode
10281039
pnpm run cssforge -- --watch
10291040

1030-
# Custom paths and output
1031-
pnpm run cssforge -- --config ./foo/bar/custom-path.ts --css ./dist/design-tokens.css --ts ./dist/design-tokens.ts --json ./dist/design-tokens.json --mode all
1041+
# Custom paths and output
1042+
pnpm run cssforge -- --config ./foo/bar/custom-path.ts --css ./dist/design-tokens.css --ts ./dist/design-tokens.ts --json ./dist/design-tokens.json --style-dictionary ./dist/design-tokens.sd.json --mode all
1043+
1044+
# Style Dictionary-compatible JSON only
1045+
pnpm run cssforge -- --mode style-dictionary --style-dictionary ./dist/design-tokens.sd.json
10321046
```
10331047

10341048
## Programmatic Usage
10351049

10361050
You can also use CSS Forge programmatically:
10371051

10381052
```typescript
1039-
import { generateCSS } from "jsr:@hebilicious/cssforge";
1053+
import { generateCSS, generateStyleDictionaryJSON } from "jsr:@hebilicious/cssforge";
10401054

10411055
// Generate CSS string
10421056
const css = generateCSS(config);
1057+
1058+
// Generate Style Dictionary-compatible token JSON
1059+
const tokens = generateStyleDictionaryJSON(config);
10431060
```
10441061

10451062
## Agentic usage

packages/cssforge/README.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,17 @@ import { cssForge } from "./.cssforge/output.ts";
179179
export { cssForge };
180180
```
181181

182+
5. Use the Style Dictionary-compatible token JSON in token-aware tools:
183+
184+
CSS Forge can also generate token JSON where each leaf keeps the CSS variable reference
185+
as `value`, the fully resolved value as `$resolvedValue`, and provenance metadata under
186+
`attributes`. This is useful for tools such as Musea that scan component styles for
187+
`var(--token)` usage while still needing resolved values for labels and swatches.
188+
189+
```bash
190+
pnpm run cssforge -- --mode style-dictionary --style-dictionary ./.cssforge/tokens.sd.json
191+
```
192+
182193
## Configuration
183194

184195
### Colors
@@ -1027,19 +1038,25 @@ pnpm run cssforge
10271038
# Watch mode
10281039
pnpm run cssforge -- --watch
10291040

1030-
# Custom paths and output
1031-
pnpm run cssforge -- --config ./foo/bar/custom-path.ts --css ./dist/design-tokens.css --ts ./dist/design-tokens.ts --json ./dist/design-tokens.json --mode all
1041+
# Custom paths and output
1042+
pnpm run cssforge -- --config ./foo/bar/custom-path.ts --css ./dist/design-tokens.css --ts ./dist/design-tokens.ts --json ./dist/design-tokens.json --style-dictionary ./dist/design-tokens.sd.json --mode all
1043+
1044+
# Style Dictionary-compatible JSON only
1045+
pnpm run cssforge -- --mode style-dictionary --style-dictionary ./dist/design-tokens.sd.json
10321046
```
10331047

10341048
## Programmatic Usage
10351049

10361050
You can also use CSS Forge programmatically:
10371051

10381052
```typescript
1039-
import { generateCSS } from "jsr:@hebilicious/cssforge";
1053+
import { generateCSS, generateStyleDictionaryJSON } from "jsr:@hebilicious/cssforge";
10401054

10411055
// Generate CSS string
10421056
const css = generateCSS(config);
1057+
1058+
// Generate Style Dictionary-compatible token JSON
1059+
const tokens = generateStyleDictionaryJSON(config);
10431060
```
10441061

10451062
## Agentic usage

packages/cssforge/src/cli.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ import type { CommandDef } from "citty";
1414
*/
1515
import { defineCommand, runMain } from "citty";
1616
import type { CSSForgeConfig } from "./config.ts";
17-
import { generateCSS, generateJSON, generateTS } from "./generator.ts";
17+
import {
18+
generateCSS,
19+
generateJSON,
20+
generateStyleDictionaryJSON,
21+
generateTS,
22+
} from "./generator.ts";
1823

1924
const writeFileRecursive = (path: string, data: string) =>
2025
fs
@@ -28,11 +33,13 @@ export interface BuildOptions {
2833
/** Path to the configuration file. */
2934
config: string;
3035
/** The output mode. */
31-
mode: "css" | "json" | "ts" | "all";
36+
mode: "css" | "json" | "ts" | "style-dictionary" | "all";
3237
/** Path for the CSS output file. */
3338
cssOutput: string;
3439
/** Path for the JSON output file. */
3540
jsonOutput: string;
41+
/** Path for the Style Dictionary-compatible JSON output file. */
42+
styleDictionaryOutput: string;
3643
/** Path for the TypeScript output file. */
3744
tsOutput: string;
3845
}
@@ -47,12 +54,14 @@ export async function build({
4754
tsOutput,
4855
cssOutput,
4956
jsonOutput,
57+
styleDictionaryOutput,
5058
mode,
5159
}: BuildOptions): Promise<{ success: boolean; error?: unknown }> {
5260
try {
5361
const absoluteconfig = resolve(process.cwd(), config);
5462
const absoluteCssOutput = resolve(process.cwd(), cssOutput);
5563
const absoluteJsonOutput = resolve(process.cwd(), jsonOutput);
64+
const absoluteStyleDictionaryOutput = resolve(process.cwd(), styleDictionaryOutput);
5665
const absoluteTsOutput = resolve(process.cwd(), tsOutput);
5766

5867
// Import config with cache busting
@@ -75,6 +84,16 @@ export async function build({
7584
console.log(`✔ Generated JSON written to ${jsonOutput}`);
7685
}
7786

87+
if (mode === "style-dictionary" || mode === "all") {
88+
await writeFileRecursive(
89+
absoluteStyleDictionaryOutput,
90+
generateStyleDictionaryJSON(userConfig.default as CSSForgeConfig),
91+
);
92+
console.log(
93+
`✔ Generated Style Dictionary JSON written to ${styleDictionaryOutput}`,
94+
);
95+
}
96+
7897
if (mode === "ts" || mode === "all") {
7998
await writeFileRecursive(
8099
absoluteTsOutput,
@@ -147,7 +166,7 @@ const mainCommand = defineCommand({
147166
},
148167
mode: {
149168
type: "string",
150-
description: "Output mode (css, json, ts, all)",
169+
description: "Output mode (css, json, ts, style-dictionary, all)",
151170
alias: "m",
152171
default: "all",
153172
},
@@ -161,6 +180,11 @@ const mainCommand = defineCommand({
161180
description: "Optional path for an output JSON file",
162181
default: "./.cssforge/output.json",
163182
},
183+
"style-dictionary": {
184+
type: "string",
185+
description: "Path for the Style Dictionary-compatible JSON output file",
186+
default: "./.cssforge/tokens.sd.json",
187+
},
164188
css: {
165189
type: "string",
166190
description: "Path for the output CSS file",
@@ -174,13 +198,15 @@ const mainCommand = defineCommand({
174198
},
175199
async run({ args }) {
176200
const { watch: shouldWatch, config, css, json, ts, mode, prefix } = args;
201+
const styleDictionary = args["style-dictionary"];
177202
const realPath = (p: string) => resolve(prefix, p);
178203
const settings = {
179204
mode,
180205
config: realPath(config),
181206
cssOutput: realPath(css),
182207
tsOutput: realPath(ts),
183208
jsonOutput: realPath(json),
209+
styleDictionaryOutput: realPath(styleDictionary),
184210
} as BuildOptions;
185211
if (shouldWatch) {
186212
const cleanup = await watch(settings);

0 commit comments

Comments
 (0)