From 98daa5c903e84df6afa84debedec43583d5592ef Mon Sep 17 00:00:00 2001 From: Narin Ratana Date: Tue, 19 Sep 2023 13:25:19 -0700 Subject: [PATCH] Add style-dictionary and generate initial tokens --- packages/tokens/README.md | 181 ++++++++++++++++++ packages/tokens/config.json | 17 ++ packages/tokens/dist/variables.js | 16 ++ packages/tokens/package.json | 12 +- packages/tokens/src/tokens/color/brand.json | 202 ++++++++++++++++++++ yarn.lock | 131 ++++++++++++- 6 files changed, 555 insertions(+), 4 deletions(-) create mode 100644 packages/tokens/README.md create mode 100644 packages/tokens/config.json create mode 100644 packages/tokens/dist/variables.js create mode 100644 packages/tokens/src/tokens/color/brand.json diff --git a/packages/tokens/README.md b/packages/tokens/README.md new file mode 100644 index 00000000..985b48fe --- /dev/null +++ b/packages/tokens/README.md @@ -0,0 +1,181 @@ +# Basic Style Dictionary + +This example code is bare-bones to show you what this framework can do. If you have the style-dictionary module installed globally, you can `cd` into this directory and run: +```bash +style-dictionary build +``` + +You should see something like this output: +``` +Copying starter files... + +Source style dictionary starter files created! + +Running `style-dictionary build` for the first time to generate build artifacts. + + +scss +✔︎ build/scss/_variables.scss + +android +✔︎ build/android/font_dimens.xml +✔︎ build/android/colors.xml + +compose +✔︎ build/compose/StyleDictionaryColor.kt +✔︎ build/compose/StyleDictionarySize.kt + +ios +✔︎ build/ios/StyleDictionaryColor.h +✔︎ build/ios/StyleDictionaryColor.m +✔︎ build/ios/StyleDictionarySize.h +✔︎ build/ios/StyleDictionarySize.m + +ios-swift +✔︎ build/ios-swift/StyleDictionary.swift + +ios-swift-separate-enums +✔︎ build/ios-swift/StyleDictionaryColor.swift +✔︎ build/ios-swift/StyleDictionarySize.swift +``` + +Good for you! You have now built your first style dictionary! Moving on, take a look at what we have built. This should have created a build directory and it should look like this: +``` +├── README.md +├── config.json +├── tokens/ +│ ├── color/ +│ ├── base.json +│ ├── font.json +│ ├── size/ +│ ├── font.json +├── build/ +│ ├── android/ +│ ├── font_dimens.xml +│ ├── colors.xml +│ ├── compose/ +│ ├── StyleDictionaryColor.kt +│ ├── StyleDictionarySize.kt +│ ├── scss/ +│ ├── _variables.scss +│ ├── ios/ +│ ├── StyleDictionaryColor.h +│ ├── StyleDictionaryColor.m +│ ├── StyleDictionarySize.h +│ ├── StyleDictionarySize.m +│ ├── ios-swift/ +│ ├── StyleDictionary.swift +│ ├── StyleDictionaryColor.swift +│ ├── StyleDictionarySize.swift +``` + +If you open `config.json` you will see there are 5 platforms defined: scss, android, compose, ios, and ios-swift. Each platform has a transformGroup, buildPath, and files. The buildPath and files of the platform should match up to the files what were built. The files built should look like these: + +**Android** +```xml + + + 12.00sp + 16.00sp + 32.00sp + 16.00sp + + + + + #ffcccccc + #ff999999 + #ff111111 + #ffff0000 + #ff00ff00 + #ffff0000 + #ff00ff00 + #ffcccccc + +``` + +**Compose** +```kotlin +object StyleDictionaryColor { + val colorBaseGrayDark = Color(0xff111111) + val colorBaseGrayLight = Color(0xffcccccc) + val colorBaseGrayMedium = Color(0xff999999) + val colorBaseGreen = Color(0xff00ff00) + val colorBaseRed = Color(0xffff0000) + val colorFontBase = Color(0xffff0000) + val colorFontSecondary = Color(0xff00ff00) + val colorFontTertiary = Color(0xffcccccc) +} + +object StyleDictionarySize { + /** the base size of the font */ + val sizeFontBase = 16.00.sp + /** the large size of the font */ + val sizeFontLarge = 32.00.sp + /** the medium size of the font */ + val sizeFontMedium = 16.00.sp + /** the small size of the font */ + val sizeFontSmall = 12.00.sp +} +``` + +**SCSS** +```scss +// variables.scss +$color-base-gray-light: #cccccc; +$color-base-gray-medium: #999999; +$color-base-gray-dark: #111111; +$color-base-red: #ff0000; +$color-base-green: #00ff00; +$color-font-base: #ff0000; +$color-font-secondary: #00ff00; +$color-font-tertiary: #cccccc; +$size-font-small: 0.75rem; +$size-font-medium: 1rem; +$size-font-large: 2rem; +$size-font-base: 1rem; +``` + +**iOS** +```objc +#import "StyleDictionaryColor.h" + +@implementation StyleDictionaryColor + ++ (UIColor *)color:(StyleDictionaryColorName)colorEnum{ + return [[self values] objectAtIndex:colorEnum]; +} + ++ (NSArray *)values { + static NSArray* colorArray; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + colorArray = @[ +[UIColor colorWithRed:0.800f green:0.800f blue:0.800f alpha:1.000f], +[UIColor colorWithRed:0.600f green:0.600f blue:0.600f alpha:1.000f], +[UIColor colorWithRed:0.067f green:0.067f blue:0.067f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.000f blue:0.000f alpha:1.000f], +[UIColor colorWithRed:0.000f green:1.000f blue:0.000f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.000f blue:0.000f alpha:1.000f], +[UIColor colorWithRed:0.000f green:1.000f blue:0.000f alpha:1.000f], +[UIColor colorWithRed:0.800f green:0.800f blue:0.800f alpha:1.000f] + ]; + }); + + return colorArray; +} + +@end +``` + +Pretty nifty! This shows a few things happening: +1. The build system does a deep merge of all the token JSON files defined in the `source` attribute of `config.json`. This allows you to split up the token JSON files however you want. There are 2 JSON files with `color` as the top level key, but they get merged properly. +1. The build system resolves references to other design tokens. `{size.font.medium.value}` gets resolved properly. +1. The build system handles references to token values in other files as well as you can see in `tokens/color/font.json`. + +Now let's make a change and see how that affects things. Open up `tokens/color/base.json` and change `"#111111"` to `"#000000"`. After you make that change, save the file and re-run the build command `style-dictionary build`. Open up the build files and take a look. + +**Huzzah!** + +Now go forth and create! Take a look at all the built-in [transforms](https://amzn.github.io/style-dictionary/#/transforms?id=pre-defined-transforms) and [formats](https://amzn.github.io/style-dictionary/#/formats?id=pre-defined-formats). diff --git a/packages/tokens/config.json b/packages/tokens/config.json new file mode 100644 index 00000000..96a65f03 --- /dev/null +++ b/packages/tokens/config.json @@ -0,0 +1,17 @@ +{ + "source": [ + "./src/tokens/**/*.json" + ], + "platforms": { + "rn": { + "transformGroup": "react-native", + "buildPath": "./dist/", + "files": [ + { + "destination": "variables.js", + "format": "javascript/es6" + } + ] + } + } +} diff --git a/packages/tokens/dist/variables.js b/packages/tokens/dist/variables.js new file mode 100644 index 00000000..ed634133 --- /dev/null +++ b/packages/tokens/dist/variables.js @@ -0,0 +1,16 @@ +/** + * Do not edit directly + * Generated on Tue, 19 Sep 2023 19:53:25 GMT + */ + +export const colorWhite = "#ffffff"; +export const colorGray = "#5b616b"; +export const colorGrayDark = "#323a45"; +export const colorGrayMedium = "#757575"; +export const colorGrayLight = "#aeb0b5"; +export const colorGrayLightAlt = "#eeeeee"; +export const colorGrayLighter = "#d6d7d9"; +export const colorGrayLightest = "#f1f1f1"; +export const colorGrayWarmDark = "#494440"; +export const colorGrayWarmLight = "#e4e2e0"; +export const colorGrayCoolLight = "#dce4ef"; diff --git a/packages/tokens/package.json b/packages/tokens/package.json index 5acd5712..735d4dab 100644 --- a/packages/tokens/package.json +++ b/packages/tokens/package.json @@ -1,8 +1,11 @@ { "name": "@department-of-veterans-affairs/mobile-tokens", - "version": "0.0.1", + "version": "0.0.2", "description": "VA Design System Mobile Token Library", - "main": "index.js", + "scripts": { + "build": "style-dictionary build", + "publish-package": "npm publish --access public --tolerate-republish" + }, "repository": { "type": "git", "url": "git+https://github.com/department-of-veterans-affairs/va-mobile-library.git" @@ -22,5 +25,8 @@ "url": "https://github.com/department-of-veterans-affairs/va-mobile-library/issues" }, "homepage": "https://github.com/department-of-veterans-affairs/va-mobile-library#readme", - "packageManager": "yarn@3.6.1" + "packageManager": "yarn@3.6.1", + "devDependencies": { + "style-dictionary": "^3.8.0" + } } diff --git a/packages/tokens/src/tokens/color/brand.json b/packages/tokens/src/tokens/color/brand.json new file mode 100644 index 00000000..074f05f9 --- /dev/null +++ b/packages/tokens/src/tokens/color/brand.json @@ -0,0 +1,202 @@ +{ + "color": { + "white": { + "value": "#fff", + "attributes": { + "category": "color" + } + }, + "gray": { + "*": { + "value": "#5b616b", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#5b616b" + }, + "name": "color-gray", + "attributes": { + "category": "color", + "type": "gray", + "item": "*" + }, + "path": [ + "color", + "gray", + "*" + ] + }, + "dark": { + "value": "#323a45", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#323a45" + }, + "name": "color-gray-dark", + "attributes": { + "category": "color", + "type": "gray", + "item": "dark" + }, + "path": [ + "color", + "gray", + "dark" + ] + }, + "medium": { + "value": "#757575", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#757575" + }, + "name": "color-gray-medium", + "attributes": { + "category": "color", + "type": "gray", + "item": "medium" + }, + "path": [ + "color", + "gray", + "medium" + ] + }, + "light": { + "value": "#aeb0b5", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#aeb0b5" + }, + "name": "color-gray-light", + "attributes": { + "category": "color", + "type": "gray", + "item": "light" + }, + "path": [ + "color", + "gray", + "light" + ] + }, + "light-alt": { + "value": "#eeeeee", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#eeeeee" + }, + "name": "color-gray-light-alt", + "attributes": { + "category": "color", + "type": "gray", + "item": "light-alt" + }, + "path": [ + "color", + "gray", + "light-alt" + ] + }, + "lighter": { + "value": "#d6d7d9", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#d6d7d9" + }, + "name": "color-gray-lighter", + "attributes": { + "category": "color", + "type": "gray", + "item": "lighter" + }, + "path": [ + "color", + "gray", + "lighter" + ] + }, + "lightest": { + "value": "#f1f1f1", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#f1f1f1" + }, + "name": "color-gray-lightest", + "attributes": { + "category": "color", + "type": "gray", + "item": "lightest" + }, + "path": [ + "color", + "gray", + "lightest" + ] + }, + "warm-dark": { + "value": "#494440", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#494440" + }, + "name": "color-gray-warm-dark", + "attributes": { + "category": "color", + "type": "gray", + "item": "warm-dark" + }, + "path": [ + "color", + "gray", + "warm-dark" + ] + }, + "warm-light": { + "value": "#e4e2e0", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#e4e2e0" + }, + "name": "color-gray-warm-light", + "attributes": { + "category": "color", + "type": "gray", + "item": "warm-light" + }, + "path": [ + "color", + "gray", + "warm-light" + ] + }, + "cool-light": { + "value": "#dce4ef", + "filePath": "tokens/color.json", + "isSource": true, + "original": { + "value": "#dce4ef" + }, + "name": "color-gray-cool-light", + "attributes": { + "category": "color", + "type": "gray", + "item": "cool-light" + }, + "path": [ + "color", + "gray", + "cool-light" + ] + } + } + } +} diff --git a/yarn.lock b/yarn.lock index 8afc0612..e7ea741b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2211,6 +2211,8 @@ __metadata: "@department-of-veterans-affairs/mobile-tokens@workspace:packages/tokens": version: 0.0.0-use.local resolution: "@department-of-veterans-affairs/mobile-tokens@workspace:packages/tokens" + dependencies: + style-dictionary: ^3.8.0 languageName: unknown linkType: soft @@ -8024,6 +8026,17 @@ __metadata: languageName: node linkType: hard +"capital-case@npm:^1.0.4": + version: 1.0.4 + resolution: "capital-case@npm:1.0.4" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + upper-case-first: ^2.0.2 + checksum: 41fa8fa87f6d24d0835a2b4a9341a3eaecb64ac29cd7c5391f35d6175a0fa98ab044e7f2602e1ec3afc886231462ed71b5b80c590b8b41af903ec2c15e5c5931 + languageName: node + linkType: hard + "capture-exit@npm:^2.0.0": version: 2.0.0 resolution: "capture-exit@npm:2.0.0" @@ -8068,6 +8081,26 @@ __metadata: languageName: node linkType: hard +"change-case@npm:^4.1.2": + version: 4.1.2 + resolution: "change-case@npm:4.1.2" + dependencies: + camel-case: ^4.1.2 + capital-case: ^1.0.4 + constant-case: ^3.0.4 + dot-case: ^3.0.4 + header-case: ^2.0.4 + no-case: ^3.0.4 + param-case: ^3.0.4 + pascal-case: ^3.1.2 + path-case: ^3.0.4 + sentence-case: ^3.0.4 + snake-case: ^3.0.4 + tslib: ^2.0.3 + checksum: e4bc4a093a1f7cce8b33896665cf9e456e3bc3cc0def2ad7691b1994cfca99b3188d0a513b16855b01a6bd20692fcde12a7d4d87a5615c4c515bbbf0e651f116 + languageName: node + linkType: hard + "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -8631,6 +8664,17 @@ __metadata: languageName: node linkType: hard +"constant-case@npm:^3.0.4": + version: 3.0.4 + resolution: "constant-case@npm:3.0.4" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + upper-case: ^2.0.2 + checksum: 6c3346d51afc28d9fae922e966c68eb77a19d94858dba230dd92d7b918b37d36db50f0311e9ecf6847e43e934b1c01406a0936973376ab17ec2c471fbcfb2cf3 + languageName: node + linkType: hard + "constants-browserify@npm:^1.0.0": version: 1.0.0 resolution: "constants-browserify@npm:1.0.0" @@ -11211,7 +11255,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^10.1.0": +"fs-extra@npm:^10.0.0, fs-extra@npm:^10.1.0": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" dependencies: @@ -12014,6 +12058,16 @@ __metadata: languageName: node linkType: hard +"header-case@npm:^2.0.4": + version: 2.0.4 + resolution: "header-case@npm:2.0.4" + dependencies: + capital-case: ^1.0.4 + tslib: ^2.0.3 + checksum: 571c83eeb25e8130d172218712f807c0b96d62b020981400bccc1503a7cf14b09b8b10498a962d2739eccf231d950e3848ba7d420b58a6acd2f9283439546cd9 + languageName: node + linkType: hard + "hermes-estree@npm:0.8.0": version: 0.8.0 resolution: "hermes-estree@npm:0.8.0" @@ -14228,6 +14282,13 @@ __metadata: languageName: node linkType: hard +"jsonc-parser@npm:^3.0.0": + version: 3.2.0 + resolution: "jsonc-parser@npm:3.2.0" + checksum: 946dd9a5f326b745aa326d48a7257e3f4a4b62c5e98ec8e49fa2bdd8d96cef7e6febf1399f5c7016114fd1f68a1c62c6138826d5d90bc650448e3cf0951c53c7 + languageName: node + linkType: hard + "jsonfile@npm:^4.0.0": version: 4.0.0 resolution: "jsonfile@npm:4.0.0" @@ -16820,6 +16881,16 @@ __metadata: languageName: node linkType: hard +"path-case@npm:^3.0.4": + version: 3.0.4 + resolution: "path-case@npm:3.0.4" + dependencies: + dot-case: ^3.0.4 + tslib: ^2.0.3 + checksum: 61de0526222629f65038a66f63330dd22d5b54014ded6636283e1d15364da38b3cf29e4433aa3f9d8b0dba407ae2b059c23b0104a34ee789944b1bc1c5c7e06d + languageName: node + linkType: hard + "path-dirname@npm:^1.0.0": version: 1.0.2 resolution: "path-dirname@npm:1.0.2" @@ -19253,6 +19324,17 @@ __metadata: languageName: node linkType: hard +"sentence-case@npm:^3.0.4": + version: 3.0.4 + resolution: "sentence-case@npm:3.0.4" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + upper-case-first: ^2.0.2 + checksum: 3cfe6c0143e649132365695706702d7f729f484fa7b25f43435876efe7af2478243eefb052bacbcce10babf9319fd6b5b6bc59b94c80a1c819bcbb40651465d5 + languageName: node + linkType: hard + "serialize-error@npm:6.0.0": version: 6.0.0 resolution: "serialize-error@npm:6.0.0" @@ -19532,6 +19614,16 @@ __metadata: languageName: node linkType: hard +"snake-case@npm:^3.0.4": + version: 3.0.4 + resolution: "snake-case@npm:3.0.4" + dependencies: + dot-case: ^3.0.4 + tslib: ^2.0.3 + checksum: 0a7a79900bbb36f8aaa922cf111702a3647ac6165736d5dc96d3ef367efc50465cac70c53cd172c382b022dac72ec91710608e5393de71f76d7142e6fd80e8a3 + languageName: node + linkType: hard + "snapdragon-node@npm:^2.0.1": version: 2.1.1 resolution: "snapdragon-node@npm:2.1.1" @@ -20187,6 +20279,25 @@ __metadata: languageName: node linkType: hard +"style-dictionary@npm:^3.8.0": + version: 3.8.0 + resolution: "style-dictionary@npm:3.8.0" + dependencies: + chalk: ^4.0.0 + change-case: ^4.1.2 + commander: ^8.3.0 + fs-extra: ^10.0.0 + glob: ^7.2.0 + json5: ^2.2.2 + jsonc-parser: ^3.0.0 + lodash: ^4.17.15 + tinycolor2: ^1.4.1 + bin: + style-dictionary: bin/style-dictionary + checksum: ed2440c2d1bd84593f9f60ffbfbb7c85c9592d125e169ea63e2044fe681191e8c9c156853d82ae606f9adf6aacbaa162e03d5ef85b80be334d76e28a57bfc189 + languageName: node + linkType: hard + "style-loader@npm:^1.3.0": version: 1.3.0 resolution: "style-loader@npm:1.3.0" @@ -21398,6 +21509,24 @@ __metadata: languageName: node linkType: hard +"upper-case-first@npm:^2.0.2": + version: 2.0.2 + resolution: "upper-case-first@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: 4487db4701effe3b54ced4b3e4aa4d9ab06c548f97244d04aafb642eedf96a76d5a03cf5f38f10f415531d5792d1ac6e1b50f2a76984dc6964ad530f12876409 + languageName: node + linkType: hard + +"upper-case@npm:^2.0.2": + version: 2.0.2 + resolution: "upper-case@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: 508723a2b03ab90cf1d6b7e0397513980fab821cbe79c87341d0e96cedefadf0d85f9d71eac24ab23f526a041d585a575cfca120a9f920e44eb4f8a7cf89121c + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1"