-
Notifications
You must be signed in to change notification settings - Fork 567
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(examples): add matching build files example #481
Changes from 1 commit
4064e6a
3cc3d4e
ef2dafa
c449bf5
2c4ce1c
ec71d0d
778ce3e
369d712
f95c420
881a57c
c9bfcbc
9690547
4bfd31e
ba6fae7
353588f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
build/ | ||
node_modules/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
## Customize token output using filters | ||
|
||
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 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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I love this 'common use cases' section. I think this is something we should start adding to examples. |
||
|
||
#### 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.json` 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! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
const StyleDictionary = require("style-dictionary"); | ||
const tokens = require("./properties"); | ||
|
||
module.exports = { | ||
source: ["properties/**/*.json"], | ||
platforms: { | ||
"esm/category": { | ||
transformGroup: "js", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like you are defining both |
||
buildPath: "build/js/esm/", | ||
transforms: ["attribute/cti", "name/cti/camel", "size/px", "color/hex"], | ||
files: tokens.map((tokenCategory) => ({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Super cool 😎 |
||
destination: `${tokenCategory}.js`, | ||
format: "javascript/es6", | ||
filter: { | ||
attributes: { | ||
category: tokenCategory, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is awesome that it uses the built-in filter mechanism! |
||
}, | ||
}, | ||
})), | ||
}, | ||
"esm/index": { | ||
transformGroup: "js", | ||
buildPath: "build/js/esm/", | ||
transforms: ["attribute/cti", "name/cti/camel", "size/px", "color/hex"], | ||
files: [ | ||
{ | ||
destination: `index.js`, | ||
format: "javascript/es6", | ||
}, | ||
], | ||
}, | ||
"cjs/category": { | ||
transformGroup: "js", | ||
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": { | ||
transformGroup: "js", | ||
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.registerTransform({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't appear that this transform or the next one are being used? |
||
name: "size/pxToPt", | ||
type: "value", | ||
matcher: function (prop) { | ||
return prop.value.match(/[\d.]+px/g); | ||
}, | ||
transformer: function (prop) { | ||
return prop.value.replace(/px/g, "pt"); | ||
}, | ||
}); | ||
|
||
StyleDictionary.registerTransform({ | ||
name: "size/pxToDp", | ||
type: "value", | ||
matcher: function (prop) { | ||
return prop.value.match(/[\d.]+px/g); | ||
}, | ||
transformer: function (prop) { | ||
return prop.value.replace(/px/g, "dp"); | ||
}, | ||
}); | ||
|
||
StyleDictionary.registerFormat({ | ||
name: "custom/cjsmodule", | ||
formatter: function (dictionary) { | ||
return `module.exports = {${dictionary.allProperties.map( | ||
(prop) => `\n\t${prop.name}: "${prop.value}"` | ||
)}\n};`; | ||
}, | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this file can be deleted? |
||
* Do not edit directly | ||
* Generated on Sat, 07 Nov 2020 21:21:52 GMT | ||
*/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about changing the name of this example? This example is showing how to generate output files 1:1 based on category/folder. I don't have a good name in mind right now...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Darn, I was hoping you had a suggestion haha. I was thinking maybe something like
matching-build-files
? Open to whatever makes it easier to understand what this example does. :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll think about it today..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about "Custom Build", or "Custom Output Structure"?
I'm so excited to see this work, I'm creating a multi-brand design system that has shared global styles among the brands, and specific brand styles for each site. I'd love to output tokens as two separate files, like
global.scss
andbrand.scss