Skip to content

Commit ef43111

Browse files
author
Olga Grabek
committed
Style Dictionary example
1 parent 831e04a commit ef43111

6 files changed

Lines changed: 2180 additions & 0 deletions

File tree

style-dictionary/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build/
2+
json/
3+
node_modules/

style-dictionary/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Style Dictionary example
2+
3+
This repository contains an example script that uses [Style Dictionary](https://amzn.github.io/style-dictionary/) to manage design tokens. The script pulls a token set generated by syncing a Figma file with zeroheight. For more details on how to sync Figma files with zeroheight, see [this guide](https://zeroheight.com/help/article/documenting-figma-color-variables).
4+
5+
## Token Set Overview
6+
7+
The token set used in this example contains two collections, each with two modes:
8+
9+
1. **Primitives**
10+
- Modern Theme
11+
- Brutal Theme
12+
2. **Tokens**
13+
- Light Mode
14+
- Dark Mode
15+
16+
## Prerequisites
17+
18+
- Node.js >= 20
19+
20+
## Getting Started
21+
22+
To get started, follow these steps:
23+
24+
1. **Install Dependencies**
25+
Run the following command in your CLI to install the required dependencies:
26+
27+
```sh
28+
npm install
29+
```
30+
31+
2. **Build the Tokens**
32+
Once dependencies are installed, you can build the tokens by running:
33+
34+
```sh
35+
npm run build
36+
```
37+
38+
## How It Works
39+
40+
The build process is driven by a custom script (index.js) that performs the following steps:
41+
42+
1. **Fetching Style Dictionary Links**
43+
The script first fetches links from the token set’s Style Dictionary URL. Each link corresponds to a JSON file that is saved locally.
44+
45+
```js
46+
async function fetchLinks() {
47+
// Logic to fetch links
48+
}
49+
50+
async function saveFiles(links) {
51+
// Logic to save JSON files locally
52+
}
53+
```
54+
55+
2. **Generating Style Dictionary Configuration**
56+
Next, the script dynamically generates a Style Dictionary configuration for each mode in the Tokens collection.
57+
58+
```js
59+
function getStyleDictionaryConfig(mode1, mode2) {
60+
// Logic to generate Style Dictionary config
61+
}
62+
```
63+
64+
3. **Building for Multiple Platforms**
65+
Finally, the script runs the build process for two platforms: `web` and `ios`.
66+
67+
## Additional Notes
68+
69+
Ensure that your Figma file is properly synced with zeroheight to avoid issues with token generation.
70+
You can customize the build process by modifying the index.js script or the generated Style Dictionary configurations.

style-dictionary/index.js

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import { promises as fs } from "fs";
2+
import fetch from "node-fetch";
3+
import path from "path";
4+
import { fileURLToPath } from "url";
5+
import StyleDictionary from "style-dictionary";
6+
import { extractCollectionAndMode, extractCollectionModes } from "./utils.js";
7+
8+
const __filename = fileURLToPath(import.meta.url);
9+
const __dirname = path.dirname(__filename);
10+
11+
const styleDictionaryURL =
12+
"https://zeroheight.zeroheight.com/api/token_management/token_set/7770/style_dictionary_links";
13+
14+
/**
15+
* Fetches links for each collection and mode
16+
*
17+
* @returns {string[]} list of URLs for each collection and mode
18+
*/
19+
async function fetchLinks() {
20+
try {
21+
/** styleDictionaryURL value is generated per a token set at zeroheight.
22+
*
23+
* If you generate a private link, you need to generate access token and add additional headers to the request
24+
* X-API-CLIENT
25+
* X-API-KEY
26+
*
27+
* Learn more: https://zeroheight.com/help/article/documenting-figma-color-variables/
28+
*/
29+
const response = await fetch(styleDictionaryURL);
30+
const textResponse = await response.text();
31+
const links = textResponse.split("\n");
32+
33+
return links;
34+
} catch (error) {
35+
console.error("❗️Error fetching links:", error);
36+
}
37+
}
38+
39+
/**
40+
* Iterates links, fetches Style Dictionary JSON files and saves them
41+
*
42+
* @param {string[]} links
43+
*/
44+
async function saveFiles(links) {
45+
try {
46+
for (const link of links) {
47+
const response = await fetch(link);
48+
49+
if (!response.ok) {
50+
throw new Error(`Failed to fetch from ${link}: ${response.statusText}`);
51+
}
52+
53+
const jsonData = await response.json();
54+
55+
const [collection, mode] = extractCollectionAndMode(link);
56+
const directory = path.join(__dirname, "json", collection);
57+
58+
await fs.mkdir(directory, { recursive: true });
59+
60+
const fileName = `${mode}.json`;
61+
const filePath = path.join(directory, fileName);
62+
63+
await fs.writeFile(filePath, JSON.stringify(jsonData, null, 2));
64+
}
65+
} catch (error) {
66+
console.error("❗️Error:", error);
67+
}
68+
}
69+
70+
/**
71+
* Returns Style Dictionary config
72+
*
73+
* @param {string} mode1
74+
* @param {string} mode2
75+
* @returns {json} Style Dictionary config
76+
*/
77+
function getStyleDictionaryConfig(mode1, mode2) {
78+
const buildDir = [mode1, mode2].join("_");
79+
80+
return {
81+
source: [`json/tokens/${mode1}.json`, `json/primitives/${mode2}.json`],
82+
platforms: {
83+
web: {
84+
transformGroup: "web",
85+
buildPath: `build/web/${buildDir}/`,
86+
files: [
87+
{
88+
destination: "tokens.css",
89+
format: "css/variables",
90+
},
91+
],
92+
},
93+
ios: {
94+
transformGroup: "ios",
95+
buildPath: `build/ios/${buildDir}/`,
96+
files: [
97+
{
98+
destination: "tokens.h",
99+
format: "ios/macros",
100+
},
101+
],
102+
},
103+
},
104+
};
105+
}
106+
107+
/**
108+
* Main function that builds tokens
109+
*/
110+
(async () => {
111+
const links = await fetchLinks();
112+
await saveFiles(links);
113+
114+
const collectionModes = extractCollectionModes(links);
115+
const tokensCollectionModes = collectionModes.tokens;
116+
const primitivesCollectionModes = collectionModes.primitives;
117+
const platforms = ["web", "ios"];
118+
119+
console.log("\n🚀 Build started...");
120+
121+
tokensCollectionModes.forEach((m1) => {
122+
primitivesCollectionModes.forEach((m2) => {
123+
platforms.forEach((platform) => {
124+
const sd = new StyleDictionary(getStyleDictionaryConfig(m1, m2));
125+
sd.buildPlatform(platform);
126+
});
127+
});
128+
});
129+
})();

0 commit comments

Comments
 (0)