Skip to content

Commit

Permalink
feat(examples): add matching build files example (#481)
Browse files Browse the repository at this point in the history
 Adding an example of how someone could automatically generate 1:1 token files based on a custom filter. #251
  • Loading branch information
dbanksdesign authored Nov 14, 2020
2 parents a8bb832 + 353588f commit 5a80ef6
Show file tree
Hide file tree
Showing 13 changed files with 9,866 additions and 4,941 deletions.
12,948 changes: 8,718 additions & 4,230 deletions examples/advanced/create-react-app/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examples/advanced/create-react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"node-sass": "^4.14.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "^3.4.1",
"react-scripts": "^4.0.0",
"styled-components": "^5.1.1"
},
"devDependencies": {
Expand All @@ -29,4 +29,4 @@
"not op_mini all"
],
"license": "Apache-2.0"
}
}
2 changes: 2 additions & 0 deletions examples/advanced/matching-build-files/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/
node_modules/
61 changes: 61 additions & 0 deletions examples/advanced/matching-build-files/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## Automatically generate separate build files that match your folder structure

This example shows how you can manage what tokens are generated and how they are organized. This is useful when you want to generate a 1:1 relationship between build files and token categories.

Common use cases include:

- Each token category as its own Sass partial (_colors.scss)
- Separate component files (button.css, input.css, etc)
- Tree shaking (only import what you need)

#### Running the example

First of all, set up the required dependencies running the command `npm install` in your local CLI environment (if you prefer to use *yarn*, update the commands accordingly).

At this point, you can run `npm run build`. This command will generate the output file in the `build` folder.

#### How does it work

The "build" command processes the JSON files in the `properties` folder. The `index.js` file adds each folder, allowing you to map through them in `config.js`. The script goes through each folder and generates a file for each folder and populates it with tokens that match the filter.

```sh
# properties/color/base.json
{
"color": {
"red": {
"value": "#FF0000"
}
}
}
```

```sh
# properties/size/base.json
{
"size": {
"small": {
"value": "2px"
}
}
}
```

Because the folder name matches the category, the output would automatically generate separate `color` and `size` files.

#### What to look at

Open the `config.js` file and see how the script first looks within the `properties` directory to map through each folder. The destination then outputs a file that would match the name, and fill that file with the tokens that match the filter criteria.

```sh
files: properties.map(tokenCategory => ({
destination: `${tokenCategory}.js`,
format: "format/js",
filter: {
attributes: {
category: tokenCategory
}
}
}))
```

Now each new folder that gets added will automatically generate a corresponding file filled with tokens that match the category!
89 changes: 89 additions & 0 deletions examples/advanced/matching-build-files/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
const StyleDictionary = require("style-dictionary");
const tokens = require("./properties");

module.exports = {
source: ["properties/**/*.json"],
platforms: {
"esm/category": {
buildPath: "build/js/esm/",
transforms: ["attribute/cti", "name/cti/camel", "size/px", "color/hex"],
files: tokens.map((tokenCategory) => ({
destination: `${tokenCategory}.js`,
format: "javascript/es6",
filter: {
attributes: {
category: tokenCategory,
},
},
})),
},
"esm/index": {
buildPath: "build/js/esm/",
transforms: ["attribute/cti", "name/cti/camel", "size/px", "color/hex"],
files: [
{
destination: `index.js`,
format: "javascript/es6",
},
],
},
"cjs/category": {
buildPath: "build/js/cjs/",
transforms: ["attribute/cti", "name/cti/camel", "size/px", "color/hex"],
files: tokens.map((tokenCategory) => ({
destination: `${tokenCategory}.js`,
format: "custom/cjsmodule",
filter: {
attributes: {
category: tokenCategory,
},
},
})),
},
"cjs/index": {
buildPath: "build/js/cjs/",
transforms: ["attribute/cti", "name/cti/camel", "size/px", "color/hex"],
files: [
{
destination: `index.js`,
format: "custom/cjsmodule",
},
],
},

// Web output in scss format
scss: {
transformGroup: "scss",
buildPath: `build/scss/`,
files: [
{
destination: `tokens.scss`,
format: "scss/variables",
},
],
},
// Web output in scss partialformat
"scss/category": {
transformGroup: "scss",
buildPath: `build/scss/`,
files: tokens.map((tokenCategory) => ({
destination: `_${tokenCategory}.scss`,
format: "scss/variables",
filter: {
attributes: {
category: tokenCategory,
},
},
})),
},
},
};

StyleDictionary.registerFormat({
name: "custom/cjsmodule",
formatter: function (dictionary) {
return `module.exports = {${dictionary.allProperties.map(
(prop) => `\n\t${prop.name}: "${prop.value}"`
)}\n};`;
},
});
Loading

0 comments on commit 5a80ef6

Please sign in to comment.