diff --git a/.editorconfig b/.editorconfig index da0310f51..1cd9f64bd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,7 +7,6 @@ indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true -insert_final_newline = true [*.md] trim_trailing_whitespace = false \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 7717b8c37..a32eb0a2e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,6 +2,7 @@ "parserOptions": { "ecmaVersion": 6 }, + "plugins": ["jest"], "env": { "node": true, "mocha": true, @@ -11,11 +12,16 @@ "Buffer": true, "escape": true }, - "extends": "eslint:recommended", + "extends": [ + "eslint:recommended", + "plugin:jest/recommended" + ], "rules": { "no-console": 0, "no-unused-vars": 1, + "no-control-regex": 0, "comma-dangle": 0, - "no-prototype-builtins": 0 + "no-prototype-builtins": 0, + "jest/valid-title": 0 } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 55c5599c7..c4b250fff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,147 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [3.0.0-rc.10](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.9...v3.0.0-rc.10) (2021-05-24) + + +### Features + +* **formats:** add typescript declarations formats ([#557](https://github.com/amzn/style-dictionary/issues/557)) ([f517bcf](https://github.com/amzn/style-dictionary/commit/f517bcfa219bddc5a10b5443ccb85c4869711064)), closes [#425](https://github.com/amzn/style-dictionary/issues/425) +* **types:** cleaning up our type definitions ([#632](https://github.com/amzn/style-dictionary/issues/632)) ([db6269b](https://github.com/amzn/style-dictionary/commit/db6269b636264cc0849f595c0f15a34c977c1398)) + + +### Bug Fixes + +* **references:** value object references now work ([#623](https://github.com/amzn/style-dictionary/issues/623)) ([23de306](https://github.com/amzn/style-dictionary/commit/23de3062c464a70d9e6492a380e1052e9500ea2d)), closes [#615](https://github.com/amzn/style-dictionary/issues/615) +* **template:** remove blank lines in scss/map-deep and scss/map-flat templates ([#588](https://github.com/amzn/style-dictionary/issues/588)) ([a88e622](https://github.com/amzn/style-dictionary/commit/a88e622bcc06a98972dddb2b11903828ba3dab2b)) + +### [2.10.3](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.5...v2.10.3) (2021-03-09) + + +### Bug Fixes + +* **extend:** remove prototype pollution ([#560](https://github.com/amzn/style-dictionary/issues/560)) ([89ee39a](https://github.com/amzn/style-dictionary/commit/89ee39a7953c1825ea4578d43f129e23b4ed5da8)) + +## [3.0.0-rc.9](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.8...v3.0.0-rc.9) (2021-05-04) + + +### Features + +* **compose:** Add Jetpack Compose format ([#599](https://github.com/amzn/style-dictionary/issues/599)) ([8a53858](https://github.com/amzn/style-dictionary/commit/8a53858dc35f4b4565abe9a6500c78814e3e6eae)), closes [#478](https://github.com/amzn/style-dictionary/issues/478) + + +### Bug Fixes + +* **formats:** bringing mapName back to scss formats ([#611](https://github.com/amzn/style-dictionary/issues/611)) ([7a28f40](https://github.com/amzn/style-dictionary/commit/7a28f40b7f44b37e565b1360683b60268d044e9e)) +* **formats:** fixing formatting options in fileHeader ([#614](https://github.com/amzn/style-dictionary/issues/614)) ([3f7fe96](https://github.com/amzn/style-dictionary/commit/3f7fe9674c0cb1f228e0415ce468d18a48e4a7f0)), closes [#612](https://github.com/amzn/style-dictionary/issues/612) +* **references:** fixing circular reference errors ([#607](https://github.com/amzn/style-dictionary/issues/607)) ([9af17f4](https://github.com/amzn/style-dictionary/commit/9af17f420c2a11c64f77041f5c2439c093f9c035)), closes [#608](https://github.com/amzn/style-dictionary/issues/608) +* **references:** flushing the filtered reference warnings ([#598](https://github.com/amzn/style-dictionary/issues/598)) ([d3b5135](https://github.com/amzn/style-dictionary/commit/d3b51352f33cb15765cb152605acd3c44e6fbf69)) + +## [3.0.0-rc.8](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.7...v3.0.0-rc.8) (2021-04-05) + + +### Features + +* **formats:** add an optional selector to css/variables format ([#582](https://github.com/amzn/style-dictionary/issues/582)) ([34922a8](https://github.com/amzn/style-dictionary/commit/34922a8572b7cefc6ca579cca9f73b16bfc4efc0)) +* **formats:** output references handles interpoloated references ([#590](https://github.com/amzn/style-dictionary/issues/590)) ([cc595ca](https://github.com/amzn/style-dictionary/commit/cc595ca0683cc757dfae562a8688eb0b8d121cbe)), closes [#589](https://github.com/amzn/style-dictionary/issues/589) + + +### Bug Fixes + +* **combine:** filePath was missing for falsey values ([#583](https://github.com/amzn/style-dictionary/issues/583)) ([8c405e6](https://github.com/amzn/style-dictionary/commit/8c405e6765367aff7eb94fda1a0a235f1c422c9c)) +* **formats:** update output references in formats to handle nested references ([#587](https://github.com/amzn/style-dictionary/issues/587)) ([9ce0311](https://github.com/amzn/style-dictionary/commit/9ce031108979493c7f5d0df34e3546322694feb6)) + +## [3.0.0-rc.7](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.6...v3.0.0-rc.7) (2021-03-24) + + +### Features + +* **formats:** adding custom file headers ([#572](https://github.com/amzn/style-dictionary/issues/572)) ([2a29502](https://github.com/amzn/style-dictionary/commit/2a29502f762c8694dd541dc9c0a0e0aa32e4dec9)), closes [#566](https://github.com/amzn/style-dictionary/issues/566) + + +### Bug Fixes + +* **references:** use unfiltered dictionary for reference resolution in formats ([#553](https://github.com/amzn/style-dictionary/issues/553)) ([62c8fb8](https://github.com/amzn/style-dictionary/commit/62c8fb8ddaccb94dc2eee3b4504f38c264689b77)) + +## [3.0.0-rc.6](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.5...v3.0.0-rc.6) (2021-03-09) + + +### Bug Fixes + +* **extend:** remove prototype pollution ([#554](https://github.com/amzn/style-dictionary/issues/554)) ([b99710a](https://github.com/amzn/style-dictionary/commit/b99710a23abf7d49be28f4ce33dbe99a8af5923f)) + +## [3.0.0-rc.5](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.4...v3.0.0-rc.5) (2021-02-27) + + +### Bug Fixes + +* **types:** introduce parser, update config, optional transform options ([#546](https://github.com/amzn/style-dictionary/issues/546)) ([0042354](https://github.com/amzn/style-dictionary/commit/0042354b4ccb43ef26ddb13adab82b73f25dbf4f)), closes [#545](https://github.com/amzn/style-dictionary/issues/545) + +## [3.0.0-rc.4](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.3...v3.0.0-rc.4) (2021-02-16) + + +### Features + +* **formats:** add stylus/variables format ([#527](https://github.com/amzn/style-dictionary/issues/527)) ([8c56752](https://github.com/amzn/style-dictionary/commit/8c56752d43616884fe6b1f4f7a77994396ce2c3f)), closes [#526](https://github.com/amzn/style-dictionary/issues/526) + +## [3.0.0-rc.3](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.2...v3.0.0-rc.3) (2021-02-06) + + +### Features + +* **build-file:** do not generate file if properties is empty ([#494](https://github.com/amzn/style-dictionary/issues/494)) ([8945c46](https://github.com/amzn/style-dictionary/commit/8945c46f26a08ff6ffac3a5aa0e84a0f330efdb4)) +* **format:** output references ([#504](https://github.com/amzn/style-dictionary/issues/504)) ([7e7889a](https://github.com/amzn/style-dictionary/commit/7e7889a41c79c58a04297762a31550c9bd7c2ee0)) +* **format:** use named parameters in formatter functions ([#533](https://github.com/amzn/style-dictionary/issues/533)) ([32bd40d](https://github.com/amzn/style-dictionary/commit/32bd40d3a94dd3be49ea795e3dbcc70e149bd6eb)) +* react-native support ([#512](https://github.com/amzn/style-dictionary/issues/512)) ([bd61cd2](https://github.com/amzn/style-dictionary/commit/bd61cd294afccd5299a7103fd2ea6177203e9994)) + + +### Bug Fixes + +* **examples:** little typo ([#518](https://github.com/amzn/style-dictionary/issues/518)) ([33271b6](https://github.com/amzn/style-dictionary/commit/33271b62b2a0c100a2be8c08f7cd89815e287327)) +* **export platform:** fixing infinite loop when there are reference errors ([#531](https://github.com/amzn/style-dictionary/issues/531)) ([6078c80](https://github.com/amzn/style-dictionary/commit/6078c8041286589eef7515945f771240bf73c8ef)) +* **property setup:** original property being mutated if the value is an object ([#534](https://github.com/amzn/style-dictionary/issues/534)) ([0b13ae2](https://github.com/amzn/style-dictionary/commit/0b13ae212023ba003ab71cc30eadb20ad10ebc0c)) +* **types:** add transitive to value transform type ([#536](https://github.com/amzn/style-dictionary/issues/536)) ([695eed6](https://github.com/amzn/style-dictionary/commit/695eed60f9f56c30542bbec8d0c1622a6a6959df)) +* **types:** Change transforms to transform in Core ([#530](https://github.com/amzn/style-dictionary/issues/530)) ([40a2601](https://github.com/amzn/style-dictionary/commit/40a2601724ed947aa141ff53e874c14c317992df)) + +## [3.0.0-rc.2](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.1...v3.0.0-rc.2) (2021-01-12) + + +### Features + +* **format:** adding android/resources format ([e43aafd](https://github.com/amzn/style-dictionary/commit/e43aafd0e4c5f34158ea0cdc222833b79b35ab16)) +* **transforms:** add 'px to rem' transform ([#491](https://github.com/amzn/style-dictionary/issues/491)) ([75f0ba3](https://github.com/amzn/style-dictionary/commit/75f0ba36e1211edf955c7b6bd6c58cbd9fc6524c)) + + +### Bug Fixes + +* **extend:** use given file path for token data ([#499](https://github.com/amzn/style-dictionary/issues/499)) ([0b23c9d](https://github.com/amzn/style-dictionary/commit/0b23c9d77e367b2080e4b624fcb294773b2aefcb)) +* **parsers:** fixed an error where parsers weren't running ([#511](https://github.com/amzn/style-dictionary/issues/511)) ([b0077c3](https://github.com/amzn/style-dictionary/commit/b0077c3d06caf5b7fcacd7378aab7827cdaa3961)) +* **types:** fix transform options type [#502](https://github.com/amzn/style-dictionary/issues/502) ([32787f8](https://github.com/amzn/style-dictionary/commit/32787f8a133a61f6132cef4bb88922f72951b804)) + +## [3.0.0-rc.1](https://github.com/amzn/style-dictionary/compare/v3.0.0-rc.0...v3.0.0-rc.1) (2020-12-04) + +## [3.0.0-rc.0](https://github.com/amzn/style-dictionary/compare/v2.10.2...v3.0.0-rc.0) (2020-12-03) + + +### Features + +* **examples:** add custom filters example ([c9bfcbc](https://github.com/amzn/style-dictionary/commit/c9bfcbcb07fec4435f2368c66d0db793d676a06e)) +* **examples:** add custom filters example ([f95c420](https://github.com/amzn/style-dictionary/commit/f95c4202e93dcc00b47e595c4910f435a57d1987)) +* **examples:** add matching build files example ([#481](https://github.com/amzn/style-dictionary/issues/481)) ([5a80ef6](https://github.com/amzn/style-dictionary/commit/5a80ef626bacb6b487f2543793e7ed6451e81498)), closes [#251](https://github.com/amzn/style-dictionary/issues/251) +* add support for !default in SCSS variables format ([#359](https://github.com/amzn/style-dictionary/issues/359)) ([fa82002](https://github.com/amzn/style-dictionary/commit/fa8200221477a7bf0d9fcb031a54dc61ba2e3f72)), closes [#307](https://github.com/amzn/style-dictionary/issues/307) +* add TypeScript typings ([#410](https://github.com/amzn/style-dictionary/issues/410)) ([a8bb832](https://github.com/amzn/style-dictionary/commit/a8bb83278fa5bf7b1796d7f466f21a7beef0da84)) +* **core:** add new entries on property object ([#356](https://github.com/amzn/style-dictionary/issues/356)) ([fd254a5](https://github.com/amzn/style-dictionary/commit/fd254a5e9f78b9888cf59770e61800357421d934)) +* **formats:** add file object to formatter method ([#439](https://github.com/amzn/style-dictionary/issues/439)) ([1481c46](https://github.com/amzn/style-dictionary/commit/1481c46647808d95dc26ff6c08a0906df09d0316)) +* **formats:** javascript/module-flat format ([#457](https://github.com/amzn/style-dictionary/issues/457)) ([37b06e8](https://github.com/amzn/style-dictionary/commit/37b06e86ba77576fb0619372fd73e16673c6440d)) +* **parser:** adding custom parser support ([#429](https://github.com/amzn/style-dictionary/issues/429)) ([887a837](https://github.com/amzn/style-dictionary/commit/887a837a72f15cb4e2550f883e6d4479e1fa9d42)) +* **transforms:** Make transitive transforms & resolves possible ([#371](https://github.com/amzn/style-dictionary/issues/371)) ([3edbb17](https://github.com/amzn/style-dictionary/commit/3edbb178d53f9e5af2328b7c26271fe436af86d3)), closes [#208](https://github.com/amzn/style-dictionary/issues/208) + +### Bug Fixes + +* **cli:** update clean config path logic ([#454](https://github.com/amzn/style-dictionary/issues/454)) ([dc3cfa5](https://github.com/amzn/style-dictionary/commit/dc3cfa58aa7cc78a6359a8bb269e6f32ba50b110)) +* **formats:** fix max call stack issue on json/nested format ([#465](https://github.com/amzn/style-dictionary/issues/465)) ([67fb361](https://github.com/amzn/style-dictionary/commit/67fb361fb2448f9b91a1a125ee61d6bbe2f77732)) +* **transforms:** fix transitive transforms ([#476](https://github.com/amzn/style-dictionary/issues/476)) ([ac0c515](https://github.com/amzn/style-dictionary/commit/ac0c515c8b4593b91eb352b1f744895796e3ab49)) + ### [2.10.3](https://github.com/amzn/style-dictionary/compare/v2.10.2...v2.10.3) (2021-03-09) @@ -9,6 +150,7 @@ All notable changes to this project will be documented in this file. See [standa * **extend:** remove prototype pollution ([#560](https://github.com/amzn/style-dictionary/issues/560)) ([89ee39a](https://github.com/amzn/style-dictionary/commit/89ee39a7953c1825ea4578d43f129e23b4ed5da8)) + ### [2.10.2](https://github.com/amzn/style-dictionary/compare/v2.10.1...v2.10.2) (2020-10-08) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef1293cd8..4bdb1f771 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,7 @@ We use npm as our package manager. After downloading the repo, please use the co We use ESLint on the code to ensure a consistent style. Any new code committed must pass our ESLint tests. Take a look at our [ESLint file][eslint]. ### Code Rules -1. **Do not mutate property names or values in a format.** Mutations like this should happen in a transformer. +1. **Do not mutate token names or values in a format.** Mutations like this should happen in a transformer. 1. **Be as generic as possible.** Do not hard-code any values or configuration in formats. 1. **Fail loudly.** Users should be aware if something is missing or configurations aren't correct. This will help debug any issues instead of failing silently. 1. **Rely on few dependencies.** This framework is meant to be extended and allows for customization. We don't want to bring a slew of dependencies that most people don't need. @@ -82,6 +82,6 @@ We use [docsify](https://docsify.js.org/#/) to transform the markdown files into [issues]: https://github.com/amzn/style-dictionary/issues [pr]: https://github.com/amzn/style-dictionary/pulls -[license]: https://github.com/amzn/style-dictionary/blob/master/LICENSE +[license]: https://github.com/amzn/style-dictionary/blob/main/LICENSE [cla]: http://en.wikipedia.org/wiki/Contributor_License_Agreement -[eslint]: https://github.com/amzn/style-dictionary/blob/master/.eslintrc.json +[eslint]: https://github.com/amzn/style-dictionary/blob/main/.eslintrc.json diff --git a/README.md b/README.md index d0d350a4c..8fdbedeb0 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@
-Get ready for the next release of Style Dictionary! 🚀
+What's new in Style Dictionary 3.0!
 
Style Dictionary logo and mascot [![npm version](https://img.shields.io/npm/v/style-dictionary.svg?style=flat-square)](https://badge.fury.io/js/style-dictionary) ![license](https://img.shields.io/npm/l/style-dictionary.svg?style=flat-square) -[![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/amzn/style-dictionary/blob/master/CONTRIBUTING.md#submitting-pull-requests) +[![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/amzn/style-dictionary/blob/main/CONTRIBUTING.md#submitting-pull-requests) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/amzn/style-dictionary/Test?style=flat-square)](https://github.com/amzn/style-dictionary/actions/workflows/test.yml) [![downloads](https://img.shields.io/npm/dm/style-dictionary.svg?style=flat-square)](https://www.npmjs.com/package/style-dictionary) # Style Dictionary > *Style once, use everywhere.* -A Style Dictionary uses design tokens to define styles once and use those styles on any platform or language. It provides a single place to create and edit your styles, and exports these properties to all the places you need - iOS, Android, CSS, JS, HTML, sketch files, style documentation, etc. It is available as a CLI through npm, but can also be used like any normal node module if you want to extend its functionality. +A Style Dictionary uses design tokens to define styles once and use those styles on any platform or language. It provides a single place to create and edit your styles, and exports these tokens to all the places you need - iOS, Android, CSS, JS, HTML, sketch files, style documentation, etc. It is available as a CLI through npm, but can also be used like any normal node module if you want to extend its functionality. -When you are managing user experiences, it can be quite challenging to keep styles consistent and synchronized across multiple development platforms and devices. At the same time, designers, developers, PMs and others must be able to have consistent and up-to-date style documentation to enable effective work and communication. Even then, mistakes inevitably happen and the design may not be implemented accurately. StyleDictionary solves this by automatically generating style definitions across all platforms from a single source - removing roadblocks, errors, and inefficiencies across your workflow. +When you are managing user experiences, it can be quite challenging to keep styles consistent and synchronized across multiple development platforms and devices. At the same time, designers, developers, PMs and others must be able to have consistent and up-to-date style documentation to enable effective work and communication. Even then, mistakes inevitably happen and the design may not be implemented accurately. Style Dictionary solves this by automatically generating style definitions across all platforms from a single source - removing roadblocks, errors, and inefficiencies across your workflow. For detailed usage head to https://amzn.github.io/style-dictionary @@ -27,7 +27,7 @@ For detailed usage head to https://amzn.github.io/style-dictionary * [Usage](#usage) * [Example](#example) * [Quick Start](#quick-start) -* [Style Properties](#style-properties) +* [Design Tokens](#design-tokens) * [Extending](#extending) * [Contributing](#contributing) * [License](#license) @@ -76,7 +76,7 @@ StyleDictionary.buildAllPlatforms(); The `.extend()` method is an overloaded method that can also take an object with the configuration in the same format as a config.json file. ```javascript const StyleDictionary = require('style-dictionary').extend({ - source: ['properties/**/*.json'], + source: ['tokens/**/*.json'], platforms: { scss: { transformGroup: 'scss', @@ -96,10 +96,11 @@ StyleDictionary.buildAllPlatforms(); ## Example [Take a look at some of our examples](examples/) -A style dictionary is a collection of style properties, key/value pairs that describe stylistic attributes like colors, sizes, icons, motion, etc. A style dictionary defines these style properties in JSON files, and can also include static assets like images and fonts. Here is a basic example of what the package structure can look like: +A style dictionary is a collection of design tokens, key/value pairs that describe stylistic attributes like colors, sizes, icons, motion, etc. A style dictionary defines these design tokens in JSON or Javascript files, and can also include static assets like images and fonts. Here is a basic example of what the package structure can look like: + ``` ├── config.json -├── properties/ +├── tokens/ │ ├── size/ │ ├── font.json │ ├── color/ @@ -111,10 +112,11 @@ A style dictionary is a collection of style properties, key/value pairs that des ``` ### config.json -This tells the style dictionary build system how and what to build. The default file path is config.json in the root of the project, but you can name it whatever you want, you can pass in the `--config` flag. +This tells the style dictionary build system how and what to build. The default file path is `config.json` or `config.js` in the root of the project, but you can name it whatever you want by passing in the `--config` flag to the [CLI](https://amzn.github.io/style-dictionary/#/using_the_cli). + ```json { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "scss": { "transformGroup": "scss", @@ -135,13 +137,14 @@ This tells the style dictionary build system how and what to build. The default } } ``` + | Attribute | Type | Description | | :--- | :--- | :--- | -| source | Array | Paths to the property json files. Can have globs. | +| source | Array | An array of file path [globs](https://github.com/isaacs/node-glob) to design token files. Style Dictionary will do a deep merge of all of the token files, allowing you to organize your files files however you want. | +| include | Array | An array of file path [globs](https://github.com/isaacs/node-glob) to design token files that contain default styles. The Style Dictionary uses this as a base collection of tokens. The tokens found using the "source" attribute will overwrite tokens found using include. | | platforms | Object | Sets of platform files to be built. | -| platforms | Array | Paths to the property json files. Can have globs. | -| platform.transformGroup | String (optional) | Apply a group of transforms to the properties, must either define this or `transforms`. | -| platform.transforms | Array (optional) | Transforms to apply sequentially to all properties. Can be a built-in one or you can create your own. | +| platform.transformGroup | String (optional) | Apply a group of transforms to the tokens, must either define this or `transforms`. | +| platform.transforms | Array (optional) | Transforms to apply sequentially to all tokens. Can be a built-in one or you can create your own. | | platform.buildPath | String (optional) | Base path to build the files, must end with a trailing slash. | | platform.files | Array (optional) | Files to be generated for this platform. | | platform.file.destination | String (optional) | Location to build the file, will be appended to the buildPath. | @@ -149,7 +152,8 @@ This tells the style dictionary build system how and what to build. The default | platform.file.options | Object (optional) | A set of extra options associated with the file. | | platform.file.options.showFileHeader | Boolean | If the generated file should have a "Do not edit + Timestamp" header (where the format supports it). By default is "true". | -### Properties +### Design Tokens + ```json { "size": { @@ -163,7 +167,7 @@ This tells the style dictionary build system how and what to build. The default } ``` -Here we are creating some basic font size properties. The style definition size.font.small.value is "10px" for example. The style definition size.font.base.value is automatically aliased to the value found in size.font.medium.value and both of those resolve to "16px". +Here we are creating some basic font size design tokens. The style definition size.font.small.value is "10px" for example. The style definition size.font.base.value is automatically aliased to the value found in size.font.medium.value and both of those resolve to "16px". Now what the style dictionary build system will do with this information is convert it to different formats, enabling these values to be used in any type of codebase. From this one file you can generate any number of files like: @@ -190,16 +194,21 @@ float const SizeFontBase = 16.00f; ## Quick Start -The style dictionary framework comes with some example code to get you started. Install the node module globally, create a directory and `cd` into it. + +The style dictionary framework comes with some example code to get you stared. Install the node module globally, create a directory and `cd` into it. + ``` $ npm i -g style-dictionary $ mkdir MyStyleDictionary $ cd MyStyleDictionary ``` + Now run: + ``` $ style-dictionary init basic ``` + This command will copy over the example files found in [example](examples/) in this repo. Now you have an example project set up. You can make changes to the style dictionary and rebuild the project by running: ``` @@ -209,13 +218,13 @@ $ style-dictionary build Take a look at the documentation for the example code. -## Style Properties +## Design Tokens -A style property is an attribute to describe something visually. It is atomic (it cannot be broken down further). Style properties have a name, a value, and optional attributes or metadata. The name of a property can be anything, but we have a proposed naming structure that works really well in the next section. +A design token is an attribute to describe something visually. It is atomic (it cannot be broken down further). Design tokens have a name, a value, and optional attributes or metadata. The name of a token can be anything, but we have a proposed naming structure that we find works really well in the next section. ### Category/Type/Item Structure -While not exactly necessary, we feel this classification structure of style properties makes the most sense semantically. Style properties can be organized into a hierarchical tree structure with the top level, category, defining the primitive nature of the property. For example, we have the color category and every property underneath is always a color. As you proceed down the tree to type, item, sub-item, and state, you get more specific about what that color is. Is it a background color, a text color, or a border color? What kind of text color is it? You get the point. Now you can structure your property json files like simple objects: +While not exactly necessary, we feel this classification structure of design tokens makes the most sense semantically. Design tokens can be organized into a hierarchical tree structure with the top level, category, defining the primitive nature of the token. For example, we have the color category and every token underneath is always a color. As you proceed down the tree to type, item, sub-item, and state, you get more specific about what that color is. Is it a background color, a text color, or a border color? What kind of text color is it? You get the point. Now you can structure your token json files like simple objects: ``` { @@ -228,15 +237,15 @@ While not exactly necessary, we feel this classification structure of style prop } ``` - The CTI is implicit in the structure, the category and type is 'size' and 'font', and there are 2 properties 'base' and 'large'. +The CTI is implicit in the structure, the category and type is 'size' and 'font', and there are 2 tokens 'base' and 'large'. - Structuring style properties in this manner gives us consistent naming and accessing of these properties. You don't need to remember if it is button_color_error or error_button_color, it is color_background_button_error! +Structuring design tokens in this manner gives us consistent naming and accessing of these tokens. You don't need to remember if it is button_color_error or error_button_color, it is color_background_button_error! - You can organize and name your style properties however you want, there are no restrictions. But we have a good amount of helpers if you do use this structure, like the 'attribute/cti' transform which adds attributes to the property of its CTI based on the path in the object. There are a lot of name transforms as well for when you want a flat structure like for Sass variables. +You can organize and name your design tokens however you want, there are no restrictions. But we have a good amount of helpers if you do use this structure, like the 'attribute/cti' transform which adds attributes to the token of its CTI based on the path in the object. There are a lot of name transforms as well for when you want a flat structure like for Sass variables. - Also, the CTI structure provides a good mechanism to target transforms for specific kinds of properties. All of the transforms provided by the framework use the CTI of a property to know if it should be applied. For instance, the 'color/hex' transform only applies to properties of the category 'color'. +Also, the CTI structure provides a good mechanism to target transforms for specific kinds of tokens. All of the transforms provided by the framework use the CTI of a token to know if it should be applied. For instance, the 'color/hex' transform only applies to tokens of the category 'color'. -You can also add a _comment_ to a style property: +You can also add a _comment_ to a design token: ``` { diff --git a/__integration__/README.md b/__integration__/README.md new file mode 100644 index 000000000..f8d9415dd --- /dev/null +++ b/__integration__/README.md @@ -0,0 +1,12 @@ +# Style Dictionary Integration Tests + +Style Dictionary is a tool to generate valid source code for multiple platforms and languages to consume. Because of this, unit testing can only get us so far. Simply unit testing or even basic snapshot testing of outputs doesn't give the whole picture. + +The integration tests here are meant to show complete end-to-end examples of Style Dictionary being used in order to validate the files it is generating. + +The integration tests still use Jest and snapshots, but rather than singling out format code, each test group builds a complete Style Dictionary and then tests the content of the output files with snapshots and validating syntax where possible. + +## To do + +* Jest snapshots are a good built-in way to test if content has changed, but storing the contents of a source code file like a CSS variables file doesn't get proper syntax highlighting and validation in IDEs. It would be better if we could store the raw output file and test against the new contents, but snapshot testing does not allow for that. +* Add more syntax validations \ No newline at end of file diff --git a/__integration__/__snapshots__/android.test.js.snap b/__integration__/__snapshots__/android.test.js.snap new file mode 100644 index 000000000..8d8a33582 --- /dev/null +++ b/__integration__/__snapshots__/android.test.js.snap @@ -0,0 +1,517 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration android android/resources should match snapshot 1`] = ` +" + + + + #ffffffff + #fff3f4f4 + #ffdee1e1 + #ffffeae9 + #ffffede3 + #ffebf9eb + #ffe9f8ff + #ffdee1e1 + #ffc8cccc + #ff0b8599 + #ff6f5ed3 + #ffebf9eb + #ffd7f4d7 + #ffc2f2bd + #ff98e58e + #ff75dd66 + #ff59cb59 + #ff2bb656 + #ff0ca750 + #ff008b46 + #ff006b40 + #ff08422f + #ff002b20 + #ffe5f9f5 + #ffcdf7ef + #ffb3f2e6 + #ff7dead5 + #ff24e0c5 + #ff08c4b2 + #ff00a99c + #ff0b968f + #ff067c7c + #ff026661 + #ff083f3f + #ff002528 + #ffd9fcfb + #ffc5f9f9 + #ffa5f2f2 + #ff76e5e2 + #ff33d6e2 + #ff17b8ce + #ff0797ae + #ff0b8599 + #ff0f6e84 + #ff035e73 + #ff083d4f + #ff002838 + #ffe9f8ff + #ffdcf2ff + #ffc7e4f9 + #ffa1d2f8 + #ff56adf5 + #ff3896e3 + #ff2b87d3 + #ff2079c3 + #ff116daa + #ff0c5689 + #ff0a3960 + #ff002138 + #fff2f2f9 + #ffeaeaf9 + #ffd8d7f9 + #ffc1c1f7 + #ffa193f2 + #ff9180f4 + #ff816fea + #ff6f5ed3 + #ff5e4eba + #ff483a9c + #ff2d246b + #ff1d1d38 + #fffef0ff + #fff9e3fc + #fff4c4f7 + #ffedadf2 + #fff282f5 + #ffdb61db + #ffc44eb9 + #ffac44a8 + #ff8f3896 + #ff6c2277 + #ff451551 + #ff29192d + #ffffe9f3 + #fffcdbeb + #ffffb5d5 + #ffff95c1 + #ffff76ae + #ffef588b + #ffe0447c + #ffce3665 + #ffb22f5b + #ff931847 + #ff561231 + #ff2b1721 + #ffffeae9 + #ffffd5d2 + #ffffb8b1 + #ffff9c8f + #ffff7f6e + #fff76054 + #ffed4c42 + #ffdb3e3e + #ffc63434 + #ff992222 + #ff6d1313 + #ff2b1111 + #ffffede3 + #fffcdccc + #ffffc6a4 + #ffffb180 + #ffff9c5d + #fffc8943 + #fff57d33 + #ffed7024 + #ffce5511 + #ff962c0b + #ff601700 + #ff2d130e + #ffffffff + #fff3f4f4 + #ffdee1e1 + #ffc8cccc + #ffb0b6b7 + #ff929a9b + #ff6e797a + #ff515e5f + #ff364141 + #ff273333 + #ff162020 + #ff040404 + #fffff8e2 + #fffdefcd + #ffffe99a + #ffffe16e + #ffffd943 + #ffffcd1c + #ffffbc00 + #ffdd9903 + #ffba7506 + #ff944c0c + #ff542a00 + #ff2d1a05 + #ff040404 + #ff273333 + #ff364141 + #ff0b8599 + #ff0b8599 + #ff6f5ed3 + #ff364141 + #ff6d1313 + #ff601700 + #ff08422f + 480.00dp + 12.00sp + 16.00sp + 24.00sp + 36.00sp + 8.00dp + 16.00dp + 16.00dp + 16.00dp + + +" +`; + +exports[`integration android android/resources with filter should match snapshot 1`] = ` +" + + + + #ffffffff + #fff3f4f4 + #ffdee1e1 + #ffffeae9 + #ffffede3 + #ffebf9eb + #ffe9f8ff + #ffdee1e1 + #ffc8cccc + #ff0b8599 + #ff6f5ed3 + #ffebf9eb + #ffd7f4d7 + #ffc2f2bd + #ff98e58e + #ff75dd66 + #ff59cb59 + #ff2bb656 + #ff0ca750 + #ff008b46 + #ff006b40 + #ff08422f + #ff002b20 + #ffe5f9f5 + #ffcdf7ef + #ffb3f2e6 + #ff7dead5 + #ff24e0c5 + #ff08c4b2 + #ff00a99c + #ff0b968f + #ff067c7c + #ff026661 + #ff083f3f + #ff002528 + #ffd9fcfb + #ffc5f9f9 + #ffa5f2f2 + #ff76e5e2 + #ff33d6e2 + #ff17b8ce + #ff0797ae + #ff0b8599 + #ff0f6e84 + #ff035e73 + #ff083d4f + #ff002838 + #ffe9f8ff + #ffdcf2ff + #ffc7e4f9 + #ffa1d2f8 + #ff56adf5 + #ff3896e3 + #ff2b87d3 + #ff2079c3 + #ff116daa + #ff0c5689 + #ff0a3960 + #ff002138 + #fff2f2f9 + #ffeaeaf9 + #ffd8d7f9 + #ffc1c1f7 + #ffa193f2 + #ff9180f4 + #ff816fea + #ff6f5ed3 + #ff5e4eba + #ff483a9c + #ff2d246b + #ff1d1d38 + #fffef0ff + #fff9e3fc + #fff4c4f7 + #ffedadf2 + #fff282f5 + #ffdb61db + #ffc44eb9 + #ffac44a8 + #ff8f3896 + #ff6c2277 + #ff451551 + #ff29192d + #ffffe9f3 + #fffcdbeb + #ffffb5d5 + #ffff95c1 + #ffff76ae + #ffef588b + #ffe0447c + #ffce3665 + #ffb22f5b + #ff931847 + #ff561231 + #ff2b1721 + #ffffeae9 + #ffffd5d2 + #ffffb8b1 + #ffff9c8f + #ffff7f6e + #fff76054 + #ffed4c42 + #ffdb3e3e + #ffc63434 + #ff992222 + #ff6d1313 + #ff2b1111 + #ffffede3 + #fffcdccc + #ffffc6a4 + #ffffb180 + #ffff9c5d + #fffc8943 + #fff57d33 + #ffed7024 + #ffce5511 + #ff962c0b + #ff601700 + #ff2d130e + #ffffffff + #fff3f4f4 + #ffdee1e1 + #ffc8cccc + #ffb0b6b7 + #ff929a9b + #ff6e797a + #ff515e5f + #ff364141 + #ff273333 + #ff162020 + #ff040404 + #fffff8e2 + #fffdefcd + #ffffe99a + #ffffe16e + #ffffd943 + #ffffcd1c + #ffffbc00 + #ffdd9903 + #ffba7506 + #ff944c0c + #ff542a00 + #ff2d1a05 + #ff040404 + #ff273333 + #ff364141 + #ff0b8599 + #ff0b8599 + #ff6f5ed3 + #ff364141 + #ff6d1313 + #ff601700 + #ff08422f + + +" +`; + +exports[`integration android android/resources with references should match snapshot 1`] = ` +" + + + + @color/color_core_neutral_0 + @color/color_core_neutral_100 + @color/color_core_neutral_200 + @color/color_core_red_0 + @color/color_core_orange_0 + @color/color_core_green_0 + @color/color_core_blue_0 + @color/color_background_tertiary + @color/color_core_neutral_300 + @color/color_core_aqua_700 + @color/color_core_purple_700 + #ffebf9eb + #ffd7f4d7 + #ffc2f2bd + #ff98e58e + #ff75dd66 + #ff59cb59 + #ff2bb656 + #ff0ca750 + #ff008b46 + #ff006b40 + #ff08422f + #ff002b20 + #ffe5f9f5 + #ffcdf7ef + #ffb3f2e6 + #ff7dead5 + #ff24e0c5 + #ff08c4b2 + #ff00a99c + #ff0b968f + #ff067c7c + #ff026661 + #ff083f3f + #ff002528 + #ffd9fcfb + #ffc5f9f9 + #ffa5f2f2 + #ff76e5e2 + #ff33d6e2 + #ff17b8ce + #ff0797ae + #ff0b8599 + #ff0f6e84 + #ff035e73 + #ff083d4f + #ff002838 + #ffe9f8ff + #ffdcf2ff + #ffc7e4f9 + #ffa1d2f8 + #ff56adf5 + #ff3896e3 + #ff2b87d3 + #ff2079c3 + #ff116daa + #ff0c5689 + #ff0a3960 + #ff002138 + #fff2f2f9 + #ffeaeaf9 + #ffd8d7f9 + #ffc1c1f7 + #ffa193f2 + #ff9180f4 + #ff816fea + #ff6f5ed3 + #ff5e4eba + #ff483a9c + #ff2d246b + #ff1d1d38 + #fffef0ff + #fff9e3fc + #fff4c4f7 + #ffedadf2 + #fff282f5 + #ffdb61db + #ffc44eb9 + #ffac44a8 + #ff8f3896 + #ff6c2277 + #ff451551 + #ff29192d + #ffffe9f3 + #fffcdbeb + #ffffb5d5 + #ffff95c1 + #ffff76ae + #ffef588b + #ffe0447c + #ffce3665 + #ffb22f5b + #ff931847 + #ff561231 + #ff2b1721 + #ffffeae9 + #ffffd5d2 + #ffffb8b1 + #ffff9c8f + #ffff7f6e + #fff76054 + #ffed4c42 + #ffdb3e3e + #ffc63434 + #ff992222 + #ff6d1313 + #ff2b1111 + #ffffede3 + #fffcdccc + #ffffc6a4 + #ffffb180 + #ffff9c5d + #fffc8943 + #fff57d33 + #ffed7024 + #ffce5511 + #ff962c0b + #ff601700 + #ff2d130e + #ffffffff + #fff3f4f4 + #ffdee1e1 + #ffc8cccc + #ffb0b6b7 + #ff929a9b + #ff6e797a + #ff515e5f + #ff364141 + #ff273333 + #ff162020 + #ff040404 + #fffff8e2 + #fffdefcd + #ffffe99a + #ffffe16e + #ffffd943 + #ffffcd1c + #ffffbc00 + #ffdd9903 + #ffba7506 + #ff944c0c + #ff542a00 + #ff2d1a05 + @color/color_core_neutral_1100 + @color/color_core_neutral_900 + @color/color_core_neutral_800 + @color/color_brand_primary + @color/color_brand_primary + @color/color_brand_secondary + @color/color_font_tertiary + @color/color_core_red_1000 + @color/color_core_orange_1000 + @color/color_core_green_1000 + 480.00dp + 12.00sp + 16.00sp + 24.00sp + 36.00sp + 8.00dp + 16.00dp + 16.00dp + 16.00dp + + +" +`; diff --git a/__integration__/__snapshots__/compose.test.js.snap b/__integration__/__snapshots__/compose.test.js.snap new file mode 100644 index 000000000..eb7f42de0 --- /dev/null +++ b/__integration__/__snapshots__/compose.test.js.snap @@ -0,0 +1,363 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration compose compose/object should match snapshot 1`] = ` +" + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + + +package com.example.tokens; + + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.* + +object StyleDictionary { + val colorBackgroundDanger = Color(0xffffeae9) + val colorBackgroundDisabled = Color(0xffdee1e1) + val colorBackgroundInfo = Color(0xffe9f8ff) + val colorBackgroundPrimary = Color(0xffffffff) + val colorBackgroundSecondary = Color(0xfff3f4f4) + val colorBackgroundSuccess = Color(0xffebf9eb) + val colorBackgroundTertiary = Color(0xffdee1e1) + val colorBackgroundWarning = Color(0xffffede3) + val colorBorderPrimary = Color(0xffc8cccc) + val colorBrandPrimary = Color(0xff0b8599) + val colorBrandSecondary = Color(0xff6f5ed3) + val colorCoreAqua0 = Color(0xffd9fcfb) + val colorCoreAqua100 = Color(0xffc5f9f9) + val colorCoreAqua1000 = Color(0xff083d4f) + val colorCoreAqua1100 = Color(0xff002838) + val colorCoreAqua200 = Color(0xffa5f2f2) + val colorCoreAqua300 = Color(0xff76e5e2) + val colorCoreAqua400 = Color(0xff33d6e2) + val colorCoreAqua500 = Color(0xff17b8ce) + val colorCoreAqua600 = Color(0xff0797ae) + val colorCoreAqua700 = Color(0xff0b8599) + val colorCoreAqua800 = Color(0xff0f6e84) + val colorCoreAqua900 = Color(0xff035e73) + val colorCoreBlue0 = Color(0xffe9f8ff) + val colorCoreBlue100 = Color(0xffdcf2ff) + val colorCoreBlue1000 = Color(0xff0a3960) + val colorCoreBlue1100 = Color(0xff002138) + val colorCoreBlue200 = Color(0xffc7e4f9) + val colorCoreBlue300 = Color(0xffa1d2f8) + val colorCoreBlue400 = Color(0xff56adf5) + val colorCoreBlue500 = Color(0xff3896e3) + val colorCoreBlue600 = Color(0xff2b87d3) + val colorCoreBlue700 = Color(0xff2079c3) + val colorCoreBlue800 = Color(0xff116daa) + val colorCoreBlue900 = Color(0xff0c5689) + val colorCoreGreen0 = Color(0xffebf9eb) + val colorCoreGreen100 = Color(0xffd7f4d7) + val colorCoreGreen1000 = Color(0xff08422f) + val colorCoreGreen1100 = Color(0xff002b20) + val colorCoreGreen200 = Color(0xffc2f2bd) + val colorCoreGreen300 = Color(0xff98e58e) + val colorCoreGreen400 = Color(0xff75dd66) + val colorCoreGreen500 = Color(0xff59cb59) + val colorCoreGreen600 = Color(0xff2bb656) + val colorCoreGreen700 = Color(0xff0ca750) + val colorCoreGreen800 = Color(0xff008b46) + val colorCoreGreen900 = Color(0xff006b40) + val colorCoreMagenta0 = Color(0xfffef0ff) + val colorCoreMagenta100 = Color(0xfff9e3fc) + val colorCoreMagenta1000 = Color(0xff451551) + val colorCoreMagenta1100 = Color(0xff29192d) + val colorCoreMagenta200 = Color(0xfff4c4f7) + val colorCoreMagenta300 = Color(0xffedadf2) + val colorCoreMagenta400 = Color(0xfff282f5) + val colorCoreMagenta500 = Color(0xffdb61db) + val colorCoreMagenta600 = Color(0xffc44eb9) + val colorCoreMagenta700 = Color(0xffac44a8) + val colorCoreMagenta800 = Color(0xff8f3896) + val colorCoreMagenta900 = Color(0xff6c2277) + val colorCoreNeutral0 = Color(0xffffffff) + val colorCoreNeutral100 = Color(0xfff3f4f4) + val colorCoreNeutral1000 = Color(0xff162020) + val colorCoreNeutral1100 = Color(0xff040404) + val colorCoreNeutral200 = Color(0xffdee1e1) + val colorCoreNeutral300 = Color(0xffc8cccc) + val colorCoreNeutral400 = Color(0xffb0b6b7) + val colorCoreNeutral500 = Color(0xff929a9b) + val colorCoreNeutral600 = Color(0xff6e797a) + val colorCoreNeutral700 = Color(0xff515e5f) + val colorCoreNeutral800 = Color(0xff364141) + val colorCoreNeutral900 = Color(0xff273333) + val colorCoreOrange0 = Color(0xffffede3) + val colorCoreOrange100 = Color(0xfffcdccc) + val colorCoreOrange1000 = Color(0xff601700) + val colorCoreOrange1100 = Color(0xff2d130e) + val colorCoreOrange200 = Color(0xffffc6a4) + val colorCoreOrange300 = Color(0xffffb180) + val colorCoreOrange400 = Color(0xffff9c5d) + val colorCoreOrange500 = Color(0xfffc8943) + val colorCoreOrange600 = Color(0xfff57d33) + val colorCoreOrange700 = Color(0xffed7024) + val colorCoreOrange800 = Color(0xffce5511) + val colorCoreOrange900 = Color(0xff962c0b) + val colorCorePink0 = Color(0xffffe9f3) + val colorCorePink100 = Color(0xfffcdbeb) + val colorCorePink1000 = Color(0xff561231) + val colorCorePink1100 = Color(0xff2b1721) + val colorCorePink200 = Color(0xffffb5d5) + val colorCorePink300 = Color(0xffff95c1) + val colorCorePink400 = Color(0xffff76ae) + val colorCorePink500 = Color(0xffef588b) + val colorCorePink600 = Color(0xffe0447c) + val colorCorePink700 = Color(0xffce3665) + val colorCorePink800 = Color(0xffb22f5b) + val colorCorePink900 = Color(0xff931847) + val colorCorePurple0 = Color(0xfff2f2f9) + val colorCorePurple100 = Color(0xffeaeaf9) + val colorCorePurple1000 = Color(0xff2d246b) + val colorCorePurple1100 = Color(0xff1d1d38) + val colorCorePurple200 = Color(0xffd8d7f9) + val colorCorePurple300 = Color(0xffc1c1f7) + val colorCorePurple400 = Color(0xffa193f2) + val colorCorePurple500 = Color(0xff9180f4) + val colorCorePurple600 = Color(0xff816fea) + val colorCorePurple700 = Color(0xff6f5ed3) + val colorCorePurple800 = Color(0xff5e4eba) + val colorCorePurple900 = Color(0xff483a9c) + val colorCoreRed0 = Color(0xffffeae9) + val colorCoreRed100 = Color(0xffffd5d2) + val colorCoreRed1000 = Color(0xff6d1313) + val colorCoreRed1100 = Color(0xff2b1111) + val colorCoreRed200 = Color(0xffffb8b1) + val colorCoreRed300 = Color(0xffff9c8f) + val colorCoreRed400 = Color(0xffff7f6e) + val colorCoreRed500 = Color(0xfff76054) + val colorCoreRed600 = Color(0xffed4c42) + val colorCoreRed700 = Color(0xffdb3e3e) + val colorCoreRed800 = Color(0xffc63434) + val colorCoreRed900 = Color(0xff992222) + val colorCoreTeal0 = Color(0xffe5f9f5) + val colorCoreTeal100 = Color(0xffcdf7ef) + val colorCoreTeal1000 = Color(0xff083f3f) + val colorCoreTeal1100 = Color(0xff002528) + val colorCoreTeal200 = Color(0xffb3f2e6) + val colorCoreTeal300 = Color(0xff7dead5) + val colorCoreTeal400 = Color(0xff24e0c5) + val colorCoreTeal500 = Color(0xff08c4b2) + val colorCoreTeal600 = Color(0xff00a99c) + val colorCoreTeal700 = Color(0xff0b968f) + val colorCoreTeal800 = Color(0xff067c7c) + val colorCoreTeal900 = Color(0xff026661) + val colorCoreYellow0 = Color(0xfffff8e2) + val colorCoreYellow100 = Color(0xfffdefcd) + val colorCoreYellow1000 = Color(0xff542a00) + val colorCoreYellow1100 = Color(0xff2d1a05) + val colorCoreYellow200 = Color(0xffffe99a) + val colorCoreYellow300 = Color(0xffffe16e) + val colorCoreYellow400 = Color(0xffffd943) + val colorCoreYellow500 = Color(0xffffcd1c) + val colorCoreYellow600 = Color(0xffffbc00) + val colorCoreYellow700 = Color(0xffdd9903) + val colorCoreYellow800 = Color(0xffba7506) + val colorCoreYellow900 = Color(0xff944c0c) + val colorFontDanger = Color(0xff6d1313) + val colorFontInteractive = Color(0xff0b8599) + val colorFontInteractiveActive = Color(0xff6f5ed3) + val colorFontInteractiveDisabled = Color(0xff364141) + val colorFontInteractiveHover = Color(0xff0b8599) + val colorFontPrimary = Color(0xff040404) + val colorFontSecondary = Color(0xff273333) + val colorFontSuccess = Color(0xff08422f) + val colorFontTertiary = Color(0xff364141) + val colorFontWarning = Color(0xff601700) + val sizeBorderRadiusLarge = 480.00.dp + val sizeFontLarge = 24.00.sp + val sizeFontMedium = 16.00.sp + val sizeFontSmall = 12.00.sp + val sizeFontXl = 36.00.sp + val sizePaddingLarge = 16.00.dp + val sizePaddingMedium = 16.00.dp + val sizePaddingSmall = 8.00.dp + val sizePaddingXl = 16.00.dp +} +" +`; + +exports[`integration compose compose/object with references should match snapshot 1`] = ` +" + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + + +package com.example.tokens; + + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.* + +object StyleDictionary { + val sizePaddingXl = 16.00.dp + val sizePaddingLarge = 16.00.dp + val sizePaddingMedium = 16.00.dp + val sizePaddingSmall = 8.00.dp + val sizeFontXl = 36.00.sp + val sizeFontLarge = 24.00.sp + val sizeFontMedium = 16.00.sp + val sizeFontSmall = 12.00.sp + val sizeBorderRadiusLarge = 480.00.dp + val colorCoreYellow1100 = Color(0xff2d1a05) + val colorCoreYellow1000 = Color(0xff542a00) + val colorCoreYellow900 = Color(0xff944c0c) + val colorCoreYellow800 = Color(0xffba7506) + val colorCoreYellow700 = Color(0xffdd9903) + val colorCoreYellow600 = Color(0xffffbc00) + val colorCoreYellow500 = Color(0xffffcd1c) + val colorCoreYellow400 = Color(0xffffd943) + val colorCoreYellow300 = Color(0xffffe16e) + val colorCoreYellow200 = Color(0xffffe99a) + val colorCoreYellow100 = Color(0xfffdefcd) + val colorCoreYellow0 = Color(0xfffff8e2) + val colorCoreNeutral1100 = Color(0xff040404) + val colorCoreNeutral1000 = Color(0xff162020) + val colorCoreNeutral900 = Color(0xff273333) + val colorCoreNeutral800 = Color(0xff364141) + val colorCoreNeutral700 = Color(0xff515e5f) + val colorCoreNeutral600 = Color(0xff6e797a) + val colorCoreNeutral500 = Color(0xff929a9b) + val colorCoreNeutral400 = Color(0xffb0b6b7) + val colorCoreNeutral300 = Color(0xffc8cccc) + val colorCoreNeutral200 = Color(0xffdee1e1) + val colorCoreNeutral100 = Color(0xfff3f4f4) + val colorCoreNeutral0 = Color(0xffffffff) + val colorCoreOrange1100 = Color(0xff2d130e) + val colorCoreOrange1000 = Color(0xff601700) + val colorCoreOrange900 = Color(0xff962c0b) + val colorCoreOrange800 = Color(0xffce5511) + val colorCoreOrange700 = Color(0xffed7024) + val colorCoreOrange600 = Color(0xfff57d33) + val colorCoreOrange500 = Color(0xfffc8943) + val colorCoreOrange400 = Color(0xffff9c5d) + val colorCoreOrange300 = Color(0xffffb180) + val colorCoreOrange200 = Color(0xffffc6a4) + val colorCoreOrange100 = Color(0xfffcdccc) + val colorCoreOrange0 = Color(0xffffede3) + val colorCoreRed1100 = Color(0xff2b1111) + val colorCoreRed1000 = Color(0xff6d1313) + val colorCoreRed900 = Color(0xff992222) + val colorCoreRed800 = Color(0xffc63434) + val colorCoreRed700 = Color(0xffdb3e3e) + val colorCoreRed600 = Color(0xffed4c42) + val colorCoreRed500 = Color(0xfff76054) + val colorCoreRed400 = Color(0xffff7f6e) + val colorCoreRed300 = Color(0xffff9c8f) + val colorCoreRed200 = Color(0xffffb8b1) + val colorCoreRed100 = Color(0xffffd5d2) + val colorCoreRed0 = Color(0xffffeae9) + val colorCorePink1100 = Color(0xff2b1721) + val colorCorePink1000 = Color(0xff561231) + val colorCorePink900 = Color(0xff931847) + val colorCorePink800 = Color(0xffb22f5b) + val colorCorePink700 = Color(0xffce3665) + val colorCorePink600 = Color(0xffe0447c) + val colorCorePink500 = Color(0xffef588b) + val colorCorePink400 = Color(0xffff76ae) + val colorCorePink300 = Color(0xffff95c1) + val colorCorePink200 = Color(0xffffb5d5) + val colorCorePink100 = Color(0xfffcdbeb) + val colorCorePink0 = Color(0xffffe9f3) + val colorCoreMagenta1100 = Color(0xff29192d) + val colorCoreMagenta1000 = Color(0xff451551) + val colorCoreMagenta900 = Color(0xff6c2277) + val colorCoreMagenta800 = Color(0xff8f3896) + val colorCoreMagenta700 = Color(0xffac44a8) + val colorCoreMagenta600 = Color(0xffc44eb9) + val colorCoreMagenta500 = Color(0xffdb61db) + val colorCoreMagenta400 = Color(0xfff282f5) + val colorCoreMagenta300 = Color(0xffedadf2) + val colorCoreMagenta200 = Color(0xfff4c4f7) + val colorCoreMagenta100 = Color(0xfff9e3fc) + val colorCoreMagenta0 = Color(0xfffef0ff) + val colorCorePurple1100 = Color(0xff1d1d38) + val colorCorePurple1000 = Color(0xff2d246b) + val colorCorePurple900 = Color(0xff483a9c) + val colorCorePurple800 = Color(0xff5e4eba) + val colorCorePurple700 = Color(0xff6f5ed3) + val colorCorePurple600 = Color(0xff816fea) + val colorCorePurple500 = Color(0xff9180f4) + val colorCorePurple400 = Color(0xffa193f2) + val colorCorePurple300 = Color(0xffc1c1f7) + val colorCorePurple200 = Color(0xffd8d7f9) + val colorCorePurple100 = Color(0xffeaeaf9) + val colorCorePurple0 = Color(0xfff2f2f9) + val colorCoreBlue1100 = Color(0xff002138) + val colorCoreBlue1000 = Color(0xff0a3960) + val colorCoreBlue900 = Color(0xff0c5689) + val colorCoreBlue800 = Color(0xff116daa) + val colorCoreBlue700 = Color(0xff2079c3) + val colorCoreBlue600 = Color(0xff2b87d3) + val colorCoreBlue500 = Color(0xff3896e3) + val colorCoreBlue400 = Color(0xff56adf5) + val colorCoreBlue300 = Color(0xffa1d2f8) + val colorCoreBlue200 = Color(0xffc7e4f9) + val colorCoreBlue100 = Color(0xffdcf2ff) + val colorCoreBlue0 = Color(0xffe9f8ff) + val colorCoreAqua1100 = Color(0xff002838) + val colorCoreAqua1000 = Color(0xff083d4f) + val colorCoreAqua900 = Color(0xff035e73) + val colorCoreAqua800 = Color(0xff0f6e84) + val colorCoreAqua700 = Color(0xff0b8599) + val colorCoreAqua600 = Color(0xff0797ae) + val colorCoreAqua500 = Color(0xff17b8ce) + val colorCoreAqua400 = Color(0xff33d6e2) + val colorCoreAqua300 = Color(0xff76e5e2) + val colorCoreAqua200 = Color(0xffa5f2f2) + val colorCoreAqua100 = Color(0xffc5f9f9) + val colorCoreAqua0 = Color(0xffd9fcfb) + val colorCoreTeal1100 = Color(0xff002528) + val colorCoreTeal1000 = Color(0xff083f3f) + val colorCoreTeal900 = Color(0xff026661) + val colorCoreTeal800 = Color(0xff067c7c) + val colorCoreTeal700 = Color(0xff0b968f) + val colorCoreTeal600 = Color(0xff00a99c) + val colorCoreTeal500 = Color(0xff08c4b2) + val colorCoreTeal400 = Color(0xff24e0c5) + val colorCoreTeal300 = Color(0xff7dead5) + val colorCoreTeal200 = Color(0xffb3f2e6) + val colorCoreTeal100 = Color(0xffcdf7ef) + val colorCoreTeal0 = Color(0xffe5f9f5) + val colorCoreGreen1100 = Color(0xff002b20) + val colorCoreGreen1000 = Color(0xff08422f) + val colorCoreGreen900 = Color(0xff006b40) + val colorCoreGreen800 = Color(0xff008b46) + val colorCoreGreen700 = Color(0xff0ca750) + val colorCoreGreen600 = Color(0xff2bb656) + val colorCoreGreen500 = Color(0xff59cb59) + val colorCoreGreen400 = Color(0xff75dd66) + val colorCoreGreen300 = Color(0xff98e58e) + val colorCoreGreen200 = Color(0xffc2f2bd) + val colorCoreGreen100 = Color(0xffd7f4d7) + val colorCoreGreen0 = Color(0xffebf9eb) + val colorFontSuccess = colorCoreGreen1000 + val colorFontWarning = colorCoreOrange1000 + val colorFontDanger = colorCoreRed1000 + val colorFontTertiary = colorCoreNeutral800 + val colorFontSecondary = colorCoreNeutral900 + val colorFontPrimary = colorCoreNeutral1100 + val colorBrandSecondary = colorCorePurple700 + val colorBrandPrimary = colorCoreAqua700 + val colorBorderPrimary = colorCoreNeutral300 + val colorBackgroundInfo = colorCoreBlue0 + val colorBackgroundSuccess = colorCoreGreen0 + val colorBackgroundWarning = colorCoreOrange0 + val colorBackgroundDanger = colorCoreRed0 + val colorBackgroundTertiary = colorCoreNeutral200 + val colorBackgroundSecondary = colorCoreNeutral100 + val colorBackgroundPrimary = colorCoreNeutral0 + val colorFontInteractiveDisabled = colorFontTertiary + val colorFontInteractiveActive = colorBrandSecondary + val colorFontInteractiveHover = colorBrandPrimary + val colorFontInteractive = colorBrandPrimary + val colorBackgroundDisabled = colorBackgroundTertiary +} +" +`; diff --git a/__integration__/__snapshots__/css.test.js.snap b/__integration__/__snapshots__/css.test.js.snap new file mode 100644 index 000000000..7733336e8 --- /dev/null +++ b/__integration__/__snapshots__/css.test.js.snap @@ -0,0 +1,529 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration css css/variables should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --breakpoint-xs: 304px; + --breakpoint-sm: 768px; + --breakpoint-md: calc(304px / 768px); + --color-background-primary: #ffffff; + --color-background-secondary: #f3f4f4; + --color-background-tertiary: #dee1e1; + --color-background-danger: #ffeae9; + --color-background-warning: #ffede3; + --color-background-success: #ebf9eb; + --color-background-info: #e9f8ff; + --color-background-disabled: #dee1e1; + --color-border-primary: #c8cccc; + --color-brand-primary: #0b8599; + --color-brand-secondary: #6f5ed3; + --color-core-green-0: #ebf9eb; + --color-core-green-100: #d7f4d7; + --color-core-green-200: #c2f2bd; + --color-core-green-300: #98e58e; + --color-core-green-400: #75dd66; + --color-core-green-500: #59cb59; + --color-core-green-600: #2bb656; + --color-core-green-700: #0ca750; + --color-core-green-800: #008b46; + --color-core-green-900: #006b40; + --color-core-green-1000: #08422f; + --color-core-green-1100: #002b20; + --color-core-teal-0: #e5f9f5; + --color-core-teal-100: #cdf7ef; + --color-core-teal-200: #b3f2e6; + --color-core-teal-300: #7dead5; + --color-core-teal-400: #24e0c5; + --color-core-teal-500: #08c4b2; + --color-core-teal-600: #00a99c; + --color-core-teal-700: #0b968f; + --color-core-teal-800: #067c7c; + --color-core-teal-900: #026661; + --color-core-teal-1000: #083f3f; + --color-core-teal-1100: #002528; + --color-core-aqua-0: #d9fcfb; + --color-core-aqua-100: #c5f9f9; + --color-core-aqua-200: #a5f2f2; + --color-core-aqua-300: #76e5e2; + --color-core-aqua-400: #33d6e2; + --color-core-aqua-500: #17b8ce; + --color-core-aqua-600: #0797ae; + --color-core-aqua-700: #0b8599; + --color-core-aqua-800: #0f6e84; + --color-core-aqua-900: #035e73; + --color-core-aqua-1000: #083d4f; + --color-core-aqua-1100: #002838; + --color-core-blue-0: #e9f8ff; + --color-core-blue-100: #dcf2ff; + --color-core-blue-200: #c7e4f9; + --color-core-blue-300: #a1d2f8; + --color-core-blue-400: #56adf5; + --color-core-blue-500: #3896e3; + --color-core-blue-600: #2b87d3; + --color-core-blue-700: #2079c3; + --color-core-blue-800: #116daa; + --color-core-blue-900: #0c5689; + --color-core-blue-1000: #0a3960; + --color-core-blue-1100: #002138; + --color-core-purple-0: #f2f2f9; + --color-core-purple-100: #eaeaf9; + --color-core-purple-200: #d8d7f9; + --color-core-purple-300: #c1c1f7; + --color-core-purple-400: #a193f2; + --color-core-purple-500: #9180f4; + --color-core-purple-600: #816fea; + --color-core-purple-700: #6f5ed3; + --color-core-purple-800: #5e4eba; + --color-core-purple-900: #483a9c; + --color-core-purple-1000: #2d246b; + --color-core-purple-1100: #1d1d38; + --color-core-magenta-0: #fef0ff; + --color-core-magenta-100: #f9e3fc; + --color-core-magenta-200: #f4c4f7; + --color-core-magenta-300: #edadf2; + --color-core-magenta-400: #f282f5; + --color-core-magenta-500: #db61db; + --color-core-magenta-600: #c44eb9; + --color-core-magenta-700: #ac44a8; + --color-core-magenta-800: #8f3896; + --color-core-magenta-900: #6c2277; + --color-core-magenta-1000: #451551; + --color-core-magenta-1100: #29192d; + --color-core-pink-0: #ffe9f3; + --color-core-pink-100: #fcdbeb; + --color-core-pink-200: #ffb5d5; + --color-core-pink-300: #ff95c1; + --color-core-pink-400: #ff76ae; + --color-core-pink-500: #ef588b; + --color-core-pink-600: #e0447c; + --color-core-pink-700: #ce3665; + --color-core-pink-800: #b22f5b; + --color-core-pink-900: #931847; + --color-core-pink-1000: #561231; + --color-core-pink-1100: #2b1721; + --color-core-red-0: #ffeae9; + --color-core-red-100: #ffd5d2; + --color-core-red-200: #ffb8b1; + --color-core-red-300: #ff9c8f; + --color-core-red-400: #ff7f6e; + --color-core-red-500: #f76054; + --color-core-red-600: #ed4c42; + --color-core-red-700: #db3e3e; + --color-core-red-800: #c63434; + --color-core-red-900: #992222; + --color-core-red-1000: #6d1313; + --color-core-red-1100: #2b1111; + --color-core-orange-0: #ffede3; + --color-core-orange-100: #fcdccc; + --color-core-orange-200: #ffc6a4; + --color-core-orange-300: #ffb180; + --color-core-orange-400: #ff9c5d; + --color-core-orange-500: #fc8943; + --color-core-orange-600: #f57d33; + --color-core-orange-700: #ed7024; + --color-core-orange-800: #ce5511; + --color-core-orange-900: #962c0b; + --color-core-orange-1000: #601700; + --color-core-orange-1100: #2d130e; + --color-core-neutral-0: #ffffff; + --color-core-neutral-100: #f3f4f4; + --color-core-neutral-200: #dee1e1; + --color-core-neutral-300: #c8cccc; + --color-core-neutral-400: #b0b6b7; + --color-core-neutral-500: #929a9b; + --color-core-neutral-600: #6e797a; + --color-core-neutral-700: #515e5f; + --color-core-neutral-800: #364141; + --color-core-neutral-900: #273333; + --color-core-neutral-1000: #162020; + --color-core-neutral-1100: #040404; + --color-core-yellow-0: #fff8e2; + --color-core-yellow-100: #fdefcd; + --color-core-yellow-200: #ffe99a; + --color-core-yellow-300: #ffe16e; + --color-core-yellow-400: #ffd943; + --color-core-yellow-500: #ffcd1c; + --color-core-yellow-600: #ffbc00; + --color-core-yellow-700: #dd9903; + --color-core-yellow-800: #ba7506; + --color-core-yellow-900: #944c0c; + --color-core-yellow-1000: #542a00; + --color-core-yellow-1100: #2d1a05; + --color-font-primary: #040404; + --color-font-secondary: #273333; + --color-font-tertiary: #364141; + --color-font-interactive: #0b8599; + --color-font-interactive-hover: #0b8599; + --color-font-interactive-active: #6f5ed3; + --color-font-interactive-disabled: #364141; + --color-font-danger: #6d1313; + --color-font-warning: #601700; + --color-font-success: #08422f; + --size-border-radius-large: 30rem; + --size-font-small: 0.75rem; + --size-font-medium: 1rem; + --size-font-large: 1.5rem; + --size-font-xl: 2.25rem; + --size-padding-small: 0.5rem; + --size-padding-medium: 1rem; + --size-padding-large: 1rem; + --size-padding-xl: 1rem; +} +" +`; + +exports[`integration css css/variables with references should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --size-padding-xl: 1rem; + --size-padding-large: 1rem; + --size-padding-medium: 1rem; + --size-padding-small: 0.5rem; + --size-font-xl: 2.25rem; + --size-font-large: 1.5rem; + --size-font-medium: 1rem; + --size-font-small: 0.75rem; + --size-border-radius-large: 30rem; + --color-core-yellow-1100: #2d1a05; + --color-core-yellow-1000: #542a00; + --color-core-yellow-900: #944c0c; + --color-core-yellow-800: #ba7506; + --color-core-yellow-700: #dd9903; + --color-core-yellow-600: #ffbc00; + --color-core-yellow-500: #ffcd1c; + --color-core-yellow-400: #ffd943; + --color-core-yellow-300: #ffe16e; + --color-core-yellow-200: #ffe99a; + --color-core-yellow-100: #fdefcd; + --color-core-yellow-0: #fff8e2; + --color-core-neutral-1100: #040404; + --color-core-neutral-1000: #162020; + --color-core-neutral-900: #273333; + --color-core-neutral-800: #364141; + --color-core-neutral-700: #515e5f; + --color-core-neutral-600: #6e797a; + --color-core-neutral-500: #929a9b; + --color-core-neutral-400: #b0b6b7; + --color-core-neutral-300: #c8cccc; + --color-core-neutral-200: #dee1e1; + --color-core-neutral-100: #f3f4f4; + --color-core-neutral-0: #ffffff; + --color-core-orange-1100: #2d130e; + --color-core-orange-1000: #601700; + --color-core-orange-900: #962c0b; + --color-core-orange-800: #ce5511; + --color-core-orange-700: #ed7024; + --color-core-orange-600: #f57d33; + --color-core-orange-500: #fc8943; + --color-core-orange-400: #ff9c5d; + --color-core-orange-300: #ffb180; + --color-core-orange-200: #ffc6a4; + --color-core-orange-100: #fcdccc; + --color-core-orange-0: #ffede3; + --color-core-red-1100: #2b1111; + --color-core-red-1000: #6d1313; + --color-core-red-900: #992222; + --color-core-red-800: #c63434; + --color-core-red-700: #db3e3e; + --color-core-red-600: #ed4c42; + --color-core-red-500: #f76054; + --color-core-red-400: #ff7f6e; + --color-core-red-300: #ff9c8f; + --color-core-red-200: #ffb8b1; + --color-core-red-100: #ffd5d2; + --color-core-red-0: #ffeae9; + --color-core-pink-1100: #2b1721; + --color-core-pink-1000: #561231; + --color-core-pink-900: #931847; + --color-core-pink-800: #b22f5b; + --color-core-pink-700: #ce3665; + --color-core-pink-600: #e0447c; + --color-core-pink-500: #ef588b; + --color-core-pink-400: #ff76ae; + --color-core-pink-300: #ff95c1; + --color-core-pink-200: #ffb5d5; + --color-core-pink-100: #fcdbeb; + --color-core-pink-0: #ffe9f3; + --color-core-magenta-1100: #29192d; + --color-core-magenta-1000: #451551; + --color-core-magenta-900: #6c2277; + --color-core-magenta-800: #8f3896; + --color-core-magenta-700: #ac44a8; + --color-core-magenta-600: #c44eb9; + --color-core-magenta-500: #db61db; + --color-core-magenta-400: #f282f5; + --color-core-magenta-300: #edadf2; + --color-core-magenta-200: #f4c4f7; + --color-core-magenta-100: #f9e3fc; + --color-core-magenta-0: #fef0ff; + --color-core-purple-1100: #1d1d38; + --color-core-purple-1000: #2d246b; + --color-core-purple-900: #483a9c; + --color-core-purple-800: #5e4eba; + --color-core-purple-700: #6f5ed3; + --color-core-purple-600: #816fea; + --color-core-purple-500: #9180f4; + --color-core-purple-400: #a193f2; + --color-core-purple-300: #c1c1f7; + --color-core-purple-200: #d8d7f9; + --color-core-purple-100: #eaeaf9; + --color-core-purple-0: #f2f2f9; + --color-core-blue-1100: #002138; + --color-core-blue-1000: #0a3960; + --color-core-blue-900: #0c5689; + --color-core-blue-800: #116daa; + --color-core-blue-700: #2079c3; + --color-core-blue-600: #2b87d3; + --color-core-blue-500: #3896e3; + --color-core-blue-400: #56adf5; + --color-core-blue-300: #a1d2f8; + --color-core-blue-200: #c7e4f9; + --color-core-blue-100: #dcf2ff; + --color-core-blue-0: #e9f8ff; + --color-core-aqua-1100: #002838; + --color-core-aqua-1000: #083d4f; + --color-core-aqua-900: #035e73; + --color-core-aqua-800: #0f6e84; + --color-core-aqua-700: #0b8599; + --color-core-aqua-600: #0797ae; + --color-core-aqua-500: #17b8ce; + --color-core-aqua-400: #33d6e2; + --color-core-aqua-300: #76e5e2; + --color-core-aqua-200: #a5f2f2; + --color-core-aqua-100: #c5f9f9; + --color-core-aqua-0: #d9fcfb; + --color-core-teal-1100: #002528; + --color-core-teal-1000: #083f3f; + --color-core-teal-900: #026661; + --color-core-teal-800: #067c7c; + --color-core-teal-700: #0b968f; + --color-core-teal-600: #00a99c; + --color-core-teal-500: #08c4b2; + --color-core-teal-400: #24e0c5; + --color-core-teal-300: #7dead5; + --color-core-teal-200: #b3f2e6; + --color-core-teal-100: #cdf7ef; + --color-core-teal-0: #e5f9f5; + --color-core-green-1100: #002b20; + --color-core-green-1000: #08422f; + --color-core-green-900: #006b40; + --color-core-green-800: #008b46; + --color-core-green-700: #0ca750; + --color-core-green-600: #2bb656; + --color-core-green-500: #59cb59; + --color-core-green-400: #75dd66; + --color-core-green-300: #98e58e; + --color-core-green-200: #c2f2bd; + --color-core-green-100: #d7f4d7; + --color-core-green-0: #ebf9eb; + --breakpoint-sm: 768px; + --breakpoint-xs: 304px; + --color-font-success: var(--color-core-green-1000); + --color-font-warning: var(--color-core-orange-1000); + --color-font-danger: var(--color-core-red-1000); + --color-font-tertiary: var(--color-core-neutral-800); + --color-font-secondary: var(--color-core-neutral-900); + --color-font-primary: var(--color-core-neutral-1100); + --color-brand-secondary: var(--color-core-purple-700); + --color-brand-primary: var(--color-core-aqua-700); + --color-border-primary: var(--color-core-neutral-300); + --color-background-info: var(--color-core-blue-0); + --color-background-success: var(--color-core-green-0); + --color-background-warning: var(--color-core-orange-0); + --color-background-danger: var(--color-core-red-0); + --color-background-tertiary: var(--color-core-neutral-200); + --color-background-secondary: var(--color-core-neutral-100); + --color-background-primary: var(--color-core-neutral-0); + --breakpoint-md: calc(var(--breakpoint-xs) / var(--breakpoint-sm)); + --color-font-interactive-disabled: var(--color-font-tertiary); + --color-font-interactive-active: var(--color-brand-secondary); + --color-font-interactive-hover: var(--color-brand-primary); + --color-font-interactive: var(--color-brand-primary); + --color-background-disabled: var(--color-background-tertiary); +} +" +`; + +exports[`integration css css/variables with selector should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +.test { + --breakpoint-xs: 304px; + --breakpoint-sm: 768px; + --breakpoint-md: calc(304px / 768px); + --color-background-primary: #ffffff; + --color-background-secondary: #f3f4f4; + --color-background-tertiary: #dee1e1; + --color-background-danger: #ffeae9; + --color-background-warning: #ffede3; + --color-background-success: #ebf9eb; + --color-background-info: #e9f8ff; + --color-background-disabled: #dee1e1; + --color-border-primary: #c8cccc; + --color-brand-primary: #0b8599; + --color-brand-secondary: #6f5ed3; + --color-core-green-0: #ebf9eb; + --color-core-green-100: #d7f4d7; + --color-core-green-200: #c2f2bd; + --color-core-green-300: #98e58e; + --color-core-green-400: #75dd66; + --color-core-green-500: #59cb59; + --color-core-green-600: #2bb656; + --color-core-green-700: #0ca750; + --color-core-green-800: #008b46; + --color-core-green-900: #006b40; + --color-core-green-1000: #08422f; + --color-core-green-1100: #002b20; + --color-core-teal-0: #e5f9f5; + --color-core-teal-100: #cdf7ef; + --color-core-teal-200: #b3f2e6; + --color-core-teal-300: #7dead5; + --color-core-teal-400: #24e0c5; + --color-core-teal-500: #08c4b2; + --color-core-teal-600: #00a99c; + --color-core-teal-700: #0b968f; + --color-core-teal-800: #067c7c; + --color-core-teal-900: #026661; + --color-core-teal-1000: #083f3f; + --color-core-teal-1100: #002528; + --color-core-aqua-0: #d9fcfb; + --color-core-aqua-100: #c5f9f9; + --color-core-aqua-200: #a5f2f2; + --color-core-aqua-300: #76e5e2; + --color-core-aqua-400: #33d6e2; + --color-core-aqua-500: #17b8ce; + --color-core-aqua-600: #0797ae; + --color-core-aqua-700: #0b8599; + --color-core-aqua-800: #0f6e84; + --color-core-aqua-900: #035e73; + --color-core-aqua-1000: #083d4f; + --color-core-aqua-1100: #002838; + --color-core-blue-0: #e9f8ff; + --color-core-blue-100: #dcf2ff; + --color-core-blue-200: #c7e4f9; + --color-core-blue-300: #a1d2f8; + --color-core-blue-400: #56adf5; + --color-core-blue-500: #3896e3; + --color-core-blue-600: #2b87d3; + --color-core-blue-700: #2079c3; + --color-core-blue-800: #116daa; + --color-core-blue-900: #0c5689; + --color-core-blue-1000: #0a3960; + --color-core-blue-1100: #002138; + --color-core-purple-0: #f2f2f9; + --color-core-purple-100: #eaeaf9; + --color-core-purple-200: #d8d7f9; + --color-core-purple-300: #c1c1f7; + --color-core-purple-400: #a193f2; + --color-core-purple-500: #9180f4; + --color-core-purple-600: #816fea; + --color-core-purple-700: #6f5ed3; + --color-core-purple-800: #5e4eba; + --color-core-purple-900: #483a9c; + --color-core-purple-1000: #2d246b; + --color-core-purple-1100: #1d1d38; + --color-core-magenta-0: #fef0ff; + --color-core-magenta-100: #f9e3fc; + --color-core-magenta-200: #f4c4f7; + --color-core-magenta-300: #edadf2; + --color-core-magenta-400: #f282f5; + --color-core-magenta-500: #db61db; + --color-core-magenta-600: #c44eb9; + --color-core-magenta-700: #ac44a8; + --color-core-magenta-800: #8f3896; + --color-core-magenta-900: #6c2277; + --color-core-magenta-1000: #451551; + --color-core-magenta-1100: #29192d; + --color-core-pink-0: #ffe9f3; + --color-core-pink-100: #fcdbeb; + --color-core-pink-200: #ffb5d5; + --color-core-pink-300: #ff95c1; + --color-core-pink-400: #ff76ae; + --color-core-pink-500: #ef588b; + --color-core-pink-600: #e0447c; + --color-core-pink-700: #ce3665; + --color-core-pink-800: #b22f5b; + --color-core-pink-900: #931847; + --color-core-pink-1000: #561231; + --color-core-pink-1100: #2b1721; + --color-core-red-0: #ffeae9; + --color-core-red-100: #ffd5d2; + --color-core-red-200: #ffb8b1; + --color-core-red-300: #ff9c8f; + --color-core-red-400: #ff7f6e; + --color-core-red-500: #f76054; + --color-core-red-600: #ed4c42; + --color-core-red-700: #db3e3e; + --color-core-red-800: #c63434; + --color-core-red-900: #992222; + --color-core-red-1000: #6d1313; + --color-core-red-1100: #2b1111; + --color-core-orange-0: #ffede3; + --color-core-orange-100: #fcdccc; + --color-core-orange-200: #ffc6a4; + --color-core-orange-300: #ffb180; + --color-core-orange-400: #ff9c5d; + --color-core-orange-500: #fc8943; + --color-core-orange-600: #f57d33; + --color-core-orange-700: #ed7024; + --color-core-orange-800: #ce5511; + --color-core-orange-900: #962c0b; + --color-core-orange-1000: #601700; + --color-core-orange-1100: #2d130e; + --color-core-neutral-0: #ffffff; + --color-core-neutral-100: #f3f4f4; + --color-core-neutral-200: #dee1e1; + --color-core-neutral-300: #c8cccc; + --color-core-neutral-400: #b0b6b7; + --color-core-neutral-500: #929a9b; + --color-core-neutral-600: #6e797a; + --color-core-neutral-700: #515e5f; + --color-core-neutral-800: #364141; + --color-core-neutral-900: #273333; + --color-core-neutral-1000: #162020; + --color-core-neutral-1100: #040404; + --color-core-yellow-0: #fff8e2; + --color-core-yellow-100: #fdefcd; + --color-core-yellow-200: #ffe99a; + --color-core-yellow-300: #ffe16e; + --color-core-yellow-400: #ffd943; + --color-core-yellow-500: #ffcd1c; + --color-core-yellow-600: #ffbc00; + --color-core-yellow-700: #dd9903; + --color-core-yellow-800: #ba7506; + --color-core-yellow-900: #944c0c; + --color-core-yellow-1000: #542a00; + --color-core-yellow-1100: #2d1a05; + --color-font-primary: #040404; + --color-font-secondary: #273333; + --color-font-tertiary: #364141; + --color-font-interactive: #0b8599; + --color-font-interactive-hover: #0b8599; + --color-font-interactive-active: #6f5ed3; + --color-font-interactive-disabled: #364141; + --color-font-danger: #6d1313; + --color-font-warning: #601700; + --color-font-success: #08422f; + --size-border-radius-large: 30rem; + --size-font-small: 0.75rem; + --size-font-medium: 1rem; + --size-font-large: 1.5rem; + --size-font-xl: 2.25rem; + --size-padding-small: 0.5rem; + --size-padding-medium: 1rem; + --size-padding-large: 1rem; + --size-padding-xl: 1rem; +} +" +`; diff --git a/__integration__/__snapshots__/customFileHeader.test.js.snap b/__integration__/__snapshots__/customFileHeader.test.js.snap new file mode 100644 index 000000000..21ad10834 --- /dev/null +++ b/__integration__/__snapshots__/customFileHeader.test.js.snap @@ -0,0 +1,114 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration valid custom file headers file options config file header should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + * hello, world! + */ + +:root { + --color-red: #ff0000; +} +" +`; + +exports[`integration valid custom file headers file options inline file header should match snapshot 1`] = ` +"/** + * build version 1.0.0 + */ + +:root { + --color-red: #ff0000; +} +" +`; + +exports[`integration valid custom file headers file options registered file header should match snapshot 1`] = ` +"/** + * hello + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --color-red: #ff0000; +} +" +`; + +exports[`integration valid custom file headers platform options file header override should match snapshot 1`] = ` +"/** + * Header overridden + */ + +module.exports = { + \\"color\\": { + \\"red\\": { + \\"value\\": \\"#ff0000\\", + \\"original\\": { + \\"value\\": \\"#ff0000\\" + }, + \\"name\\": \\"ColorRed\\", + \\"attributes\\": { + \\"category\\": \\"color\\", + \\"type\\": \\"red\\" + }, + \\"path\\": [ + \\"color\\", + \\"red\\" + ] + } + } +};" +`; + +exports[`integration valid custom file headers platform options no file options should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + * hello, world! + */ + +module.exports = { + \\"color\\": { + \\"red\\": { + \\"value\\": \\"#ff0000\\", + \\"original\\": { + \\"value\\": \\"#ff0000\\" + }, + \\"name\\": \\"ColorRed\\", + \\"attributes\\": { + \\"category\\": \\"color\\", + \\"type\\": \\"red\\" + }, + \\"path\\": [ + \\"color\\", + \\"red\\" + ] + } + } +};" +`; + +exports[`integration valid custom file headers platform options showFileHeader should match snapshot 1`] = ` +"module.exports = { + \\"color\\": { + \\"red\\": { + \\"value\\": \\"#ff0000\\", + \\"original\\": { + \\"value\\": \\"#ff0000\\" + }, + \\"name\\": \\"ColorRed\\", + \\"attributes\\": { + \\"category\\": \\"color\\", + \\"type\\": \\"red\\" + }, + \\"path\\": [ + \\"color\\", + \\"red\\" + ] + } + } +};" +`; diff --git a/__integration__/__snapshots__/customFormats.test.js.snap b/__integration__/__snapshots__/customFormats.test.js.snap new file mode 100644 index 000000000..842a01f3d --- /dev/null +++ b/__integration__/__snapshots__/customFormats.test.js.snap @@ -0,0 +1,2567 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration custom formats inline custom with new args should match snapshot 1`] = ` +"{ + \\"dictionary\\": { + \\"properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"allProperties\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"tokens\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"allTokens\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"_properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + } + }, + \\"allProperties\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"platform\\": { + \\"transformGroup\\": \\"js\\", + \\"buildPath\\": \\"__integration__/build/\\", + \\"options\\": { + \\"otherOption\\": \\"platform option\\" + }, + \\"files\\": [ + { + \\"destination\\": \\"inlineCustomFormatWithOldArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + }, + { + \\"destination\\": \\"inlineCustomFormatWithNewArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + } + ], + \\"transforms\\": [ + { + \\"type\\": \\"attribute\\" + }, + { + \\"type\\": \\"name\\" + }, + { + \\"type\\": \\"value\\" + }, + { + \\"type\\": \\"value\\" + } + ], + \\"actions\\": [] + }, + \\"file\\": { + \\"options\\": { + \\"otherOption\\": \\"Test\\", + \\"showFileHeader\\": true + }, + \\"destination\\": \\"inlineCustomFormatWithNewArgs.json\\" + }, + \\"options\\": { + \\"otherOption\\": \\"Test\\", + \\"showFileHeader\\": true + } +}" +`; + +exports[`integration custom formats inline custom with old args should match snapshot 1`] = ` +"{ + \\"dictionary\\": { + \\"dictionary\\": { + \\"properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"allProperties\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"tokens\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"allTokens\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"_properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + } + }, + \\"allProperties\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"platform\\": { + \\"transformGroup\\": \\"js\\", + \\"buildPath\\": \\"__integration__/build/\\", + \\"options\\": { + \\"otherOption\\": \\"platform option\\" + }, + \\"files\\": [ + { + \\"destination\\": \\"inlineCustomFormatWithOldArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + }, + { + \\"destination\\": \\"inlineCustomFormatWithNewArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + } + ], + \\"transforms\\": [ + { + \\"type\\": \\"attribute\\" + }, + { + \\"type\\": \\"name\\" + }, + { + \\"type\\": \\"value\\" + }, + { + \\"type\\": \\"value\\" + } + ], + \\"actions\\": [] + }, + \\"file\\": { + \\"options\\": { + \\"otherOption\\": \\"Test\\", + \\"showFileHeader\\": true + }, + \\"destination\\": \\"inlineCustomFormatWithOldArgs.json\\" + }, + \\"options\\": { + \\"otherOption\\": \\"Test\\", + \\"showFileHeader\\": true + } + }, + \\"platform\\": { + \\"transformGroup\\": \\"js\\", + \\"buildPath\\": \\"__integration__/build/\\", + \\"options\\": { + \\"otherOption\\": \\"platform option\\" + }, + \\"files\\": [ + { + \\"destination\\": \\"inlineCustomFormatWithOldArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + }, + { + \\"destination\\": \\"inlineCustomFormatWithNewArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + } + ], + \\"transforms\\": [ + { + \\"type\\": \\"attribute\\" + }, + { + \\"type\\": \\"name\\" + }, + { + \\"type\\": \\"value\\" + }, + { + \\"type\\": \\"value\\" + } + ], + \\"actions\\": [] + }, + \\"file\\": { + \\"destination\\": \\"inlineCustomFormatWithOldArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + } +}" +`; + +exports[`integration custom formats register custom format with new args should match snapshot 1`] = ` +"{ + \\"dictionary\\": { + \\"properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"allProperties\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"tokens\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"allTokens\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"_properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + } + }, + \\"allProperties\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"platform\\": { + \\"transformGroup\\": \\"js\\", + \\"buildPath\\": \\"__integration__/build/\\", + \\"options\\": { + \\"otherOption\\": \\"platform option\\" + }, + \\"files\\": [ + { + \\"destination\\": \\"registerCustomFormatWithOldArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + }, + { + \\"destination\\": \\"registerCustomFormatWithNewArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + } + ], + \\"transforms\\": [ + { + \\"type\\": \\"attribute\\" + }, + { + \\"type\\": \\"name\\" + }, + { + \\"type\\": \\"value\\" + }, + { + \\"type\\": \\"value\\" + } + ], + \\"actions\\": [] + }, + \\"file\\": { + \\"options\\": { + \\"otherOption\\": \\"Test\\", + \\"showFileHeader\\": true + }, + \\"destination\\": \\"registerCustomFormatWithNewArgs.json\\" + }, + \\"options\\": { + \\"otherOption\\": \\"Test\\", + \\"showFileHeader\\": true + } +}" +`; + +exports[`integration custom formats register custom format with old args should match snapshot 1`] = ` +"{ + \\"dictionary\\": { + \\"dictionary\\": { + \\"properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"allProperties\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"tokens\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"allTokens\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"_properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + } + }, + \\"allProperties\\": [ + { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + ], + \\"properties\\": { + \\"size\\": { + \\"padding\\": { + \\"small\\": { + \\"value\\": \\"0.5rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 0.5 + }, + \\"name\\": \\"SizePaddingSmall\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"small\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"small\\" + ] + }, + \\"medium\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingMedium\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"medium\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"medium\\" + ] + }, + \\"large\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingLarge\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"large\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"large\\" + ] + }, + \\"xl\\": { + \\"value\\": \\"1rem\\", + \\"filePath\\": \\"__integration__/tokens/size/padding.json\\", + \\"isSource\\": true, + \\"original\\": { + \\"value\\": 1 + }, + \\"name\\": \\"SizePaddingXl\\", + \\"attributes\\": { + \\"category\\": \\"size\\", + \\"type\\": \\"padding\\", + \\"item\\": \\"xl\\" + }, + \\"path\\": [ + \\"size\\", + \\"padding\\", + \\"xl\\" + ] + } + } + } + }, + \\"platform\\": { + \\"transformGroup\\": \\"js\\", + \\"buildPath\\": \\"__integration__/build/\\", + \\"options\\": { + \\"otherOption\\": \\"platform option\\" + }, + \\"files\\": [ + { + \\"destination\\": \\"registerCustomFormatWithOldArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + }, + { + \\"destination\\": \\"registerCustomFormatWithNewArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + } + ], + \\"transforms\\": [ + { + \\"type\\": \\"attribute\\" + }, + { + \\"type\\": \\"name\\" + }, + { + \\"type\\": \\"value\\" + }, + { + \\"type\\": \\"value\\" + } + ], + \\"actions\\": [] + }, + \\"file\\": { + \\"options\\": { + \\"otherOption\\": \\"Test\\", + \\"showFileHeader\\": true + }, + \\"destination\\": \\"registerCustomFormatWithOldArgs.json\\" + }, + \\"options\\": { + \\"otherOption\\": \\"Test\\", + \\"showFileHeader\\": true + } + }, + \\"platform\\": { + \\"transformGroup\\": \\"js\\", + \\"buildPath\\": \\"__integration__/build/\\", + \\"options\\": { + \\"otherOption\\": \\"platform option\\" + }, + \\"files\\": [ + { + \\"destination\\": \\"registerCustomFormatWithOldArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + }, + { + \\"destination\\": \\"registerCustomFormatWithNewArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + } + ], + \\"transforms\\": [ + { + \\"type\\": \\"attribute\\" + }, + { + \\"type\\": \\"name\\" + }, + { + \\"type\\": \\"value\\" + }, + { + \\"type\\": \\"value\\" + } + ], + \\"actions\\": [] + }, + \\"file\\": { + \\"destination\\": \\"registerCustomFormatWithOldArgs.json\\", + \\"options\\": { + \\"showFileHeader\\": true, + \\"otherOption\\": \\"Test\\" + } + } +}" +`; diff --git a/__integration__/__snapshots__/flutter.test.js.snap b/__integration__/__snapshots__/flutter.test.js.snap new file mode 100644 index 000000000..bad987aaf --- /dev/null +++ b/__integration__/__snapshots__/flutter.test.js.snap @@ -0,0 +1,535 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration flutter flutter/class.dart separate should match snapshot 1`] = ` +" +// +// style_dictionary_color.dart +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + + +import 'dart:ui'; + +class StyleDictionaryColor { + StyleDictionaryColor._(); + + static const backgroundDanger = Color(0xFFFFEAE9); + static const backgroundDisabled = Color(0xFFDEE1E1); + static const backgroundInfo = Color(0xFFE9F8FF); + static const backgroundPrimary = Color(0xFFFFFFFF); + static const backgroundSecondary = Color(0xFFF3F4F4); + static const backgroundSuccess = Color(0xFFEBF9EB); + static const backgroundTertiary = Color(0xFFDEE1E1); + static const backgroundWarning = Color(0xFFFFEDE3); + static const borderPrimary = Color(0xFFC8CCCC); + static const brandPrimary = Color(0xFF0B8599); + static const brandSecondary = Color(0xFF6F5ED3); + static const coreAqua0 = Color(0xFFD9FCFB); + static const coreAqua100 = Color(0xFFC5F9F9); + static const coreAqua1000 = Color(0xFF083D4F); + static const coreAqua1100 = Color(0xFF002838); + static const coreAqua200 = Color(0xFFA5F2F2); + static const coreAqua300 = Color(0xFF76E5E2); + static const coreAqua400 = Color(0xFF33D6E2); + static const coreAqua500 = Color(0xFF17B8CE); + static const coreAqua600 = Color(0xFF0797AE); + static const coreAqua700 = Color(0xFF0B8599); + static const coreAqua800 = Color(0xFF0F6E84); + static const coreAqua900 = Color(0xFF035E73); + static const coreBlue0 = Color(0xFFE9F8FF); + static const coreBlue100 = Color(0xFFDCF2FF); + static const coreBlue1000 = Color(0xFF0A3960); + static const coreBlue1100 = Color(0xFF002138); + static const coreBlue200 = Color(0xFFC7E4F9); + static const coreBlue300 = Color(0xFFA1D2F8); + static const coreBlue400 = Color(0xFF56ADF5); + static const coreBlue500 = Color(0xFF3896E3); + static const coreBlue600 = Color(0xFF2B87D3); + static const coreBlue700 = Color(0xFF2079C3); + static const coreBlue800 = Color(0xFF116DAA); + static const coreBlue900 = Color(0xFF0C5689); + static const coreGreen0 = Color(0xFFEBF9EB); + static const coreGreen100 = Color(0xFFD7F4D7); + static const coreGreen1000 = Color(0xFF08422F); + static const coreGreen1100 = Color(0xFF002B20); + static const coreGreen200 = Color(0xFFC2F2BD); + static const coreGreen300 = Color(0xFF98E58E); + static const coreGreen400 = Color(0xFF75DD66); + static const coreGreen500 = Color(0xFF59CB59); + static const coreGreen600 = Color(0xFF2BB656); + static const coreGreen700 = Color(0xFF0CA750); + static const coreGreen800 = Color(0xFF008B46); + static const coreGreen900 = Color(0xFF006B40); + static const coreMagenta0 = Color(0xFFFEF0FF); + static const coreMagenta100 = Color(0xFFF9E3FC); + static const coreMagenta1000 = Color(0xFF451551); + static const coreMagenta1100 = Color(0xFF29192D); + static const coreMagenta200 = Color(0xFFF4C4F7); + static const coreMagenta300 = Color(0xFFEDADF2); + static const coreMagenta400 = Color(0xFFF282F5); + static const coreMagenta500 = Color(0xFFDB61DB); + static const coreMagenta600 = Color(0xFFC44EB9); + static const coreMagenta700 = Color(0xFFAC44A8); + static const coreMagenta800 = Color(0xFF8F3896); + static const coreMagenta900 = Color(0xFF6C2277); + static const coreNeutral0 = Color(0xFFFFFFFF); + static const coreNeutral100 = Color(0xFFF3F4F4); + static const coreNeutral1000 = Color(0xFF162020); + static const coreNeutral1100 = Color(0xFF040404); + static const coreNeutral200 = Color(0xFFDEE1E1); + static const coreNeutral300 = Color(0xFFC8CCCC); + static const coreNeutral400 = Color(0xFFB0B6B7); + static const coreNeutral500 = Color(0xFF929A9B); + static const coreNeutral600 = Color(0xFF6E797A); + static const coreNeutral700 = Color(0xFF515E5F); + static const coreNeutral800 = Color(0xFF364141); + static const coreNeutral900 = Color(0xFF273333); + static const coreOrange0 = Color(0xFFFFEDE3); + static const coreOrange100 = Color(0xFFFCDCCC); + static const coreOrange1000 = Color(0xFF601700); + static const coreOrange1100 = Color(0xFF2D130E); + static const coreOrange200 = Color(0xFFFFC6A4); + static const coreOrange300 = Color(0xFFFFB180); + static const coreOrange400 = Color(0xFFFF9C5D); + static const coreOrange500 = Color(0xFFFC8943); + static const coreOrange600 = Color(0xFFF57D33); + static const coreOrange700 = Color(0xFFED7024); + static const coreOrange800 = Color(0xFFCE5511); + static const coreOrange900 = Color(0xFF962C0B); + static const corePink0 = Color(0xFFFFE9F3); + static const corePink100 = Color(0xFFFCDBEB); + static const corePink1000 = Color(0xFF561231); + static const corePink1100 = Color(0xFF2B1721); + static const corePink200 = Color(0xFFFFB5D5); + static const corePink300 = Color(0xFFFF95C1); + static const corePink400 = Color(0xFFFF76AE); + static const corePink500 = Color(0xFFEF588B); + static const corePink600 = Color(0xFFE0447C); + static const corePink700 = Color(0xFFCE3665); + static const corePink800 = Color(0xFFB22F5B); + static const corePink900 = Color(0xFF931847); + static const corePurple0 = Color(0xFFF2F2F9); + static const corePurple100 = Color(0xFFEAEAF9); + static const corePurple1000 = Color(0xFF2D246B); + static const corePurple1100 = Color(0xFF1D1D38); + static const corePurple200 = Color(0xFFD8D7F9); + static const corePurple300 = Color(0xFFC1C1F7); + static const corePurple400 = Color(0xFFA193F2); + static const corePurple500 = Color(0xFF9180F4); + static const corePurple600 = Color(0xFF816FEA); + static const corePurple700 = Color(0xFF6F5ED3); + static const corePurple800 = Color(0xFF5E4EBA); + static const corePurple900 = Color(0xFF483A9C); + static const coreRed0 = Color(0xFFFFEAE9); + static const coreRed100 = Color(0xFFFFD5D2); + static const coreRed1000 = Color(0xFF6D1313); + static const coreRed1100 = Color(0xFF2B1111); + static const coreRed200 = Color(0xFFFFB8B1); + static const coreRed300 = Color(0xFFFF9C8F); + static const coreRed400 = Color(0xFFFF7F6E); + static const coreRed500 = Color(0xFFF76054); + static const coreRed600 = Color(0xFFED4C42); + static const coreRed700 = Color(0xFFDB3E3E); + static const coreRed800 = Color(0xFFC63434); + static const coreRed900 = Color(0xFF992222); + static const coreTeal0 = Color(0xFFE5F9F5); + static const coreTeal100 = Color(0xFFCDF7EF); + static const coreTeal1000 = Color(0xFF083F3F); + static const coreTeal1100 = Color(0xFF002528); + static const coreTeal200 = Color(0xFFB3F2E6); + static const coreTeal300 = Color(0xFF7DEAD5); + static const coreTeal400 = Color(0xFF24E0C5); + static const coreTeal500 = Color(0xFF08C4B2); + static const coreTeal600 = Color(0xFF00A99C); + static const coreTeal700 = Color(0xFF0B968F); + static const coreTeal800 = Color(0xFF067C7C); + static const coreTeal900 = Color(0xFF026661); + static const coreYellow0 = Color(0xFFFFF8E2); + static const coreYellow100 = Color(0xFFFDEFCD); + static const coreYellow1000 = Color(0xFF542A00); + static const coreYellow1100 = Color(0xFF2D1A05); + static const coreYellow200 = Color(0xFFFFE99A); + static const coreYellow300 = Color(0xFFFFE16E); + static const coreYellow400 = Color(0xFFFFD943); + static const coreYellow500 = Color(0xFFFFCD1C); + static const coreYellow600 = Color(0xFFFFBC00); + static const coreYellow700 = Color(0xFFDD9903); + static const coreYellow800 = Color(0xFFBA7506); + static const coreYellow900 = Color(0xFF944C0C); + static const fontDanger = Color(0xFF6D1313); + static const fontInteractive = Color(0xFF0B8599); + static const fontInteractiveActive = Color(0xFF6F5ED3); + static const fontInteractiveDisabled = Color(0xFF364141); + static const fontInteractiveHover = Color(0xFF0B8599); + static const fontPrimary = Color(0xFF040404); + static const fontSecondary = Color(0xFF273333); + static const fontSuccess = Color(0xFF08422F); + static const fontTertiary = Color(0xFF364141); + static const fontWarning = Color(0xFF601700); +}" +`; + +exports[`integration flutter flutter/class.dart should match snapshot 1`] = ` +" +// +// style_dictionary.dart +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + + +import 'dart:ui'; + +class StyleDictionary { + StyleDictionary._(); + + static const colorBackgroundDanger = Color(0xFFFFEAE9); + static const colorBackgroundDisabled = Color(0xFFDEE1E1); + static const colorBackgroundInfo = Color(0xFFE9F8FF); + static const colorBackgroundPrimary = Color(0xFFFFFFFF); + static const colorBackgroundSecondary = Color(0xFFF3F4F4); + static const colorBackgroundSuccess = Color(0xFFEBF9EB); + static const colorBackgroundTertiary = Color(0xFFDEE1E1); + static const colorBackgroundWarning = Color(0xFFFFEDE3); + static const colorBorderPrimary = Color(0xFFC8CCCC); + static const colorBrandPrimary = Color(0xFF0B8599); + static const colorBrandSecondary = Color(0xFF6F5ED3); + static const colorCoreAqua0 = Color(0xFFD9FCFB); + static const colorCoreAqua100 = Color(0xFFC5F9F9); + static const colorCoreAqua1000 = Color(0xFF083D4F); + static const colorCoreAqua1100 = Color(0xFF002838); + static const colorCoreAqua200 = Color(0xFFA5F2F2); + static const colorCoreAqua300 = Color(0xFF76E5E2); + static const colorCoreAqua400 = Color(0xFF33D6E2); + static const colorCoreAqua500 = Color(0xFF17B8CE); + static const colorCoreAqua600 = Color(0xFF0797AE); + static const colorCoreAqua700 = Color(0xFF0B8599); + static const colorCoreAqua800 = Color(0xFF0F6E84); + static const colorCoreAqua900 = Color(0xFF035E73); + static const colorCoreBlue0 = Color(0xFFE9F8FF); + static const colorCoreBlue100 = Color(0xFFDCF2FF); + static const colorCoreBlue1000 = Color(0xFF0A3960); + static const colorCoreBlue1100 = Color(0xFF002138); + static const colorCoreBlue200 = Color(0xFFC7E4F9); + static const colorCoreBlue300 = Color(0xFFA1D2F8); + static const colorCoreBlue400 = Color(0xFF56ADF5); + static const colorCoreBlue500 = Color(0xFF3896E3); + static const colorCoreBlue600 = Color(0xFF2B87D3); + static const colorCoreBlue700 = Color(0xFF2079C3); + static const colorCoreBlue800 = Color(0xFF116DAA); + static const colorCoreBlue900 = Color(0xFF0C5689); + static const colorCoreGreen0 = Color(0xFFEBF9EB); + static const colorCoreGreen100 = Color(0xFFD7F4D7); + static const colorCoreGreen1000 = Color(0xFF08422F); + static const colorCoreGreen1100 = Color(0xFF002B20); + static const colorCoreGreen200 = Color(0xFFC2F2BD); + static const colorCoreGreen300 = Color(0xFF98E58E); + static const colorCoreGreen400 = Color(0xFF75DD66); + static const colorCoreGreen500 = Color(0xFF59CB59); + static const colorCoreGreen600 = Color(0xFF2BB656); + static const colorCoreGreen700 = Color(0xFF0CA750); + static const colorCoreGreen800 = Color(0xFF008B46); + static const colorCoreGreen900 = Color(0xFF006B40); + static const colorCoreMagenta0 = Color(0xFFFEF0FF); + static const colorCoreMagenta100 = Color(0xFFF9E3FC); + static const colorCoreMagenta1000 = Color(0xFF451551); + static const colorCoreMagenta1100 = Color(0xFF29192D); + static const colorCoreMagenta200 = Color(0xFFF4C4F7); + static const colorCoreMagenta300 = Color(0xFFEDADF2); + static const colorCoreMagenta400 = Color(0xFFF282F5); + static const colorCoreMagenta500 = Color(0xFFDB61DB); + static const colorCoreMagenta600 = Color(0xFFC44EB9); + static const colorCoreMagenta700 = Color(0xFFAC44A8); + static const colorCoreMagenta800 = Color(0xFF8F3896); + static const colorCoreMagenta900 = Color(0xFF6C2277); + static const colorCoreNeutral0 = Color(0xFFFFFFFF); + static const colorCoreNeutral100 = Color(0xFFF3F4F4); + static const colorCoreNeutral1000 = Color(0xFF162020); + static const colorCoreNeutral1100 = Color(0xFF040404); + static const colorCoreNeutral200 = Color(0xFFDEE1E1); + static const colorCoreNeutral300 = Color(0xFFC8CCCC); + static const colorCoreNeutral400 = Color(0xFFB0B6B7); + static const colorCoreNeutral500 = Color(0xFF929A9B); + static const colorCoreNeutral600 = Color(0xFF6E797A); + static const colorCoreNeutral700 = Color(0xFF515E5F); + static const colorCoreNeutral800 = Color(0xFF364141); + static const colorCoreNeutral900 = Color(0xFF273333); + static const colorCoreOrange0 = Color(0xFFFFEDE3); + static const colorCoreOrange100 = Color(0xFFFCDCCC); + static const colorCoreOrange1000 = Color(0xFF601700); + static const colorCoreOrange1100 = Color(0xFF2D130E); + static const colorCoreOrange200 = Color(0xFFFFC6A4); + static const colorCoreOrange300 = Color(0xFFFFB180); + static const colorCoreOrange400 = Color(0xFFFF9C5D); + static const colorCoreOrange500 = Color(0xFFFC8943); + static const colorCoreOrange600 = Color(0xFFF57D33); + static const colorCoreOrange700 = Color(0xFFED7024); + static const colorCoreOrange800 = Color(0xFFCE5511); + static const colorCoreOrange900 = Color(0xFF962C0B); + static const colorCorePink0 = Color(0xFFFFE9F3); + static const colorCorePink100 = Color(0xFFFCDBEB); + static const colorCorePink1000 = Color(0xFF561231); + static const colorCorePink1100 = Color(0xFF2B1721); + static const colorCorePink200 = Color(0xFFFFB5D5); + static const colorCorePink300 = Color(0xFFFF95C1); + static const colorCorePink400 = Color(0xFFFF76AE); + static const colorCorePink500 = Color(0xFFEF588B); + static const colorCorePink600 = Color(0xFFE0447C); + static const colorCorePink700 = Color(0xFFCE3665); + static const colorCorePink800 = Color(0xFFB22F5B); + static const colorCorePink900 = Color(0xFF931847); + static const colorCorePurple0 = Color(0xFFF2F2F9); + static const colorCorePurple100 = Color(0xFFEAEAF9); + static const colorCorePurple1000 = Color(0xFF2D246B); + static const colorCorePurple1100 = Color(0xFF1D1D38); + static const colorCorePurple200 = Color(0xFFD8D7F9); + static const colorCorePurple300 = Color(0xFFC1C1F7); + static const colorCorePurple400 = Color(0xFFA193F2); + static const colorCorePurple500 = Color(0xFF9180F4); + static const colorCorePurple600 = Color(0xFF816FEA); + static const colorCorePurple700 = Color(0xFF6F5ED3); + static const colorCorePurple800 = Color(0xFF5E4EBA); + static const colorCorePurple900 = Color(0xFF483A9C); + static const colorCoreRed0 = Color(0xFFFFEAE9); + static const colorCoreRed100 = Color(0xFFFFD5D2); + static const colorCoreRed1000 = Color(0xFF6D1313); + static const colorCoreRed1100 = Color(0xFF2B1111); + static const colorCoreRed200 = Color(0xFFFFB8B1); + static const colorCoreRed300 = Color(0xFFFF9C8F); + static const colorCoreRed400 = Color(0xFFFF7F6E); + static const colorCoreRed500 = Color(0xFFF76054); + static const colorCoreRed600 = Color(0xFFED4C42); + static const colorCoreRed700 = Color(0xFFDB3E3E); + static const colorCoreRed800 = Color(0xFFC63434); + static const colorCoreRed900 = Color(0xFF992222); + static const colorCoreTeal0 = Color(0xFFE5F9F5); + static const colorCoreTeal100 = Color(0xFFCDF7EF); + static const colorCoreTeal1000 = Color(0xFF083F3F); + static const colorCoreTeal1100 = Color(0xFF002528); + static const colorCoreTeal200 = Color(0xFFB3F2E6); + static const colorCoreTeal300 = Color(0xFF7DEAD5); + static const colorCoreTeal400 = Color(0xFF24E0C5); + static const colorCoreTeal500 = Color(0xFF08C4B2); + static const colorCoreTeal600 = Color(0xFF00A99C); + static const colorCoreTeal700 = Color(0xFF0B968F); + static const colorCoreTeal800 = Color(0xFF067C7C); + static const colorCoreTeal900 = Color(0xFF026661); + static const colorCoreYellow0 = Color(0xFFFFF8E2); + static const colorCoreYellow100 = Color(0xFFFDEFCD); + static const colorCoreYellow1000 = Color(0xFF542A00); + static const colorCoreYellow1100 = Color(0xFF2D1A05); + static const colorCoreYellow200 = Color(0xFFFFE99A); + static const colorCoreYellow300 = Color(0xFFFFE16E); + static const colorCoreYellow400 = Color(0xFFFFD943); + static const colorCoreYellow500 = Color(0xFFFFCD1C); + static const colorCoreYellow600 = Color(0xFFFFBC00); + static const colorCoreYellow700 = Color(0xFFDD9903); + static const colorCoreYellow800 = Color(0xFFBA7506); + static const colorCoreYellow900 = Color(0xFF944C0C); + static const colorFontDanger = Color(0xFF6D1313); + static const colorFontInteractive = Color(0xFF0B8599); + static const colorFontInteractiveActive = Color(0xFF6F5ED3); + static const colorFontInteractiveDisabled = Color(0xFF364141); + static const colorFontInteractiveHover = Color(0xFF0B8599); + static const colorFontPrimary = Color(0xFF040404); + static const colorFontSecondary = Color(0xFF273333); + static const colorFontSuccess = Color(0xFF08422F); + static const colorFontTertiary = Color(0xFF364141); + static const colorFontWarning = Color(0xFF601700); + static const sizeBorderRadiusLarge = 480.00; + static const sizeFontLarge = 24.00; + static const sizeFontMedium = 16.00; + static const sizeFontSmall = 12.00; + static const sizeFontXl = 36.00; + static const sizePaddingLarge = 16.00; + static const sizePaddingMedium = 16.00; + static const sizePaddingSmall = 8.00; + static const sizePaddingXl = 16.00; +}" +`; + +exports[`integration flutter flutter/class.dart with references should match snapshot 1`] = ` +" +// +// style_dictionary_with_references.dart +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + + +import 'dart:ui'; + +class StyleDictionary { + StyleDictionary._(); + + static const sizePaddingXl = 16.00; + static const sizePaddingLarge = 16.00; + static const sizePaddingMedium = 16.00; + static const sizePaddingSmall = 8.00; + static const sizeFontXl = 36.00; + static const sizeFontLarge = 24.00; + static const sizeFontMedium = 16.00; + static const sizeFontSmall = 12.00; + static const sizeBorderRadiusLarge = 480.00; + static const colorCoreYellow1100 = Color(0xFF2D1A05); + static const colorCoreYellow1000 = Color(0xFF542A00); + static const colorCoreYellow900 = Color(0xFF944C0C); + static const colorCoreYellow800 = Color(0xFFBA7506); + static const colorCoreYellow700 = Color(0xFFDD9903); + static const colorCoreYellow600 = Color(0xFFFFBC00); + static const colorCoreYellow500 = Color(0xFFFFCD1C); + static const colorCoreYellow400 = Color(0xFFFFD943); + static const colorCoreYellow300 = Color(0xFFFFE16E); + static const colorCoreYellow200 = Color(0xFFFFE99A); + static const colorCoreYellow100 = Color(0xFFFDEFCD); + static const colorCoreYellow0 = Color(0xFFFFF8E2); + static const colorCoreNeutral1100 = Color(0xFF040404); + static const colorCoreNeutral1000 = Color(0xFF162020); + static const colorCoreNeutral900 = Color(0xFF273333); + static const colorCoreNeutral800 = Color(0xFF364141); + static const colorCoreNeutral700 = Color(0xFF515E5F); + static const colorCoreNeutral600 = Color(0xFF6E797A); + static const colorCoreNeutral500 = Color(0xFF929A9B); + static const colorCoreNeutral400 = Color(0xFFB0B6B7); + static const colorCoreNeutral300 = Color(0xFFC8CCCC); + static const colorCoreNeutral200 = Color(0xFFDEE1E1); + static const colorCoreNeutral100 = Color(0xFFF3F4F4); + static const colorCoreNeutral0 = Color(0xFFFFFFFF); + static const colorCoreOrange1100 = Color(0xFF2D130E); + static const colorCoreOrange1000 = Color(0xFF601700); + static const colorCoreOrange900 = Color(0xFF962C0B); + static const colorCoreOrange800 = Color(0xFFCE5511); + static const colorCoreOrange700 = Color(0xFFED7024); + static const colorCoreOrange600 = Color(0xFFF57D33); + static const colorCoreOrange500 = Color(0xFFFC8943); + static const colorCoreOrange400 = Color(0xFFFF9C5D); + static const colorCoreOrange300 = Color(0xFFFFB180); + static const colorCoreOrange200 = Color(0xFFFFC6A4); + static const colorCoreOrange100 = Color(0xFFFCDCCC); + static const colorCoreOrange0 = Color(0xFFFFEDE3); + static const colorCoreRed1100 = Color(0xFF2B1111); + static const colorCoreRed1000 = Color(0xFF6D1313); + static const colorCoreRed900 = Color(0xFF992222); + static const colorCoreRed800 = Color(0xFFC63434); + static const colorCoreRed700 = Color(0xFFDB3E3E); + static const colorCoreRed600 = Color(0xFFED4C42); + static const colorCoreRed500 = Color(0xFFF76054); + static const colorCoreRed400 = Color(0xFFFF7F6E); + static const colorCoreRed300 = Color(0xFFFF9C8F); + static const colorCoreRed200 = Color(0xFFFFB8B1); + static const colorCoreRed100 = Color(0xFFFFD5D2); + static const colorCoreRed0 = Color(0xFFFFEAE9); + static const colorCorePink1100 = Color(0xFF2B1721); + static const colorCorePink1000 = Color(0xFF561231); + static const colorCorePink900 = Color(0xFF931847); + static const colorCorePink800 = Color(0xFFB22F5B); + static const colorCorePink700 = Color(0xFFCE3665); + static const colorCorePink600 = Color(0xFFE0447C); + static const colorCorePink500 = Color(0xFFEF588B); + static const colorCorePink400 = Color(0xFFFF76AE); + static const colorCorePink300 = Color(0xFFFF95C1); + static const colorCorePink200 = Color(0xFFFFB5D5); + static const colorCorePink100 = Color(0xFFFCDBEB); + static const colorCorePink0 = Color(0xFFFFE9F3); + static const colorCoreMagenta1100 = Color(0xFF29192D); + static const colorCoreMagenta1000 = Color(0xFF451551); + static const colorCoreMagenta900 = Color(0xFF6C2277); + static const colorCoreMagenta800 = Color(0xFF8F3896); + static const colorCoreMagenta700 = Color(0xFFAC44A8); + static const colorCoreMagenta600 = Color(0xFFC44EB9); + static const colorCoreMagenta500 = Color(0xFFDB61DB); + static const colorCoreMagenta400 = Color(0xFFF282F5); + static const colorCoreMagenta300 = Color(0xFFEDADF2); + static const colorCoreMagenta200 = Color(0xFFF4C4F7); + static const colorCoreMagenta100 = Color(0xFFF9E3FC); + static const colorCoreMagenta0 = Color(0xFFFEF0FF); + static const colorCorePurple1100 = Color(0xFF1D1D38); + static const colorCorePurple1000 = Color(0xFF2D246B); + static const colorCorePurple900 = Color(0xFF483A9C); + static const colorCorePurple800 = Color(0xFF5E4EBA); + static const colorCorePurple700 = Color(0xFF6F5ED3); + static const colorCorePurple600 = Color(0xFF816FEA); + static const colorCorePurple500 = Color(0xFF9180F4); + static const colorCorePurple400 = Color(0xFFA193F2); + static const colorCorePurple300 = Color(0xFFC1C1F7); + static const colorCorePurple200 = Color(0xFFD8D7F9); + static const colorCorePurple100 = Color(0xFFEAEAF9); + static const colorCorePurple0 = Color(0xFFF2F2F9); + static const colorCoreBlue1100 = Color(0xFF002138); + static const colorCoreBlue1000 = Color(0xFF0A3960); + static const colorCoreBlue900 = Color(0xFF0C5689); + static const colorCoreBlue800 = Color(0xFF116DAA); + static const colorCoreBlue700 = Color(0xFF2079C3); + static const colorCoreBlue600 = Color(0xFF2B87D3); + static const colorCoreBlue500 = Color(0xFF3896E3); + static const colorCoreBlue400 = Color(0xFF56ADF5); + static const colorCoreBlue300 = Color(0xFFA1D2F8); + static const colorCoreBlue200 = Color(0xFFC7E4F9); + static const colorCoreBlue100 = Color(0xFFDCF2FF); + static const colorCoreBlue0 = Color(0xFFE9F8FF); + static const colorCoreAqua1100 = Color(0xFF002838); + static const colorCoreAqua1000 = Color(0xFF083D4F); + static const colorCoreAqua900 = Color(0xFF035E73); + static const colorCoreAqua800 = Color(0xFF0F6E84); + static const colorCoreAqua700 = Color(0xFF0B8599); + static const colorCoreAqua600 = Color(0xFF0797AE); + static const colorCoreAqua500 = Color(0xFF17B8CE); + static const colorCoreAqua400 = Color(0xFF33D6E2); + static const colorCoreAqua300 = Color(0xFF76E5E2); + static const colorCoreAqua200 = Color(0xFFA5F2F2); + static const colorCoreAqua100 = Color(0xFFC5F9F9); + static const colorCoreAqua0 = Color(0xFFD9FCFB); + static const colorCoreTeal1100 = Color(0xFF002528); + static const colorCoreTeal1000 = Color(0xFF083F3F); + static const colorCoreTeal900 = Color(0xFF026661); + static const colorCoreTeal800 = Color(0xFF067C7C); + static const colorCoreTeal700 = Color(0xFF0B968F); + static const colorCoreTeal600 = Color(0xFF00A99C); + static const colorCoreTeal500 = Color(0xFF08C4B2); + static const colorCoreTeal400 = Color(0xFF24E0C5); + static const colorCoreTeal300 = Color(0xFF7DEAD5); + static const colorCoreTeal200 = Color(0xFFB3F2E6); + static const colorCoreTeal100 = Color(0xFFCDF7EF); + static const colorCoreTeal0 = Color(0xFFE5F9F5); + static const colorCoreGreen1100 = Color(0xFF002B20); + static const colorCoreGreen1000 = Color(0xFF08422F); + static const colorCoreGreen900 = Color(0xFF006B40); + static const colorCoreGreen800 = Color(0xFF008B46); + static const colorCoreGreen700 = Color(0xFF0CA750); + static const colorCoreGreen600 = Color(0xFF2BB656); + static const colorCoreGreen500 = Color(0xFF59CB59); + static const colorCoreGreen400 = Color(0xFF75DD66); + static const colorCoreGreen300 = Color(0xFF98E58E); + static const colorCoreGreen200 = Color(0xFFC2F2BD); + static const colorCoreGreen100 = Color(0xFFD7F4D7); + static const colorCoreGreen0 = Color(0xFFEBF9EB); + static const colorFontSuccess = colorCoreGreen1000; + static const colorFontWarning = colorCoreOrange1000; + static const colorFontDanger = colorCoreRed1000; + static const colorFontTertiary = colorCoreNeutral800; + static const colorFontSecondary = colorCoreNeutral900; + static const colorFontPrimary = colorCoreNeutral1100; + static const colorBrandSecondary = colorCorePurple700; + static const colorBrandPrimary = colorCoreAqua700; + static const colorBorderPrimary = colorCoreNeutral300; + static const colorBackgroundInfo = colorCoreBlue0; + static const colorBackgroundSuccess = colorCoreGreen0; + static const colorBackgroundWarning = colorCoreOrange0; + static const colorBackgroundDanger = colorCoreRed0; + static const colorBackgroundTertiary = colorCoreNeutral200; + static const colorBackgroundSecondary = colorCoreNeutral100; + static const colorBackgroundPrimary = colorCoreNeutral0; + static const colorFontInteractiveDisabled = colorFontTertiary; + static const colorFontInteractiveActive = colorBrandSecondary; + static const colorFontInteractiveHover = colorBrandPrimary; + static const colorFontInteractive = colorBrandPrimary; + static const colorBackgroundDisabled = colorBackgroundTertiary; +}" +`; diff --git a/__integration__/__snapshots__/iOSObjectiveC.test.js.snap b/__integration__/__snapshots__/iOSObjectiveC.test.js.snap new file mode 100644 index 000000000..2b1d7a3d3 --- /dev/null +++ b/__integration__/__snapshots__/iOSObjectiveC.test.js.snap @@ -0,0 +1,1975 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration ios objective-c ios/color.h should match snapshot 1`] = ` +" +// +// color.h +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +#import + +typedef NS_ENUM(NSInteger, StyleDictionaryColorName) { +ColorBackgroundPrimary, +ColorBackgroundSecondary, +ColorBackgroundTertiary, +ColorBackgroundDanger, +ColorBackgroundWarning, +ColorBackgroundSuccess, +ColorBackgroundInfo, +ColorBackgroundDisabled, +ColorBorderPrimary, +ColorBrandPrimary, +ColorBrandSecondary, +ColorCoreGreen0, +ColorCoreGreen100, +ColorCoreGreen200, +ColorCoreGreen300, +ColorCoreGreen400, +ColorCoreGreen500, +ColorCoreGreen600, +ColorCoreGreen700, +ColorCoreGreen800, +ColorCoreGreen900, +ColorCoreGreen1000, +ColorCoreGreen1100, +ColorCoreTeal0, +ColorCoreTeal100, +ColorCoreTeal200, +ColorCoreTeal300, +ColorCoreTeal400, +ColorCoreTeal500, +ColorCoreTeal600, +ColorCoreTeal700, +ColorCoreTeal800, +ColorCoreTeal900, +ColorCoreTeal1000, +ColorCoreTeal1100, +ColorCoreAqua0, +ColorCoreAqua100, +ColorCoreAqua200, +ColorCoreAqua300, +ColorCoreAqua400, +ColorCoreAqua500, +ColorCoreAqua600, +ColorCoreAqua700, +ColorCoreAqua800, +ColorCoreAqua900, +ColorCoreAqua1000, +ColorCoreAqua1100, +ColorCoreBlue0, +ColorCoreBlue100, +ColorCoreBlue200, +ColorCoreBlue300, +ColorCoreBlue400, +ColorCoreBlue500, +ColorCoreBlue600, +ColorCoreBlue700, +ColorCoreBlue800, +ColorCoreBlue900, +ColorCoreBlue1000, +ColorCoreBlue1100, +ColorCorePurple0, +ColorCorePurple100, +ColorCorePurple200, +ColorCorePurple300, +ColorCorePurple400, +ColorCorePurple500, +ColorCorePurple600, +ColorCorePurple700, +ColorCorePurple800, +ColorCorePurple900, +ColorCorePurple1000, +ColorCorePurple1100, +ColorCoreMagenta0, +ColorCoreMagenta100, +ColorCoreMagenta200, +ColorCoreMagenta300, +ColorCoreMagenta400, +ColorCoreMagenta500, +ColorCoreMagenta600, +ColorCoreMagenta700, +ColorCoreMagenta800, +ColorCoreMagenta900, +ColorCoreMagenta1000, +ColorCoreMagenta1100, +ColorCorePink0, +ColorCorePink100, +ColorCorePink200, +ColorCorePink300, +ColorCorePink400, +ColorCorePink500, +ColorCorePink600, +ColorCorePink700, +ColorCorePink800, +ColorCorePink900, +ColorCorePink1000, +ColorCorePink1100, +ColorCoreRed0, +ColorCoreRed100, +ColorCoreRed200, +ColorCoreRed300, +ColorCoreRed400, +ColorCoreRed500, +ColorCoreRed600, +ColorCoreRed700, +ColorCoreRed800, +ColorCoreRed900, +ColorCoreRed1000, +ColorCoreRed1100, +ColorCoreOrange0, +ColorCoreOrange100, +ColorCoreOrange200, +ColorCoreOrange300, +ColorCoreOrange400, +ColorCoreOrange500, +ColorCoreOrange600, +ColorCoreOrange700, +ColorCoreOrange800, +ColorCoreOrange900, +ColorCoreOrange1000, +ColorCoreOrange1100, +ColorCoreNeutral0, +ColorCoreNeutral100, +ColorCoreNeutral200, +ColorCoreNeutral300, +ColorCoreNeutral400, +ColorCoreNeutral500, +ColorCoreNeutral600, +ColorCoreNeutral700, +ColorCoreNeutral800, +ColorCoreNeutral900, +ColorCoreNeutral1000, +ColorCoreNeutral1100, +ColorCoreYellow0, +ColorCoreYellow100, +ColorCoreYellow200, +ColorCoreYellow300, +ColorCoreYellow400, +ColorCoreYellow500, +ColorCoreYellow600, +ColorCoreYellow700, +ColorCoreYellow800, +ColorCoreYellow900, +ColorCoreYellow1000, +ColorCoreYellow1100, +ColorFontPrimary, +ColorFontSecondary, +ColorFontTertiary, +ColorFontInteractive, +ColorFontInteractiveHover, +ColorFontInteractiveActive, +ColorFontInteractiveDisabled, +ColorFontDanger, +ColorFontWarning, +ColorFontSuccess +}; + +@interface StyleDictionaryColor : NSObject ++ (NSArray *)values; ++ (UIColor *)color:(StyleDictionaryColorName)color; +@end +" +`; + +exports[`integration ios objective-c ios/color.m should match snapshot 1`] = ` +" +// +// color.m +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +#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:1.000f green:1.000f blue:1.000f alpha:1.000f], +[UIColor colorWithRed:0.953f green:0.957f blue:0.957f alpha:1.000f], +[UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.918f blue:0.914f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.929f blue:0.890f alpha:1.000f], +[UIColor colorWithRed:0.922f green:0.976f blue:0.922f alpha:1.000f], +[UIColor colorWithRed:0.914f green:0.973f blue:1.000f alpha:1.000f], +[UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f], +[UIColor colorWithRed:0.784f green:0.800f blue:0.800f alpha:1.000f], +[UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f], +[UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f], +[UIColor colorWithRed:0.922f green:0.976f blue:0.922f alpha:1.000f], +[UIColor colorWithRed:0.843f green:0.957f blue:0.843f alpha:1.000f], +[UIColor colorWithRed:0.761f green:0.949f blue:0.741f alpha:1.000f], +[UIColor colorWithRed:0.596f green:0.898f blue:0.557f alpha:1.000f], +[UIColor colorWithRed:0.459f green:0.867f blue:0.400f alpha:1.000f], +[UIColor colorWithRed:0.349f green:0.796f blue:0.349f alpha:1.000f], +[UIColor colorWithRed:0.169f green:0.714f blue:0.337f alpha:1.000f], +[UIColor colorWithRed:0.047f green:0.655f blue:0.314f alpha:1.000f], +[UIColor colorWithRed:0.000f green:0.545f blue:0.275f alpha:1.000f], +[UIColor colorWithRed:0.000f green:0.420f blue:0.251f alpha:1.000f], +[UIColor colorWithRed:0.031f green:0.259f blue:0.184f alpha:1.000f], +[UIColor colorWithRed:0.000f green:0.169f blue:0.125f alpha:1.000f], +[UIColor colorWithRed:0.898f green:0.976f blue:0.961f alpha:1.000f], +[UIColor colorWithRed:0.804f green:0.969f blue:0.937f alpha:1.000f], +[UIColor colorWithRed:0.702f green:0.949f blue:0.902f alpha:1.000f], +[UIColor colorWithRed:0.490f green:0.918f blue:0.835f alpha:1.000f], +[UIColor colorWithRed:0.141f green:0.878f blue:0.773f alpha:1.000f], +[UIColor colorWithRed:0.031f green:0.769f blue:0.698f alpha:1.000f], +[UIColor colorWithRed:0.000f green:0.663f blue:0.612f alpha:1.000f], +[UIColor colorWithRed:0.043f green:0.588f blue:0.561f alpha:1.000f], +[UIColor colorWithRed:0.024f green:0.486f blue:0.486f alpha:1.000f], +[UIColor colorWithRed:0.008f green:0.400f blue:0.380f alpha:1.000f], +[UIColor colorWithRed:0.031f green:0.247f blue:0.247f alpha:1.000f], +[UIColor colorWithRed:0.000f green:0.145f blue:0.157f alpha:1.000f], +[UIColor colorWithRed:0.851f green:0.988f blue:0.984f alpha:1.000f], +[UIColor colorWithRed:0.773f green:0.976f blue:0.976f alpha:1.000f], +[UIColor colorWithRed:0.647f green:0.949f blue:0.949f alpha:1.000f], +[UIColor colorWithRed:0.463f green:0.898f blue:0.886f alpha:1.000f], +[UIColor colorWithRed:0.200f green:0.839f blue:0.886f alpha:1.000f], +[UIColor colorWithRed:0.090f green:0.722f blue:0.808f alpha:1.000f], +[UIColor colorWithRed:0.027f green:0.592f blue:0.682f alpha:1.000f], +[UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f], +[UIColor colorWithRed:0.059f green:0.431f blue:0.518f alpha:1.000f], +[UIColor colorWithRed:0.012f green:0.369f blue:0.451f alpha:1.000f], +[UIColor colorWithRed:0.031f green:0.239f blue:0.310f alpha:1.000f], +[UIColor colorWithRed:0.000f green:0.157f blue:0.220f alpha:1.000f], +[UIColor colorWithRed:0.914f green:0.973f blue:1.000f alpha:1.000f], +[UIColor colorWithRed:0.863f green:0.949f blue:1.000f alpha:1.000f], +[UIColor colorWithRed:0.780f green:0.894f blue:0.976f alpha:1.000f], +[UIColor colorWithRed:0.631f green:0.824f blue:0.973f alpha:1.000f], +[UIColor colorWithRed:0.337f green:0.678f blue:0.961f alpha:1.000f], +[UIColor colorWithRed:0.220f green:0.588f blue:0.890f alpha:1.000f], +[UIColor colorWithRed:0.169f green:0.529f blue:0.827f alpha:1.000f], +[UIColor colorWithRed:0.125f green:0.475f blue:0.765f alpha:1.000f], +[UIColor colorWithRed:0.067f green:0.427f blue:0.667f alpha:1.000f], +[UIColor colorWithRed:0.047f green:0.337f blue:0.537f alpha:1.000f], +[UIColor colorWithRed:0.039f green:0.224f blue:0.376f alpha:1.000f], +[UIColor colorWithRed:0.000f green:0.129f blue:0.220f alpha:1.000f], +[UIColor colorWithRed:0.949f green:0.949f blue:0.976f alpha:1.000f], +[UIColor colorWithRed:0.918f green:0.918f blue:0.976f alpha:1.000f], +[UIColor colorWithRed:0.847f green:0.843f blue:0.976f alpha:1.000f], +[UIColor colorWithRed:0.757f green:0.757f blue:0.969f alpha:1.000f], +[UIColor colorWithRed:0.631f green:0.576f blue:0.949f alpha:1.000f], +[UIColor colorWithRed:0.569f green:0.502f blue:0.957f alpha:1.000f], +[UIColor colorWithRed:0.506f green:0.435f blue:0.918f alpha:1.000f], +[UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f], +[UIColor colorWithRed:0.369f green:0.306f blue:0.729f alpha:1.000f], +[UIColor colorWithRed:0.282f green:0.227f blue:0.612f alpha:1.000f], +[UIColor colorWithRed:0.176f green:0.141f blue:0.420f alpha:1.000f], +[UIColor colorWithRed:0.114f green:0.114f blue:0.220f alpha:1.000f], +[UIColor colorWithRed:0.996f green:0.941f blue:1.000f alpha:1.000f], +[UIColor colorWithRed:0.976f green:0.890f blue:0.988f alpha:1.000f], +[UIColor colorWithRed:0.957f green:0.769f blue:0.969f alpha:1.000f], +[UIColor colorWithRed:0.929f green:0.678f blue:0.949f alpha:1.000f], +[UIColor colorWithRed:0.949f green:0.510f blue:0.961f alpha:1.000f], +[UIColor colorWithRed:0.859f green:0.380f blue:0.859f alpha:1.000f], +[UIColor colorWithRed:0.769f green:0.306f blue:0.725f alpha:1.000f], +[UIColor colorWithRed:0.675f green:0.267f blue:0.659f alpha:1.000f], +[UIColor colorWithRed:0.561f green:0.220f blue:0.588f alpha:1.000f], +[UIColor colorWithRed:0.424f green:0.133f blue:0.467f alpha:1.000f], +[UIColor colorWithRed:0.271f green:0.082f blue:0.318f alpha:1.000f], +[UIColor colorWithRed:0.161f green:0.098f blue:0.176f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.914f blue:0.953f alpha:1.000f], +[UIColor colorWithRed:0.988f green:0.859f blue:0.922f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.710f blue:0.835f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.584f blue:0.757f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.463f blue:0.682f alpha:1.000f], +[UIColor colorWithRed:0.937f green:0.345f blue:0.545f alpha:1.000f], +[UIColor colorWithRed:0.878f green:0.267f blue:0.486f alpha:1.000f], +[UIColor colorWithRed:0.808f green:0.212f blue:0.396f alpha:1.000f], +[UIColor colorWithRed:0.698f green:0.184f blue:0.357f alpha:1.000f], +[UIColor colorWithRed:0.576f green:0.094f blue:0.278f alpha:1.000f], +[UIColor colorWithRed:0.337f green:0.071f blue:0.192f alpha:1.000f], +[UIColor colorWithRed:0.169f green:0.090f blue:0.129f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.918f blue:0.914f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.835f blue:0.824f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.722f blue:0.694f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.612f blue:0.561f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.498f blue:0.431f alpha:1.000f], +[UIColor colorWithRed:0.969f green:0.376f blue:0.329f alpha:1.000f], +[UIColor colorWithRed:0.929f green:0.298f blue:0.259f alpha:1.000f], +[UIColor colorWithRed:0.859f green:0.243f blue:0.243f alpha:1.000f], +[UIColor colorWithRed:0.776f green:0.204f blue:0.204f alpha:1.000f], +[UIColor colorWithRed:0.600f green:0.133f blue:0.133f alpha:1.000f], +[UIColor colorWithRed:0.427f green:0.075f blue:0.075f alpha:1.000f], +[UIColor colorWithRed:0.169f green:0.067f blue:0.067f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.929f blue:0.890f alpha:1.000f], +[UIColor colorWithRed:0.988f green:0.863f blue:0.800f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.776f blue:0.643f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.694f blue:0.502f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.612f blue:0.365f alpha:1.000f], +[UIColor colorWithRed:0.988f green:0.537f blue:0.263f alpha:1.000f], +[UIColor colorWithRed:0.961f green:0.490f blue:0.200f alpha:1.000f], +[UIColor colorWithRed:0.929f green:0.439f blue:0.141f alpha:1.000f], +[UIColor colorWithRed:0.808f green:0.333f blue:0.067f alpha:1.000f], +[UIColor colorWithRed:0.588f green:0.173f blue:0.043f alpha:1.000f], +[UIColor colorWithRed:0.376f green:0.090f blue:0.000f alpha:1.000f], +[UIColor colorWithRed:0.176f green:0.075f blue:0.055f alpha:1.000f], +[UIColor colorWithRed:1.000f green:1.000f blue:1.000f alpha:1.000f], +[UIColor colorWithRed:0.953f green:0.957f blue:0.957f alpha:1.000f], +[UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f], +[UIColor colorWithRed:0.784f green:0.800f blue:0.800f alpha:1.000f], +[UIColor colorWithRed:0.690f green:0.714f blue:0.718f alpha:1.000f], +[UIColor colorWithRed:0.573f green:0.604f blue:0.608f alpha:1.000f], +[UIColor colorWithRed:0.431f green:0.475f blue:0.478f alpha:1.000f], +[UIColor colorWithRed:0.318f green:0.369f blue:0.373f alpha:1.000f], +[UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f], +[UIColor colorWithRed:0.153f green:0.200f blue:0.200f alpha:1.000f], +[UIColor colorWithRed:0.086f green:0.125f blue:0.125f alpha:1.000f], +[UIColor colorWithRed:0.016f green:0.016f blue:0.016f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.973f blue:0.886f alpha:1.000f], +[UIColor colorWithRed:0.992f green:0.937f blue:0.804f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.914f blue:0.604f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.882f blue:0.431f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.851f blue:0.263f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.804f blue:0.110f alpha:1.000f], +[UIColor colorWithRed:1.000f green:0.737f blue:0.000f alpha:1.000f], +[UIColor colorWithRed:0.867f green:0.600f blue:0.012f alpha:1.000f], +[UIColor colorWithRed:0.729f green:0.459f blue:0.024f alpha:1.000f], +[UIColor colorWithRed:0.580f green:0.298f blue:0.047f alpha:1.000f], +[UIColor colorWithRed:0.329f green:0.165f blue:0.000f alpha:1.000f], +[UIColor colorWithRed:0.176f green:0.102f blue:0.020f alpha:1.000f], +[UIColor colorWithRed:0.016f green:0.016f blue:0.016f alpha:1.000f], +[UIColor colorWithRed:0.153f green:0.200f blue:0.200f alpha:1.000f], +[UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f], +[UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f], +[UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f], +[UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f], +[UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f], +[UIColor colorWithRed:0.427f green:0.075f blue:0.075f alpha:1.000f], +[UIColor colorWithRed:0.376f green:0.090f blue:0.000f alpha:1.000f], +[UIColor colorWithRed:0.031f green:0.259f blue:0.184f alpha:1.000f] + ]; + }); + + return colorArray; +} + +@end +" +`; + +exports[`integration ios objective-c ios/macros.h should match snapshot 1`] = ` +" +// +// macros.h +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +#import +#import + +#define ColorBackgroundPrimary [UIColor colorWithRed:1.000f green:1.000f blue:1.000f alpha:1.000f] +#define ColorBackgroundSecondary [UIColor colorWithRed:0.953f green:0.957f blue:0.957f alpha:1.000f] +#define ColorBackgroundTertiary [UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f] +#define ColorBackgroundDanger [UIColor colorWithRed:1.000f green:0.918f blue:0.914f alpha:1.000f] +#define ColorBackgroundWarning [UIColor colorWithRed:1.000f green:0.929f blue:0.890f alpha:1.000f] +#define ColorBackgroundSuccess [UIColor colorWithRed:0.922f green:0.976f blue:0.922f alpha:1.000f] +#define ColorBackgroundInfo [UIColor colorWithRed:0.914f green:0.973f blue:1.000f alpha:1.000f] +#define ColorBackgroundDisabled [UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f] +#define ColorBorderPrimary [UIColor colorWithRed:0.784f green:0.800f blue:0.800f alpha:1.000f] +#define ColorBrandPrimary [UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f] +#define ColorBrandSecondary [UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f] +#define ColorCoreGreen0 [UIColor colorWithRed:0.922f green:0.976f blue:0.922f alpha:1.000f] +#define ColorCoreGreen100 [UIColor colorWithRed:0.843f green:0.957f blue:0.843f alpha:1.000f] +#define ColorCoreGreen200 [UIColor colorWithRed:0.761f green:0.949f blue:0.741f alpha:1.000f] +#define ColorCoreGreen300 [UIColor colorWithRed:0.596f green:0.898f blue:0.557f alpha:1.000f] +#define ColorCoreGreen400 [UIColor colorWithRed:0.459f green:0.867f blue:0.400f alpha:1.000f] +#define ColorCoreGreen500 [UIColor colorWithRed:0.349f green:0.796f blue:0.349f alpha:1.000f] +#define ColorCoreGreen600 [UIColor colorWithRed:0.169f green:0.714f blue:0.337f alpha:1.000f] +#define ColorCoreGreen700 [UIColor colorWithRed:0.047f green:0.655f blue:0.314f alpha:1.000f] +#define ColorCoreGreen800 [UIColor colorWithRed:0.000f green:0.545f blue:0.275f alpha:1.000f] +#define ColorCoreGreen900 [UIColor colorWithRed:0.000f green:0.420f blue:0.251f alpha:1.000f] +#define ColorCoreGreen1000 [UIColor colorWithRed:0.031f green:0.259f blue:0.184f alpha:1.000f] +#define ColorCoreGreen1100 [UIColor colorWithRed:0.000f green:0.169f blue:0.125f alpha:1.000f] +#define ColorCoreTeal0 [UIColor colorWithRed:0.898f green:0.976f blue:0.961f alpha:1.000f] +#define ColorCoreTeal100 [UIColor colorWithRed:0.804f green:0.969f blue:0.937f alpha:1.000f] +#define ColorCoreTeal200 [UIColor colorWithRed:0.702f green:0.949f blue:0.902f alpha:1.000f] +#define ColorCoreTeal300 [UIColor colorWithRed:0.490f green:0.918f blue:0.835f alpha:1.000f] +#define ColorCoreTeal400 [UIColor colorWithRed:0.141f green:0.878f blue:0.773f alpha:1.000f] +#define ColorCoreTeal500 [UIColor colorWithRed:0.031f green:0.769f blue:0.698f alpha:1.000f] +#define ColorCoreTeal600 [UIColor colorWithRed:0.000f green:0.663f blue:0.612f alpha:1.000f] +#define ColorCoreTeal700 [UIColor colorWithRed:0.043f green:0.588f blue:0.561f alpha:1.000f] +#define ColorCoreTeal800 [UIColor colorWithRed:0.024f green:0.486f blue:0.486f alpha:1.000f] +#define ColorCoreTeal900 [UIColor colorWithRed:0.008f green:0.400f blue:0.380f alpha:1.000f] +#define ColorCoreTeal1000 [UIColor colorWithRed:0.031f green:0.247f blue:0.247f alpha:1.000f] +#define ColorCoreTeal1100 [UIColor colorWithRed:0.000f green:0.145f blue:0.157f alpha:1.000f] +#define ColorCoreAqua0 [UIColor colorWithRed:0.851f green:0.988f blue:0.984f alpha:1.000f] +#define ColorCoreAqua100 [UIColor colorWithRed:0.773f green:0.976f blue:0.976f alpha:1.000f] +#define ColorCoreAqua200 [UIColor colorWithRed:0.647f green:0.949f blue:0.949f alpha:1.000f] +#define ColorCoreAqua300 [UIColor colorWithRed:0.463f green:0.898f blue:0.886f alpha:1.000f] +#define ColorCoreAqua400 [UIColor colorWithRed:0.200f green:0.839f blue:0.886f alpha:1.000f] +#define ColorCoreAqua500 [UIColor colorWithRed:0.090f green:0.722f blue:0.808f alpha:1.000f] +#define ColorCoreAqua600 [UIColor colorWithRed:0.027f green:0.592f blue:0.682f alpha:1.000f] +#define ColorCoreAqua700 [UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f] +#define ColorCoreAqua800 [UIColor colorWithRed:0.059f green:0.431f blue:0.518f alpha:1.000f] +#define ColorCoreAqua900 [UIColor colorWithRed:0.012f green:0.369f blue:0.451f alpha:1.000f] +#define ColorCoreAqua1000 [UIColor colorWithRed:0.031f green:0.239f blue:0.310f alpha:1.000f] +#define ColorCoreAqua1100 [UIColor colorWithRed:0.000f green:0.157f blue:0.220f alpha:1.000f] +#define ColorCoreBlue0 [UIColor colorWithRed:0.914f green:0.973f blue:1.000f alpha:1.000f] +#define ColorCoreBlue100 [UIColor colorWithRed:0.863f green:0.949f blue:1.000f alpha:1.000f] +#define ColorCoreBlue200 [UIColor colorWithRed:0.780f green:0.894f blue:0.976f alpha:1.000f] +#define ColorCoreBlue300 [UIColor colorWithRed:0.631f green:0.824f blue:0.973f alpha:1.000f] +#define ColorCoreBlue400 [UIColor colorWithRed:0.337f green:0.678f blue:0.961f alpha:1.000f] +#define ColorCoreBlue500 [UIColor colorWithRed:0.220f green:0.588f blue:0.890f alpha:1.000f] +#define ColorCoreBlue600 [UIColor colorWithRed:0.169f green:0.529f blue:0.827f alpha:1.000f] +#define ColorCoreBlue700 [UIColor colorWithRed:0.125f green:0.475f blue:0.765f alpha:1.000f] +#define ColorCoreBlue800 [UIColor colorWithRed:0.067f green:0.427f blue:0.667f alpha:1.000f] +#define ColorCoreBlue900 [UIColor colorWithRed:0.047f green:0.337f blue:0.537f alpha:1.000f] +#define ColorCoreBlue1000 [UIColor colorWithRed:0.039f green:0.224f blue:0.376f alpha:1.000f] +#define ColorCoreBlue1100 [UIColor colorWithRed:0.000f green:0.129f blue:0.220f alpha:1.000f] +#define ColorCorePurple0 [UIColor colorWithRed:0.949f green:0.949f blue:0.976f alpha:1.000f] +#define ColorCorePurple100 [UIColor colorWithRed:0.918f green:0.918f blue:0.976f alpha:1.000f] +#define ColorCorePurple200 [UIColor colorWithRed:0.847f green:0.843f blue:0.976f alpha:1.000f] +#define ColorCorePurple300 [UIColor colorWithRed:0.757f green:0.757f blue:0.969f alpha:1.000f] +#define ColorCorePurple400 [UIColor colorWithRed:0.631f green:0.576f blue:0.949f alpha:1.000f] +#define ColorCorePurple500 [UIColor colorWithRed:0.569f green:0.502f blue:0.957f alpha:1.000f] +#define ColorCorePurple600 [UIColor colorWithRed:0.506f green:0.435f blue:0.918f alpha:1.000f] +#define ColorCorePurple700 [UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f] +#define ColorCorePurple800 [UIColor colorWithRed:0.369f green:0.306f blue:0.729f alpha:1.000f] +#define ColorCorePurple900 [UIColor colorWithRed:0.282f green:0.227f blue:0.612f alpha:1.000f] +#define ColorCorePurple1000 [UIColor colorWithRed:0.176f green:0.141f blue:0.420f alpha:1.000f] +#define ColorCorePurple1100 [UIColor colorWithRed:0.114f green:0.114f blue:0.220f alpha:1.000f] +#define ColorCoreMagenta0 [UIColor colorWithRed:0.996f green:0.941f blue:1.000f alpha:1.000f] +#define ColorCoreMagenta100 [UIColor colorWithRed:0.976f green:0.890f blue:0.988f alpha:1.000f] +#define ColorCoreMagenta200 [UIColor colorWithRed:0.957f green:0.769f blue:0.969f alpha:1.000f] +#define ColorCoreMagenta300 [UIColor colorWithRed:0.929f green:0.678f blue:0.949f alpha:1.000f] +#define ColorCoreMagenta400 [UIColor colorWithRed:0.949f green:0.510f blue:0.961f alpha:1.000f] +#define ColorCoreMagenta500 [UIColor colorWithRed:0.859f green:0.380f blue:0.859f alpha:1.000f] +#define ColorCoreMagenta600 [UIColor colorWithRed:0.769f green:0.306f blue:0.725f alpha:1.000f] +#define ColorCoreMagenta700 [UIColor colorWithRed:0.675f green:0.267f blue:0.659f alpha:1.000f] +#define ColorCoreMagenta800 [UIColor colorWithRed:0.561f green:0.220f blue:0.588f alpha:1.000f] +#define ColorCoreMagenta900 [UIColor colorWithRed:0.424f green:0.133f blue:0.467f alpha:1.000f] +#define ColorCoreMagenta1000 [UIColor colorWithRed:0.271f green:0.082f blue:0.318f alpha:1.000f] +#define ColorCoreMagenta1100 [UIColor colorWithRed:0.161f green:0.098f blue:0.176f alpha:1.000f] +#define ColorCorePink0 [UIColor colorWithRed:1.000f green:0.914f blue:0.953f alpha:1.000f] +#define ColorCorePink100 [UIColor colorWithRed:0.988f green:0.859f blue:0.922f alpha:1.000f] +#define ColorCorePink200 [UIColor colorWithRed:1.000f green:0.710f blue:0.835f alpha:1.000f] +#define ColorCorePink300 [UIColor colorWithRed:1.000f green:0.584f blue:0.757f alpha:1.000f] +#define ColorCorePink400 [UIColor colorWithRed:1.000f green:0.463f blue:0.682f alpha:1.000f] +#define ColorCorePink500 [UIColor colorWithRed:0.937f green:0.345f blue:0.545f alpha:1.000f] +#define ColorCorePink600 [UIColor colorWithRed:0.878f green:0.267f blue:0.486f alpha:1.000f] +#define ColorCorePink700 [UIColor colorWithRed:0.808f green:0.212f blue:0.396f alpha:1.000f] +#define ColorCorePink800 [UIColor colorWithRed:0.698f green:0.184f blue:0.357f alpha:1.000f] +#define ColorCorePink900 [UIColor colorWithRed:0.576f green:0.094f blue:0.278f alpha:1.000f] +#define ColorCorePink1000 [UIColor colorWithRed:0.337f green:0.071f blue:0.192f alpha:1.000f] +#define ColorCorePink1100 [UIColor colorWithRed:0.169f green:0.090f blue:0.129f alpha:1.000f] +#define ColorCoreRed0 [UIColor colorWithRed:1.000f green:0.918f blue:0.914f alpha:1.000f] +#define ColorCoreRed100 [UIColor colorWithRed:1.000f green:0.835f blue:0.824f alpha:1.000f] +#define ColorCoreRed200 [UIColor colorWithRed:1.000f green:0.722f blue:0.694f alpha:1.000f] +#define ColorCoreRed300 [UIColor colorWithRed:1.000f green:0.612f blue:0.561f alpha:1.000f] +#define ColorCoreRed400 [UIColor colorWithRed:1.000f green:0.498f blue:0.431f alpha:1.000f] +#define ColorCoreRed500 [UIColor colorWithRed:0.969f green:0.376f blue:0.329f alpha:1.000f] +#define ColorCoreRed600 [UIColor colorWithRed:0.929f green:0.298f blue:0.259f alpha:1.000f] +#define ColorCoreRed700 [UIColor colorWithRed:0.859f green:0.243f blue:0.243f alpha:1.000f] +#define ColorCoreRed800 [UIColor colorWithRed:0.776f green:0.204f blue:0.204f alpha:1.000f] +#define ColorCoreRed900 [UIColor colorWithRed:0.600f green:0.133f blue:0.133f alpha:1.000f] +#define ColorCoreRed1000 [UIColor colorWithRed:0.427f green:0.075f blue:0.075f alpha:1.000f] +#define ColorCoreRed1100 [UIColor colorWithRed:0.169f green:0.067f blue:0.067f alpha:1.000f] +#define ColorCoreOrange0 [UIColor colorWithRed:1.000f green:0.929f blue:0.890f alpha:1.000f] +#define ColorCoreOrange100 [UIColor colorWithRed:0.988f green:0.863f blue:0.800f alpha:1.000f] +#define ColorCoreOrange200 [UIColor colorWithRed:1.000f green:0.776f blue:0.643f alpha:1.000f] +#define ColorCoreOrange300 [UIColor colorWithRed:1.000f green:0.694f blue:0.502f alpha:1.000f] +#define ColorCoreOrange400 [UIColor colorWithRed:1.000f green:0.612f blue:0.365f alpha:1.000f] +#define ColorCoreOrange500 [UIColor colorWithRed:0.988f green:0.537f blue:0.263f alpha:1.000f] +#define ColorCoreOrange600 [UIColor colorWithRed:0.961f green:0.490f blue:0.200f alpha:1.000f] +#define ColorCoreOrange700 [UIColor colorWithRed:0.929f green:0.439f blue:0.141f alpha:1.000f] +#define ColorCoreOrange800 [UIColor colorWithRed:0.808f green:0.333f blue:0.067f alpha:1.000f] +#define ColorCoreOrange900 [UIColor colorWithRed:0.588f green:0.173f blue:0.043f alpha:1.000f] +#define ColorCoreOrange1000 [UIColor colorWithRed:0.376f green:0.090f blue:0.000f alpha:1.000f] +#define ColorCoreOrange1100 [UIColor colorWithRed:0.176f green:0.075f blue:0.055f alpha:1.000f] +#define ColorCoreNeutral0 [UIColor colorWithRed:1.000f green:1.000f blue:1.000f alpha:1.000f] +#define ColorCoreNeutral100 [UIColor colorWithRed:0.953f green:0.957f blue:0.957f alpha:1.000f] +#define ColorCoreNeutral200 [UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f] +#define ColorCoreNeutral300 [UIColor colorWithRed:0.784f green:0.800f blue:0.800f alpha:1.000f] +#define ColorCoreNeutral400 [UIColor colorWithRed:0.690f green:0.714f blue:0.718f alpha:1.000f] +#define ColorCoreNeutral500 [UIColor colorWithRed:0.573f green:0.604f blue:0.608f alpha:1.000f] +#define ColorCoreNeutral600 [UIColor colorWithRed:0.431f green:0.475f blue:0.478f alpha:1.000f] +#define ColorCoreNeutral700 [UIColor colorWithRed:0.318f green:0.369f blue:0.373f alpha:1.000f] +#define ColorCoreNeutral800 [UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f] +#define ColorCoreNeutral900 [UIColor colorWithRed:0.153f green:0.200f blue:0.200f alpha:1.000f] +#define ColorCoreNeutral1000 [UIColor colorWithRed:0.086f green:0.125f blue:0.125f alpha:1.000f] +#define ColorCoreNeutral1100 [UIColor colorWithRed:0.016f green:0.016f blue:0.016f alpha:1.000f] +#define ColorCoreYellow0 [UIColor colorWithRed:1.000f green:0.973f blue:0.886f alpha:1.000f] +#define ColorCoreYellow100 [UIColor colorWithRed:0.992f green:0.937f blue:0.804f alpha:1.000f] +#define ColorCoreYellow200 [UIColor colorWithRed:1.000f green:0.914f blue:0.604f alpha:1.000f] +#define ColorCoreYellow300 [UIColor colorWithRed:1.000f green:0.882f blue:0.431f alpha:1.000f] +#define ColorCoreYellow400 [UIColor colorWithRed:1.000f green:0.851f blue:0.263f alpha:1.000f] +#define ColorCoreYellow500 [UIColor colorWithRed:1.000f green:0.804f blue:0.110f alpha:1.000f] +#define ColorCoreYellow600 [UIColor colorWithRed:1.000f green:0.737f blue:0.000f alpha:1.000f] +#define ColorCoreYellow700 [UIColor colorWithRed:0.867f green:0.600f blue:0.012f alpha:1.000f] +#define ColorCoreYellow800 [UIColor colorWithRed:0.729f green:0.459f blue:0.024f alpha:1.000f] +#define ColorCoreYellow900 [UIColor colorWithRed:0.580f green:0.298f blue:0.047f alpha:1.000f] +#define ColorCoreYellow1000 [UIColor colorWithRed:0.329f green:0.165f blue:0.000f alpha:1.000f] +#define ColorCoreYellow1100 [UIColor colorWithRed:0.176f green:0.102f blue:0.020f alpha:1.000f] +#define ColorFontPrimary [UIColor colorWithRed:0.016f green:0.016f blue:0.016f alpha:1.000f] +#define ColorFontSecondary [UIColor colorWithRed:0.153f green:0.200f blue:0.200f alpha:1.000f] +#define ColorFontTertiary [UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f] +#define ColorFontInteractive [UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f] +#define ColorFontInteractiveHover [UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f] +#define ColorFontInteractiveActive [UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f] +#define ColorFontInteractiveDisabled [UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f] +#define ColorFontDanger [UIColor colorWithRed:0.427f green:0.075f blue:0.075f alpha:1.000f] +#define ColorFontWarning [UIColor colorWithRed:0.376f green:0.090f blue:0.000f alpha:1.000f] +#define ColorFontSuccess [UIColor colorWithRed:0.031f green:0.259f blue:0.184f alpha:1.000f] +#define SizeBorderRadiusLarge 480.00f +#define SizeFontSmall 12.00f +#define SizeFontMedium 16.00f +#define SizeFontLarge 24.00f +#define SizeFontXl 36.00f +#define SizePaddingSmall 8.00f +#define SizePaddingMedium 16.00f +#define SizePaddingLarge 16.00f +#define SizePaddingXl 16.00f + +" +`; + +exports[`integration ios objective-c ios/singleton.h should match snapshot 1`] = ` +" +// +// singleton.h +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +#import +#import + +@interface StyleDictionary : NSObject + ++ (NSDictionary *)properties; ++ (NSDictionary *)getProperty:(NSString *)keyPath; ++ (nonnull)getValue:(NSString *)keyPath; + +@end +" +`; + +exports[`integration ios objective-c ios/singleton.m should match snapshot 1`] = ` +" +// +// singleton.m +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +#import \\"StyleDictionary.h\\" + +@implementation StyleDictionary + ++ (NSDictionary *)getProperty:(NSString *)keyPath { + return [[self properties] valueForKeyPath:keyPath]; +} + ++ (nonnull)getValue:(NSString *)keyPath { + return [[self properties] valueForKeyPath:[NSString stringWithFormat:@\\"%@.value\\", keyPath]]; +} + ++ (NSDictionary *)properties { + static NSDictionary * dictionary; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + dictionary = @{ + @\\"color\\": @{ + @\\"background\\": @{ + @\\"primary\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:1.000f blue:1.000f alpha:1.000f], + @\\"name\\": @\\"ColorBackgroundPrimary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"background\\", + @\\"item\\": @\\"primary\\" + }, + @\\"secondary\\": @{ + @\\"value\\": [UIColor colorWithRed:0.953f green:0.957f blue:0.957f alpha:1.000f], + @\\"name\\": @\\"ColorBackgroundSecondary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"background\\", + @\\"item\\": @\\"secondary\\" + }, + @\\"tertiary\\": @{ + @\\"value\\": [UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f], + @\\"name\\": @\\"ColorBackgroundTertiary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"background\\", + @\\"item\\": @\\"tertiary\\" + }, + @\\"danger\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.918f blue:0.914f alpha:1.000f], + @\\"name\\": @\\"ColorBackgroundDanger\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"background\\", + @\\"item\\": @\\"danger\\" + }, + @\\"warning\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.929f blue:0.890f alpha:1.000f], + @\\"name\\": @\\"ColorBackgroundWarning\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"background\\", + @\\"item\\": @\\"warning\\" + }, + @\\"success\\": @{ + @\\"value\\": [UIColor colorWithRed:0.922f green:0.976f blue:0.922f alpha:1.000f], + @\\"name\\": @\\"ColorBackgroundSuccess\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"background\\", + @\\"item\\": @\\"success\\" + }, + @\\"info\\": @{ + @\\"value\\": [UIColor colorWithRed:0.914f green:0.973f blue:1.000f alpha:1.000f], + @\\"name\\": @\\"ColorBackgroundInfo\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"background\\", + @\\"item\\": @\\"info\\" + }, + @\\"disabled\\": @{ + @\\"value\\": [UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f], + @\\"name\\": @\\"ColorBackgroundDisabled\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"background\\", + @\\"item\\": @\\"disabled\\" + } + }, + @\\"border\\": @{ + @\\"primary\\": @{ + @\\"value\\": [UIColor colorWithRed:0.784f green:0.800f blue:0.800f alpha:1.000f], + @\\"name\\": @\\"ColorBorderPrimary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"border\\", + @\\"item\\": @\\"primary\\" + }, + @\\"secondary\\": @ + }, + @\\"tertiary\\": @ + } + }, + @\\"brand\\": @{ + @\\"primary\\": @{ + @\\"value\\": [UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f], + @\\"name\\": @\\"ColorBrandPrimary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"brand\\", + @\\"item\\": @\\"primary\\" + }, + @\\"secondary\\": @{ + @\\"value\\": [UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f], + @\\"name\\": @\\"ColorBrandSecondary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"brand\\", + @\\"item\\": @\\"secondary\\" + } + }, + @\\"core\\": @{ + @\\"green\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:0.922f green:0.976f blue:0.922f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.843f green:0.957f blue:0.843f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:0.761f green:0.949f blue:0.741f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:0.596f green:0.898f blue:0.557f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:0.459f green:0.867f blue:0.400f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.349f green:0.796f blue:0.349f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.169f green:0.714f blue:0.337f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.047f green:0.655f blue:0.314f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.000f green:0.545f blue:0.275f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.000f green:0.420f blue:0.251f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.031f green:0.259f blue:0.184f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.000f green:0.169f blue:0.125f alpha:1.000f], + @\\"name\\": @\\"ColorCoreGreen1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"green\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"teal\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:0.898f green:0.976f blue:0.961f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.804f green:0.969f blue:0.937f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:0.702f green:0.949f blue:0.902f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:0.490f green:0.918f blue:0.835f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:0.141f green:0.878f blue:0.773f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.031f green:0.769f blue:0.698f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.000f green:0.663f blue:0.612f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.043f green:0.588f blue:0.561f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.024f green:0.486f blue:0.486f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.008f green:0.400f blue:0.380f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.031f green:0.247f blue:0.247f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.000f green:0.145f blue:0.157f alpha:1.000f], + @\\"name\\": @\\"ColorCoreTeal1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"teal\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"aqua\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:0.851f green:0.988f blue:0.984f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.773f green:0.976f blue:0.976f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:0.647f green:0.949f blue:0.949f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:0.463f green:0.898f blue:0.886f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:0.200f green:0.839f blue:0.886f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.090f green:0.722f blue:0.808f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.027f green:0.592f blue:0.682f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.059f green:0.431f blue:0.518f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.012f green:0.369f blue:0.451f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.031f green:0.239f blue:0.310f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.000f green:0.157f blue:0.220f alpha:1.000f], + @\\"name\\": @\\"ColorCoreAqua1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"aqua\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"blue\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:0.914f green:0.973f blue:1.000f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.863f green:0.949f blue:1.000f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:0.780f green:0.894f blue:0.976f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:0.631f green:0.824f blue:0.973f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:0.337f green:0.678f blue:0.961f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.220f green:0.588f blue:0.890f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.169f green:0.529f blue:0.827f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.125f green:0.475f blue:0.765f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.067f green:0.427f blue:0.667f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.047f green:0.337f blue:0.537f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.039f green:0.224f blue:0.376f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.000f green:0.129f blue:0.220f alpha:1.000f], + @\\"name\\": @\\"ColorCoreBlue1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"blue\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"purple\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:0.949f green:0.949f blue:0.976f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.918f green:0.918f blue:0.976f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:0.847f green:0.843f blue:0.976f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:0.757f green:0.757f blue:0.969f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:0.631f green:0.576f blue:0.949f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.569f green:0.502f blue:0.957f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.506f green:0.435f blue:0.918f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.369f green:0.306f blue:0.729f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.282f green:0.227f blue:0.612f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.176f green:0.141f blue:0.420f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.114f green:0.114f blue:0.220f alpha:1.000f], + @\\"name\\": @\\"ColorCorePurple1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"purple\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"magenta\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:0.996f green:0.941f blue:1.000f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.976f green:0.890f blue:0.988f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:0.957f green:0.769f blue:0.969f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:0.929f green:0.678f blue:0.949f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:0.949f green:0.510f blue:0.961f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.859f green:0.380f blue:0.859f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.769f green:0.306f blue:0.725f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.675f green:0.267f blue:0.659f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.561f green:0.220f blue:0.588f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.424f green:0.133f blue:0.467f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.271f green:0.082f blue:0.318f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.161f green:0.098f blue:0.176f alpha:1.000f], + @\\"name\\": @\\"ColorCoreMagenta1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"magenta\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"pink\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.914f blue:0.953f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.988f green:0.859f blue:0.922f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.710f blue:0.835f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.584f blue:0.757f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.463f blue:0.682f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.937f green:0.345f blue:0.545f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.878f green:0.267f blue:0.486f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.808f green:0.212f blue:0.396f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.698f green:0.184f blue:0.357f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.576f green:0.094f blue:0.278f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.337f green:0.071f blue:0.192f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.169f green:0.090f blue:0.129f alpha:1.000f], + @\\"name\\": @\\"ColorCorePink1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"pink\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"red\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.918f blue:0.914f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.835f blue:0.824f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.722f blue:0.694f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.612f blue:0.561f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.498f blue:0.431f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.969f green:0.376f blue:0.329f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.929f green:0.298f blue:0.259f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.859f green:0.243f blue:0.243f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.776f green:0.204f blue:0.204f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.600f green:0.133f blue:0.133f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.427f green:0.075f blue:0.075f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.169f green:0.067f blue:0.067f alpha:1.000f], + @\\"name\\": @\\"ColorCoreRed1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"red\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"orange\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.929f blue:0.890f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.988f green:0.863f blue:0.800f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.776f blue:0.643f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.694f blue:0.502f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.612f blue:0.365f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.988f green:0.537f blue:0.263f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.961f green:0.490f blue:0.200f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.929f green:0.439f blue:0.141f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.808f green:0.333f blue:0.067f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.588f green:0.173f blue:0.043f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.376f green:0.090f blue:0.000f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.176f green:0.075f blue:0.055f alpha:1.000f], + @\\"name\\": @\\"ColorCoreOrange1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"orange\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"neutral\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:1.000f blue:1.000f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.953f green:0.957f blue:0.957f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:0.871f green:0.882f blue:0.882f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:0.784f green:0.800f blue:0.800f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:0.690f green:0.714f blue:0.718f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:0.573f green:0.604f blue:0.608f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:0.431f green:0.475f blue:0.478f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.318f green:0.369f blue:0.373f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.153f green:0.200f blue:0.200f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.086f green:0.125f blue:0.125f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.016f green:0.016f blue:0.016f alpha:1.000f], + @\\"name\\": @\\"ColorCoreNeutral1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"neutral\\", + @\\"subitem\\": @\\"1100\\" + } + }, + @\\"yellow\\": @{ + @\\"0\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.973f blue:0.886f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow0\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"0\\" + }, + @\\"100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.992f green:0.937f blue:0.804f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"100\\" + }, + @\\"200\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.914f blue:0.604f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow200\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"200\\" + }, + @\\"300\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.882f blue:0.431f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow300\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"300\\" + }, + @\\"400\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.851f blue:0.263f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow400\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"400\\" + }, + @\\"500\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.804f blue:0.110f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow500\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"500\\" + }, + @\\"600\\": @{ + @\\"value\\": [UIColor colorWithRed:1.000f green:0.737f blue:0.000f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow600\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"600\\" + }, + @\\"700\\": @{ + @\\"value\\": [UIColor colorWithRed:0.867f green:0.600f blue:0.012f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow700\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"700\\" + }, + @\\"800\\": @{ + @\\"value\\": [UIColor colorWithRed:0.729f green:0.459f blue:0.024f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow800\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"800\\" + }, + @\\"900\\": @{ + @\\"value\\": [UIColor colorWithRed:0.580f green:0.298f blue:0.047f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow900\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"900\\" + }, + @\\"1000\\": @{ + @\\"value\\": [UIColor colorWithRed:0.329f green:0.165f blue:0.000f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow1000\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"1000\\" + }, + @\\"1100\\": @{ + @\\"value\\": [UIColor colorWithRed:0.176f green:0.102f blue:0.020f alpha:1.000f], + @\\"name\\": @\\"ColorCoreYellow1100\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"core\\", + @\\"item\\": @\\"yellow\\", + @\\"subitem\\": @\\"1100\\" + } + } + }, + @\\"font\\": @{ + @\\"primary\\": @{ + @\\"value\\": [UIColor colorWithRed:0.016f green:0.016f blue:0.016f alpha:1.000f], + @\\"name\\": @\\"ColorFontPrimary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"primary\\" + }, + @\\"secondary\\": @{ + @\\"value\\": [UIColor colorWithRed:0.153f green:0.200f blue:0.200f alpha:1.000f], + @\\"name\\": @\\"ColorFontSecondary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"secondary\\" + }, + @\\"tertiary\\": @{ + @\\"value\\": [UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f], + @\\"name\\": @\\"ColorFontTertiary\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"tertiary\\" + }, + @\\"interactive\\": @{ + @\\"_\\": @{ + @\\"value\\": [UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f], + @\\"name\\": @\\"ColorFontInteractive\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"interactive\\", + @\\"subitem\\": @\\"_\\" + }, + @\\"hover\\": @{ + @\\"value\\": [UIColor colorWithRed:0.043f green:0.522f blue:0.600f alpha:1.000f], + @\\"name\\": @\\"ColorFontInteractiveHover\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"interactive\\", + @\\"subitem\\": @\\"hover\\" + }, + @\\"active\\": @{ + @\\"value\\": [UIColor colorWithRed:0.435f green:0.369f blue:0.827f alpha:1.000f], + @\\"name\\": @\\"ColorFontInteractiveActive\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"interactive\\", + @\\"subitem\\": @\\"active\\" + }, + @\\"disabled\\": @{ + @\\"value\\": [UIColor colorWithRed:0.212f green:0.255f blue:0.255f alpha:1.000f], + @\\"name\\": @\\"ColorFontInteractiveDisabled\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"interactive\\", + @\\"subitem\\": @\\"disabled\\" + } + }, + @\\"danger\\": @{ + @\\"value\\": [UIColor colorWithRed:0.427f green:0.075f blue:0.075f alpha:1.000f], + @\\"name\\": @\\"ColorFontDanger\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"danger\\" + }, + @\\"warning\\": @{ + @\\"value\\": [UIColor colorWithRed:0.376f green:0.090f blue:0.000f alpha:1.000f], + @\\"name\\": @\\"ColorFontWarning\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"warning\\" + }, + @\\"success\\": @{ + @\\"value\\": [UIColor colorWithRed:0.031f green:0.259f blue:0.184f alpha:1.000f], + @\\"name\\": @\\"ColorFontSuccess\\", + @\\"category\\": @\\"color\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"success\\" + } + } + }, + @\\"size\\": @{ + @\\"border\\": @{ + @\\"radius\\": @{ + @\\"large\\": @{ + @\\"value\\": @480.00f, + @\\"name\\": @\\"SizeBorderRadiusLarge\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"border\\", + @\\"item\\": @\\"radius\\", + @\\"subitem\\": @\\"large\\" + } + } + }, + @\\"font\\": @{ + @\\"small\\": @{ + @\\"value\\": @12.00f, + @\\"name\\": @\\"SizeFontSmall\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"small\\" + }, + @\\"medium\\": @{ + @\\"value\\": @16.00f, + @\\"name\\": @\\"SizeFontMedium\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"medium\\" + }, + @\\"large\\": @{ + @\\"value\\": @24.00f, + @\\"name\\": @\\"SizeFontLarge\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"large\\" + }, + @\\"xl\\": @{ + @\\"value\\": @36.00f, + @\\"name\\": @\\"SizeFontXl\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"font\\", + @\\"item\\": @\\"xl\\" + } + }, + @\\"padding\\": @{ + @\\"small\\": @{ + @\\"value\\": @8.00f, + @\\"name\\": @\\"SizePaddingSmall\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"padding\\", + @\\"item\\": @\\"small\\" + }, + @\\"medium\\": @{ + @\\"value\\": @16.00f, + @\\"name\\": @\\"SizePaddingMedium\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"padding\\", + @\\"item\\": @\\"medium\\" + }, + @\\"large\\": @{ + @\\"value\\": @16.00f, + @\\"name\\": @\\"SizePaddingLarge\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"padding\\", + @\\"item\\": @\\"large\\" + }, + @\\"xl\\": @{ + @\\"value\\": @16.00f, + @\\"name\\": @\\"SizePaddingXl\\", + @\\"category\\": @\\"size\\", + @\\"type\\": @\\"padding\\", + @\\"item\\": @\\"xl\\" + } + } + } + }; + }); + + return dictionary; +} + +@end + + +" +`; + +exports[`integration ios objective-c ios/static.h should match snapshot 1`] = ` +" +// static.h +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +#import + + +extern CGFloat const SizeBorderRadiusLarge; +extern CGFloat const SizeFontSmall; +extern CGFloat const SizeFontMedium; +extern CGFloat const SizeFontLarge; +extern CGFloat const SizeFontXl; +extern CGFloat const SizePaddingSmall; +extern CGFloat const SizePaddingMedium; +extern CGFloat const SizePaddingLarge; +extern CGFloat const SizePaddingXl; +" +`; + +exports[`integration ios objective-c ios/static.m should match snapshot 1`] = ` +" +// +// static.m +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +#import \\"StyleDictionaryStatic.h\\" + + +CGFloat const SizeBorderRadiusLarge = 480.00f; +CGFloat const SizeFontSmall = 12.00f; +CGFloat const SizeFontMedium = 16.00f; +CGFloat const SizeFontLarge = 24.00f; +CGFloat const SizeFontXl = 36.00f; +CGFloat const SizePaddingSmall = 8.00f; +CGFloat const SizePaddingMedium = 16.00f; +CGFloat const SizePaddingLarge = 16.00f; +CGFloat const SizePaddingXl = 16.00f; +" +`; diff --git a/__integration__/__snapshots__/objectValues.test.js.snap b/__integration__/__snapshots__/objectValues.test.js.snap new file mode 100644 index 000000000..7fc7c7478 --- /dev/null +++ b/__integration__/__snapshots__/objectValues.test.js.snap @@ -0,0 +1,93 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration object values css/variables border should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --border-primary: 0.125rem solid #ff0000; +} +" +`; + +exports[`integration object values css/variables border with references should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --border-primary: var(--size-border) solid var(--color-red); +} +" +`; + +exports[`integration object values css/variables hex syntax should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --color-red: #ff0000; + --color-green: #40bf40; +} +" +`; + +exports[`integration object values css/variables hex syntax with references should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --color-red: #ff0000; + --color-green: #40bf40; +} +" +`; + +exports[`integration object values css/variables hsl syntax should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --color-red: #ff0000; + --color-green: hsl(120, 50%, 50%); +} +" +`; + +exports[`integration object values css/variables hsl syntax with references should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --color-red: #ff0000; + --color-green: hsl(120, 50%, 50%); +} +" +`; + +exports[`integration object values scss/variables should match snapshot 1`] = ` +" +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + +$border-primary: 0.125rem solid #ff0000;" +`; + +exports[`integration object values scss/variables with references should match snapshot 1`] = ` +" +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + +$border-primary: $size-border solid $color-red;" +`; diff --git a/__integration__/__snapshots__/scss.test.js.snap b/__integration__/__snapshots__/scss.test.js.snap new file mode 100644 index 000000000..ee431b3cf --- /dev/null +++ b/__integration__/__snapshots__/scss.test.js.snap @@ -0,0 +1,917 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration scss scss/map-deep should match snapshot 1`] = ` +" +/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +$color-background-primary: #ffffff !default; +$color-background-secondary: #f3f4f4 !default; +$color-background-tertiary: #dee1e1 !default; +$color-background-danger: #ffeae9 !default; +$color-background-warning: #ffede3 !default; +$color-background-success: #ebf9eb !default; +$color-background-info: #e9f8ff !default; +$color-background-disabled: #dee1e1 !default; +$color-border-primary: #c8cccc !default; +$color-brand-primary: #0b8599 !default; +$color-brand-secondary: #6f5ed3 !default; +$color-core-green-0: #ebf9eb !default; +$color-core-green-100: #d7f4d7 !default; +$color-core-green-200: #c2f2bd !default; +$color-core-green-300: #98e58e !default; +$color-core-green-400: #75dd66 !default; +$color-core-green-500: #59cb59 !default; +$color-core-green-600: #2bb656 !default; +$color-core-green-700: #0ca750 !default; +$color-core-green-800: #008b46 !default; +$color-core-green-900: #006b40 !default; +$color-core-green-1000: #08422f !default; +$color-core-green-1100: #002b20 !default; +$color-core-teal-0: #e5f9f5 !default; +$color-core-teal-100: #cdf7ef !default; +$color-core-teal-200: #b3f2e6 !default; +$color-core-teal-300: #7dead5 !default; +$color-core-teal-400: #24e0c5 !default; +$color-core-teal-500: #08c4b2 !default; +$color-core-teal-600: #00a99c !default; +$color-core-teal-700: #0b968f !default; +$color-core-teal-800: #067c7c !default; +$color-core-teal-900: #026661 !default; +$color-core-teal-1000: #083f3f !default; +$color-core-teal-1100: #002528 !default; +$color-core-aqua-0: #d9fcfb !default; +$color-core-aqua-100: #c5f9f9 !default; +$color-core-aqua-200: #a5f2f2 !default; +$color-core-aqua-300: #76e5e2 !default; +$color-core-aqua-400: #33d6e2 !default; +$color-core-aqua-500: #17b8ce !default; +$color-core-aqua-600: #0797ae !default; +$color-core-aqua-700: #0b8599 !default; +$color-core-aqua-800: #0f6e84 !default; +$color-core-aqua-900: #035e73 !default; +$color-core-aqua-1000: #083d4f !default; +$color-core-aqua-1100: #002838 !default; +$color-core-blue-0: #e9f8ff !default; +$color-core-blue-100: #dcf2ff !default; +$color-core-blue-200: #c7e4f9 !default; +$color-core-blue-300: #a1d2f8 !default; +$color-core-blue-400: #56adf5 !default; +$color-core-blue-500: #3896e3 !default; +$color-core-blue-600: #2b87d3 !default; +$color-core-blue-700: #2079c3 !default; +$color-core-blue-800: #116daa !default; +$color-core-blue-900: #0c5689 !default; +$color-core-blue-1000: #0a3960 !default; +$color-core-blue-1100: #002138 !default; +$color-core-purple-0: #f2f2f9 !default; +$color-core-purple-100: #eaeaf9 !default; +$color-core-purple-200: #d8d7f9 !default; +$color-core-purple-300: #c1c1f7 !default; +$color-core-purple-400: #a193f2 !default; +$color-core-purple-500: #9180f4 !default; +$color-core-purple-600: #816fea !default; +$color-core-purple-700: #6f5ed3 !default; +$color-core-purple-800: #5e4eba !default; +$color-core-purple-900: #483a9c !default; +$color-core-purple-1000: #2d246b !default; +$color-core-purple-1100: #1d1d38 !default; +$color-core-magenta-0: #fef0ff !default; +$color-core-magenta-100: #f9e3fc !default; +$color-core-magenta-200: #f4c4f7 !default; +$color-core-magenta-300: #edadf2 !default; +$color-core-magenta-400: #f282f5 !default; +$color-core-magenta-500: #db61db !default; +$color-core-magenta-600: #c44eb9 !default; +$color-core-magenta-700: #ac44a8 !default; +$color-core-magenta-800: #8f3896 !default; +$color-core-magenta-900: #6c2277 !default; +$color-core-magenta-1000: #451551 !default; +$color-core-magenta-1100: #29192d !default; +$color-core-pink-0: #ffe9f3 !default; +$color-core-pink-100: #fcdbeb !default; +$color-core-pink-200: #ffb5d5 !default; +$color-core-pink-300: #ff95c1 !default; +$color-core-pink-400: #ff76ae !default; +$color-core-pink-500: #ef588b !default; +$color-core-pink-600: #e0447c !default; +$color-core-pink-700: #ce3665 !default; +$color-core-pink-800: #b22f5b !default; +$color-core-pink-900: #931847 !default; +$color-core-pink-1000: #561231 !default; +$color-core-pink-1100: #2b1721 !default; +$color-core-red-0: #ffeae9 !default; +$color-core-red-100: #ffd5d2 !default; +$color-core-red-200: #ffb8b1 !default; +$color-core-red-300: #ff9c8f !default; +$color-core-red-400: #ff7f6e !default; +$color-core-red-500: #f76054 !default; +$color-core-red-600: #ed4c42 !default; +$color-core-red-700: #db3e3e !default; +$color-core-red-800: #c63434 !default; +$color-core-red-900: #992222 !default; +$color-core-red-1000: #6d1313 !default; +$color-core-red-1100: #2b1111 !default; +$color-core-orange-0: #ffede3 !default; +$color-core-orange-100: #fcdccc !default; +$color-core-orange-200: #ffc6a4 !default; +$color-core-orange-300: #ffb180 !default; +$color-core-orange-400: #ff9c5d !default; +$color-core-orange-500: #fc8943 !default; +$color-core-orange-600: #f57d33 !default; +$color-core-orange-700: #ed7024 !default; +$color-core-orange-800: #ce5511 !default; +$color-core-orange-900: #962c0b !default; +$color-core-orange-1000: #601700 !default; +$color-core-orange-1100: #2d130e !default; +$color-core-neutral-0: #ffffff !default; +$color-core-neutral-100: #f3f4f4 !default; +$color-core-neutral-200: #dee1e1 !default; +$color-core-neutral-300: #c8cccc !default; +$color-core-neutral-400: #b0b6b7 !default; +$color-core-neutral-500: #929a9b !default; +$color-core-neutral-600: #6e797a !default; +$color-core-neutral-700: #515e5f !default; +$color-core-neutral-800: #364141 !default; +$color-core-neutral-900: #273333 !default; +$color-core-neutral-1000: #162020 !default; +$color-core-neutral-1100: #040404 !default; +$color-core-yellow-0: #fff8e2 !default; +$color-core-yellow-100: #fdefcd !default; +$color-core-yellow-200: #ffe99a !default; +$color-core-yellow-300: #ffe16e !default; +$color-core-yellow-400: #ffd943 !default; +$color-core-yellow-500: #ffcd1c !default; +$color-core-yellow-600: #ffbc00 !default; +$color-core-yellow-700: #dd9903 !default; +$color-core-yellow-800: #ba7506 !default; +$color-core-yellow-900: #944c0c !default; +$color-core-yellow-1000: #542a00 !default; +$color-core-yellow-1100: #2d1a05 !default; +$color-font-primary: #040404 !default; +$color-font-secondary: #273333 !default; +$color-font-tertiary: #364141 !default; +$color-font-interactive: #0b8599 !default; +$color-font-interactive-hover: #0b8599 !default; +$color-font-interactive-active: #6f5ed3 !default; +$color-font-interactive-disabled: #364141 !default; +$color-font-danger: #6d1313 !default; +$color-font-warning: #601700 !default; +$color-font-success: #08422f !default; +$size-border-radius-large: 30rem !default; +$size-font-small: 0.75rem !default; +$size-font-medium: 1rem !default; +$size-font-large: 1.5rem !default; +$size-font-xl: 2.25rem !default; +$size-padding-small: 0.5rem !default; +$size-padding-medium: 1rem !default; +$size-padding-large: 1rem !default; +$size-padding-xl: 1rem !default; + +$design-system-tokens: ( + 'color': ( + 'background': ( + 'primary': $color-background-primary, + 'secondary': $color-background-secondary, + 'tertiary': $color-background-tertiary, + 'danger': $color-background-danger, + 'warning': $color-background-warning, + 'success': $color-background-success, + 'info': $color-background-info, + 'disabled': $color-background-disabled + ), + 'border': ( + 'primary': $color-border-primary, + 'secondary': ( + + ), + 'tertiary': ( + + ) + ), + 'brand': ( + 'primary': $color-brand-primary, + 'secondary': $color-brand-secondary + ), + 'core': ( + 'green': ( + '0': $color-core-green-0, + '100': $color-core-green-100, + '200': $color-core-green-200, + '300': $color-core-green-300, + '400': $color-core-green-400, + '500': $color-core-green-500, + '600': $color-core-green-600, + '700': $color-core-green-700, + '800': $color-core-green-800, + '900': $color-core-green-900, + '1000': $color-core-green-1000, + '1100': $color-core-green-1100 + ), + 'teal': ( + '0': $color-core-teal-0, + '100': $color-core-teal-100, + '200': $color-core-teal-200, + '300': $color-core-teal-300, + '400': $color-core-teal-400, + '500': $color-core-teal-500, + '600': $color-core-teal-600, + '700': $color-core-teal-700, + '800': $color-core-teal-800, + '900': $color-core-teal-900, + '1000': $color-core-teal-1000, + '1100': $color-core-teal-1100 + ), + 'aqua': ( + '0': $color-core-aqua-0, + '100': $color-core-aqua-100, + '200': $color-core-aqua-200, + '300': $color-core-aqua-300, + '400': $color-core-aqua-400, + '500': $color-core-aqua-500, + '600': $color-core-aqua-600, + '700': $color-core-aqua-700, + '800': $color-core-aqua-800, + '900': $color-core-aqua-900, + '1000': $color-core-aqua-1000, + '1100': $color-core-aqua-1100 + ), + 'blue': ( + '0': $color-core-blue-0, + '100': $color-core-blue-100, + '200': $color-core-blue-200, + '300': $color-core-blue-300, + '400': $color-core-blue-400, + '500': $color-core-blue-500, + '600': $color-core-blue-600, + '700': $color-core-blue-700, + '800': $color-core-blue-800, + '900': $color-core-blue-900, + '1000': $color-core-blue-1000, + '1100': $color-core-blue-1100 + ), + 'purple': ( + '0': $color-core-purple-0, + '100': $color-core-purple-100, + '200': $color-core-purple-200, + '300': $color-core-purple-300, + '400': $color-core-purple-400, + '500': $color-core-purple-500, + '600': $color-core-purple-600, + '700': $color-core-purple-700, + '800': $color-core-purple-800, + '900': $color-core-purple-900, + '1000': $color-core-purple-1000, + '1100': $color-core-purple-1100 + ), + 'magenta': ( + '0': $color-core-magenta-0, + '100': $color-core-magenta-100, + '200': $color-core-magenta-200, + '300': $color-core-magenta-300, + '400': $color-core-magenta-400, + '500': $color-core-magenta-500, + '600': $color-core-magenta-600, + '700': $color-core-magenta-700, + '800': $color-core-magenta-800, + '900': $color-core-magenta-900, + '1000': $color-core-magenta-1000, + '1100': $color-core-magenta-1100 + ), + 'pink': ( + '0': $color-core-pink-0, + '100': $color-core-pink-100, + '200': $color-core-pink-200, + '300': $color-core-pink-300, + '400': $color-core-pink-400, + '500': $color-core-pink-500, + '600': $color-core-pink-600, + '700': $color-core-pink-700, + '800': $color-core-pink-800, + '900': $color-core-pink-900, + '1000': $color-core-pink-1000, + '1100': $color-core-pink-1100 + ), + 'red': ( + '0': $color-core-red-0, + '100': $color-core-red-100, + '200': $color-core-red-200, + '300': $color-core-red-300, + '400': $color-core-red-400, + '500': $color-core-red-500, + '600': $color-core-red-600, + '700': $color-core-red-700, + '800': $color-core-red-800, + '900': $color-core-red-900, + '1000': $color-core-red-1000, + '1100': $color-core-red-1100 + ), + 'orange': ( + '0': $color-core-orange-0, + '100': $color-core-orange-100, + '200': $color-core-orange-200, + '300': $color-core-orange-300, + '400': $color-core-orange-400, + '500': $color-core-orange-500, + '600': $color-core-orange-600, + '700': $color-core-orange-700, + '800': $color-core-orange-800, + '900': $color-core-orange-900, + '1000': $color-core-orange-1000, + '1100': $color-core-orange-1100 + ), + 'neutral': ( + '0': $color-core-neutral-0, + '100': $color-core-neutral-100, + '200': $color-core-neutral-200, + '300': $color-core-neutral-300, + '400': $color-core-neutral-400, + '500': $color-core-neutral-500, + '600': $color-core-neutral-600, + '700': $color-core-neutral-700, + '800': $color-core-neutral-800, + '900': $color-core-neutral-900, + '1000': $color-core-neutral-1000, + '1100': $color-core-neutral-1100 + ), + 'yellow': ( + '0': $color-core-yellow-0, + '100': $color-core-yellow-100, + '200': $color-core-yellow-200, + '300': $color-core-yellow-300, + '400': $color-core-yellow-400, + '500': $color-core-yellow-500, + '600': $color-core-yellow-600, + '700': $color-core-yellow-700, + '800': $color-core-yellow-800, + '900': $color-core-yellow-900, + '1000': $color-core-yellow-1000, + '1100': $color-core-yellow-1100 + ) + ), + 'font': ( + 'primary': $color-font-primary, + 'secondary': $color-font-secondary, + 'tertiary': $color-font-tertiary, + 'interactive': ( + '_': $color-font-interactive, + 'hover': $color-font-interactive-hover, + 'active': $color-font-interactive-active, + 'disabled': $color-font-interactive-disabled + ), + 'danger': $color-font-danger, + 'warning': $color-font-warning, + 'success': $color-font-success + ) + ), + 'size': ( + 'border': ( + 'radius': ( + 'large': $size-border-radius-large + ) + ), + 'font': ( + 'small': $size-font-small, + 'medium': $size-font-medium, + 'large': $size-font-large, + 'xl': $size-font-xl + ), + 'padding': ( + 'small': $size-padding-small, + 'medium': $size-padding-medium, + 'large': $size-padding-large, + 'xl': $size-padding-xl + ) + ) +); +" +`; + +exports[`integration scss scss/map-flat should match snapshot 1`] = ` +" +/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +$design-system-tokens: ( + 'color-background-primary': #ffffff, + 'color-background-secondary': #f3f4f4, + 'color-background-tertiary': #dee1e1, + 'color-background-danger': #ffeae9, + 'color-background-warning': #ffede3, + 'color-background-success': #ebf9eb, + 'color-background-info': #e9f8ff, + 'color-background-disabled': #dee1e1, + 'color-border-primary': #c8cccc, + 'color-brand-primary': #0b8599, + 'color-brand-secondary': #6f5ed3, + 'color-core-green-0': #ebf9eb, + 'color-core-green-100': #d7f4d7, + 'color-core-green-200': #c2f2bd, + 'color-core-green-300': #98e58e, + 'color-core-green-400': #75dd66, + 'color-core-green-500': #59cb59, + 'color-core-green-600': #2bb656, + 'color-core-green-700': #0ca750, + 'color-core-green-800': #008b46, + 'color-core-green-900': #006b40, + 'color-core-green-1000': #08422f, + 'color-core-green-1100': #002b20, + 'color-core-teal-0': #e5f9f5, + 'color-core-teal-100': #cdf7ef, + 'color-core-teal-200': #b3f2e6, + 'color-core-teal-300': #7dead5, + 'color-core-teal-400': #24e0c5, + 'color-core-teal-500': #08c4b2, + 'color-core-teal-600': #00a99c, + 'color-core-teal-700': #0b968f, + 'color-core-teal-800': #067c7c, + 'color-core-teal-900': #026661, + 'color-core-teal-1000': #083f3f, + 'color-core-teal-1100': #002528, + 'color-core-aqua-0': #d9fcfb, + 'color-core-aqua-100': #c5f9f9, + 'color-core-aqua-200': #a5f2f2, + 'color-core-aqua-300': #76e5e2, + 'color-core-aqua-400': #33d6e2, + 'color-core-aqua-500': #17b8ce, + 'color-core-aqua-600': #0797ae, + 'color-core-aqua-700': #0b8599, + 'color-core-aqua-800': #0f6e84, + 'color-core-aqua-900': #035e73, + 'color-core-aqua-1000': #083d4f, + 'color-core-aqua-1100': #002838, + 'color-core-blue-0': #e9f8ff, + 'color-core-blue-100': #dcf2ff, + 'color-core-blue-200': #c7e4f9, + 'color-core-blue-300': #a1d2f8, + 'color-core-blue-400': #56adf5, + 'color-core-blue-500': #3896e3, + 'color-core-blue-600': #2b87d3, + 'color-core-blue-700': #2079c3, + 'color-core-blue-800': #116daa, + 'color-core-blue-900': #0c5689, + 'color-core-blue-1000': #0a3960, + 'color-core-blue-1100': #002138, + 'color-core-purple-0': #f2f2f9, + 'color-core-purple-100': #eaeaf9, + 'color-core-purple-200': #d8d7f9, + 'color-core-purple-300': #c1c1f7, + 'color-core-purple-400': #a193f2, + 'color-core-purple-500': #9180f4, + 'color-core-purple-600': #816fea, + 'color-core-purple-700': #6f5ed3, + 'color-core-purple-800': #5e4eba, + 'color-core-purple-900': #483a9c, + 'color-core-purple-1000': #2d246b, + 'color-core-purple-1100': #1d1d38, + 'color-core-magenta-0': #fef0ff, + 'color-core-magenta-100': #f9e3fc, + 'color-core-magenta-200': #f4c4f7, + 'color-core-magenta-300': #edadf2, + 'color-core-magenta-400': #f282f5, + 'color-core-magenta-500': #db61db, + 'color-core-magenta-600': #c44eb9, + 'color-core-magenta-700': #ac44a8, + 'color-core-magenta-800': #8f3896, + 'color-core-magenta-900': #6c2277, + 'color-core-magenta-1000': #451551, + 'color-core-magenta-1100': #29192d, + 'color-core-pink-0': #ffe9f3, + 'color-core-pink-100': #fcdbeb, + 'color-core-pink-200': #ffb5d5, + 'color-core-pink-300': #ff95c1, + 'color-core-pink-400': #ff76ae, + 'color-core-pink-500': #ef588b, + 'color-core-pink-600': #e0447c, + 'color-core-pink-700': #ce3665, + 'color-core-pink-800': #b22f5b, + 'color-core-pink-900': #931847, + 'color-core-pink-1000': #561231, + 'color-core-pink-1100': #2b1721, + 'color-core-red-0': #ffeae9, + 'color-core-red-100': #ffd5d2, + 'color-core-red-200': #ffb8b1, + 'color-core-red-300': #ff9c8f, + 'color-core-red-400': #ff7f6e, + 'color-core-red-500': #f76054, + 'color-core-red-600': #ed4c42, + 'color-core-red-700': #db3e3e, + 'color-core-red-800': #c63434, + 'color-core-red-900': #992222, + 'color-core-red-1000': #6d1313, + 'color-core-red-1100': #2b1111, + 'color-core-orange-0': #ffede3, + 'color-core-orange-100': #fcdccc, + 'color-core-orange-200': #ffc6a4, + 'color-core-orange-300': #ffb180, + 'color-core-orange-400': #ff9c5d, + 'color-core-orange-500': #fc8943, + 'color-core-orange-600': #f57d33, + 'color-core-orange-700': #ed7024, + 'color-core-orange-800': #ce5511, + 'color-core-orange-900': #962c0b, + 'color-core-orange-1000': #601700, + 'color-core-orange-1100': #2d130e, + 'color-core-neutral-0': #ffffff, + 'color-core-neutral-100': #f3f4f4, + 'color-core-neutral-200': #dee1e1, + 'color-core-neutral-300': #c8cccc, + 'color-core-neutral-400': #b0b6b7, + 'color-core-neutral-500': #929a9b, + 'color-core-neutral-600': #6e797a, + 'color-core-neutral-700': #515e5f, + 'color-core-neutral-800': #364141, + 'color-core-neutral-900': #273333, + 'color-core-neutral-1000': #162020, + 'color-core-neutral-1100': #040404, + 'color-core-yellow-0': #fff8e2, + 'color-core-yellow-100': #fdefcd, + 'color-core-yellow-200': #ffe99a, + 'color-core-yellow-300': #ffe16e, + 'color-core-yellow-400': #ffd943, + 'color-core-yellow-500': #ffcd1c, + 'color-core-yellow-600': #ffbc00, + 'color-core-yellow-700': #dd9903, + 'color-core-yellow-800': #ba7506, + 'color-core-yellow-900': #944c0c, + 'color-core-yellow-1000': #542a00, + 'color-core-yellow-1100': #2d1a05, + 'color-font-primary': #040404, + 'color-font-secondary': #273333, + 'color-font-tertiary': #364141, + 'color-font-interactive': #0b8599, + 'color-font-interactive-hover': #0b8599, + 'color-font-interactive-active': #6f5ed3, + 'color-font-interactive-disabled': #364141, + 'color-font-danger': #6d1313, + 'color-font-warning': #601700, + 'color-font-success': #08422f, + 'size-border-radius-large': 30rem, + 'size-font-small': 0.75rem, + 'size-font-medium': 1rem, + 'size-font-large': 1.5rem, + 'size-font-xl': 2.25rem, + 'size-padding-small': 0.5rem, + 'size-padding-medium': 1rem, + 'size-padding-large': 1rem, + 'size-padding-xl': 1rem +); +" +`; + +exports[`integration scss scss/variables should match snapshot 1`] = ` +" +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + +$color-background-primary: #ffffff !default; +$color-background-secondary: #f3f4f4; +$color-background-tertiary: #dee1e1; +$color-background-danger: #ffeae9; +$color-background-warning: #ffede3; +$color-background-success: #ebf9eb; +$color-background-info: #e9f8ff; +$color-background-disabled: #dee1e1; +$color-border-primary: #c8cccc; +$color-brand-primary: #0b8599; +$color-brand-secondary: #6f5ed3; +$color-core-green-0: #ebf9eb; +$color-core-green-100: #d7f4d7; +$color-core-green-200: #c2f2bd; +$color-core-green-300: #98e58e; +$color-core-green-400: #75dd66; +$color-core-green-500: #59cb59; +$color-core-green-600: #2bb656; +$color-core-green-700: #0ca750; +$color-core-green-800: #008b46; +$color-core-green-900: #006b40; +$color-core-green-1000: #08422f; +$color-core-green-1100: #002b20; +$color-core-teal-0: #e5f9f5; +$color-core-teal-100: #cdf7ef; +$color-core-teal-200: #b3f2e6; +$color-core-teal-300: #7dead5; +$color-core-teal-400: #24e0c5; +$color-core-teal-500: #08c4b2; +$color-core-teal-600: #00a99c; +$color-core-teal-700: #0b968f; +$color-core-teal-800: #067c7c; +$color-core-teal-900: #026661; +$color-core-teal-1000: #083f3f; +$color-core-teal-1100: #002528; +$color-core-aqua-0: #d9fcfb; +$color-core-aqua-100: #c5f9f9; +$color-core-aqua-200: #a5f2f2; +$color-core-aqua-300: #76e5e2; +$color-core-aqua-400: #33d6e2; +$color-core-aqua-500: #17b8ce; +$color-core-aqua-600: #0797ae; +$color-core-aqua-700: #0b8599; +$color-core-aqua-800: #0f6e84; +$color-core-aqua-900: #035e73; +$color-core-aqua-1000: #083d4f; +$color-core-aqua-1100: #002838; +$color-core-blue-0: #e9f8ff; +$color-core-blue-100: #dcf2ff; +$color-core-blue-200: #c7e4f9; +$color-core-blue-300: #a1d2f8; +$color-core-blue-400: #56adf5; +$color-core-blue-500: #3896e3; +$color-core-blue-600: #2b87d3; +$color-core-blue-700: #2079c3; +$color-core-blue-800: #116daa; +$color-core-blue-900: #0c5689; +$color-core-blue-1000: #0a3960; +$color-core-blue-1100: #002138; +$color-core-purple-0: #f2f2f9; +$color-core-purple-100: #eaeaf9; +$color-core-purple-200: #d8d7f9; +$color-core-purple-300: #c1c1f7; +$color-core-purple-400: #a193f2; +$color-core-purple-500: #9180f4; +$color-core-purple-600: #816fea; +$color-core-purple-700: #6f5ed3; +$color-core-purple-800: #5e4eba; +$color-core-purple-900: #483a9c; +$color-core-purple-1000: #2d246b; +$color-core-purple-1100: #1d1d38; +$color-core-magenta-0: #fef0ff; +$color-core-magenta-100: #f9e3fc; +$color-core-magenta-200: #f4c4f7; +$color-core-magenta-300: #edadf2; +$color-core-magenta-400: #f282f5; +$color-core-magenta-500: #db61db; +$color-core-magenta-600: #c44eb9; +$color-core-magenta-700: #ac44a8; +$color-core-magenta-800: #8f3896; +$color-core-magenta-900: #6c2277; +$color-core-magenta-1000: #451551; +$color-core-magenta-1100: #29192d; +$color-core-pink-0: #ffe9f3; +$color-core-pink-100: #fcdbeb; +$color-core-pink-200: #ffb5d5; +$color-core-pink-300: #ff95c1; +$color-core-pink-400: #ff76ae; +$color-core-pink-500: #ef588b; +$color-core-pink-600: #e0447c; +$color-core-pink-700: #ce3665; +$color-core-pink-800: #b22f5b; +$color-core-pink-900: #931847; +$color-core-pink-1000: #561231; +$color-core-pink-1100: #2b1721; +$color-core-red-0: #ffeae9; +$color-core-red-100: #ffd5d2; +$color-core-red-200: #ffb8b1; +$color-core-red-300: #ff9c8f; +$color-core-red-400: #ff7f6e; +$color-core-red-500: #f76054; +$color-core-red-600: #ed4c42; +$color-core-red-700: #db3e3e; +$color-core-red-800: #c63434; +$color-core-red-900: #992222; +$color-core-red-1000: #6d1313; +$color-core-red-1100: #2b1111; +$color-core-orange-0: #ffede3; +$color-core-orange-100: #fcdccc; +$color-core-orange-200: #ffc6a4; +$color-core-orange-300: #ffb180; +$color-core-orange-400: #ff9c5d; +$color-core-orange-500: #fc8943; +$color-core-orange-600: #f57d33; +$color-core-orange-700: #ed7024; +$color-core-orange-800: #ce5511; +$color-core-orange-900: #962c0b; +$color-core-orange-1000: #601700; +$color-core-orange-1100: #2d130e; +$color-core-neutral-0: #ffffff; +$color-core-neutral-100: #f3f4f4; +$color-core-neutral-200: #dee1e1; +$color-core-neutral-300: #c8cccc; +$color-core-neutral-400: #b0b6b7; +$color-core-neutral-500: #929a9b; +$color-core-neutral-600: #6e797a; +$color-core-neutral-700: #515e5f; +$color-core-neutral-800: #364141; +$color-core-neutral-900: #273333; +$color-core-neutral-1000: #162020; +$color-core-neutral-1100: #040404; +$color-core-yellow-0: #fff8e2; +$color-core-yellow-100: #fdefcd; +$color-core-yellow-200: #ffe99a; +$color-core-yellow-300: #ffe16e; +$color-core-yellow-400: #ffd943; +$color-core-yellow-500: #ffcd1c; +$color-core-yellow-600: #ffbc00; +$color-core-yellow-700: #dd9903; +$color-core-yellow-800: #ba7506; +$color-core-yellow-900: #944c0c; +$color-core-yellow-1000: #542a00; +$color-core-yellow-1100: #2d1a05; +$color-font-primary: #040404; +$color-font-secondary: #273333; +$color-font-tertiary: #364141; +$color-font-interactive: #0b8599; +$color-font-interactive-hover: #0b8599; +$color-font-interactive-active: #6f5ed3; +$color-font-interactive-disabled: #364141; +$color-font-danger: #6d1313; +$color-font-warning: #601700; +$color-font-success: #08422f; +$size-border-radius-large: 30rem; +$size-font-small: 0.75rem; +$size-font-medium: 1rem; +$size-font-large: 1.5rem; +$size-font-xl: 2.25rem; +$size-padding-small: 0.5rem; +$size-padding-medium: 1rem; +$size-padding-large: 1rem; +$size-padding-xl: 1rem;" +`; + +exports[`integration scss scss/variables with filter and output references should match snapshot 1`] = ` +" +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + +$color-background-info: $color-core-blue-0; +$color-background-success: $color-core-green-0; +$color-background-warning: $color-core-orange-0; +$color-background-danger: $color-core-red-0; +$color-background-tertiary: $color-core-neutral-200; +$color-background-secondary: $color-core-neutral-100; +$color-background-primary: $color-core-neutral-0 !default; +$color-background-disabled: $color-background-tertiary;" +`; + +exports[`integration scss scss/variables with outputReferences should match snapshot 1`] = ` +" +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + +$size-padding-xl: 1rem; +$size-padding-large: 1rem; +$size-padding-medium: 1rem; +$size-padding-small: 0.5rem; +$size-font-xl: 2.25rem; +$size-font-large: 1.5rem; +$size-font-medium: 1rem; +$size-font-small: 0.75rem; +$size-border-radius-large: 30rem; +$color-core-yellow-1100: #2d1a05; +$color-core-yellow-1000: #542a00; +$color-core-yellow-900: #944c0c; +$color-core-yellow-800: #ba7506; +$color-core-yellow-700: #dd9903; +$color-core-yellow-600: #ffbc00; +$color-core-yellow-500: #ffcd1c; +$color-core-yellow-400: #ffd943; +$color-core-yellow-300: #ffe16e; +$color-core-yellow-200: #ffe99a; +$color-core-yellow-100: #fdefcd; +$color-core-yellow-0: #fff8e2; +$color-core-neutral-1100: #040404; +$color-core-neutral-1000: #162020; +$color-core-neutral-900: #273333; +$color-core-neutral-800: #364141; +$color-core-neutral-700: #515e5f; +$color-core-neutral-600: #6e797a; +$color-core-neutral-500: #929a9b; +$color-core-neutral-400: #b0b6b7; +$color-core-neutral-300: #c8cccc; +$color-core-neutral-200: #dee1e1; +$color-core-neutral-100: #f3f4f4; +$color-core-neutral-0: #ffffff; +$color-core-orange-1100: #2d130e; +$color-core-orange-1000: #601700; +$color-core-orange-900: #962c0b; +$color-core-orange-800: #ce5511; +$color-core-orange-700: #ed7024; +$color-core-orange-600: #f57d33; +$color-core-orange-500: #fc8943; +$color-core-orange-400: #ff9c5d; +$color-core-orange-300: #ffb180; +$color-core-orange-200: #ffc6a4; +$color-core-orange-100: #fcdccc; +$color-core-orange-0: #ffede3; +$color-core-red-1100: #2b1111; +$color-core-red-1000: #6d1313; +$color-core-red-900: #992222; +$color-core-red-800: #c63434; +$color-core-red-700: #db3e3e; +$color-core-red-600: #ed4c42; +$color-core-red-500: #f76054; +$color-core-red-400: #ff7f6e; +$color-core-red-300: #ff9c8f; +$color-core-red-200: #ffb8b1; +$color-core-red-100: #ffd5d2; +$color-core-red-0: #ffeae9; +$color-core-pink-1100: #2b1721; +$color-core-pink-1000: #561231; +$color-core-pink-900: #931847; +$color-core-pink-800: #b22f5b; +$color-core-pink-700: #ce3665; +$color-core-pink-600: #e0447c; +$color-core-pink-500: #ef588b; +$color-core-pink-400: #ff76ae; +$color-core-pink-300: #ff95c1; +$color-core-pink-200: #ffb5d5; +$color-core-pink-100: #fcdbeb; +$color-core-pink-0: #ffe9f3; +$color-core-magenta-1100: #29192d; +$color-core-magenta-1000: #451551; +$color-core-magenta-900: #6c2277; +$color-core-magenta-800: #8f3896; +$color-core-magenta-700: #ac44a8; +$color-core-magenta-600: #c44eb9; +$color-core-magenta-500: #db61db; +$color-core-magenta-400: #f282f5; +$color-core-magenta-300: #edadf2; +$color-core-magenta-200: #f4c4f7; +$color-core-magenta-100: #f9e3fc; +$color-core-magenta-0: #fef0ff; +$color-core-purple-1100: #1d1d38; +$color-core-purple-1000: #2d246b; +$color-core-purple-900: #483a9c; +$color-core-purple-800: #5e4eba; +$color-core-purple-700: #6f5ed3; +$color-core-purple-600: #816fea; +$color-core-purple-500: #9180f4; +$color-core-purple-400: #a193f2; +$color-core-purple-300: #c1c1f7; +$color-core-purple-200: #d8d7f9; +$color-core-purple-100: #eaeaf9; +$color-core-purple-0: #f2f2f9; +$color-core-blue-1100: #002138; +$color-core-blue-1000: #0a3960; +$color-core-blue-900: #0c5689; +$color-core-blue-800: #116daa; +$color-core-blue-700: #2079c3; +$color-core-blue-600: #2b87d3; +$color-core-blue-500: #3896e3; +$color-core-blue-400: #56adf5; +$color-core-blue-300: #a1d2f8; +$color-core-blue-200: #c7e4f9; +$color-core-blue-100: #dcf2ff; +$color-core-blue-0: #e9f8ff; +$color-core-aqua-1100: #002838; +$color-core-aqua-1000: #083d4f; +$color-core-aqua-900: #035e73; +$color-core-aqua-800: #0f6e84; +$color-core-aqua-700: #0b8599; +$color-core-aqua-600: #0797ae; +$color-core-aqua-500: #17b8ce; +$color-core-aqua-400: #33d6e2; +$color-core-aqua-300: #76e5e2; +$color-core-aqua-200: #a5f2f2; +$color-core-aqua-100: #c5f9f9; +$color-core-aqua-0: #d9fcfb; +$color-core-teal-1100: #002528; +$color-core-teal-1000: #083f3f; +$color-core-teal-900: #026661; +$color-core-teal-800: #067c7c; +$color-core-teal-700: #0b968f; +$color-core-teal-600: #00a99c; +$color-core-teal-500: #08c4b2; +$color-core-teal-400: #24e0c5; +$color-core-teal-300: #7dead5; +$color-core-teal-200: #b3f2e6; +$color-core-teal-100: #cdf7ef; +$color-core-teal-0: #e5f9f5; +$color-core-green-1100: #002b20; +$color-core-green-1000: #08422f; +$color-core-green-900: #006b40; +$color-core-green-800: #008b46; +$color-core-green-700: #0ca750; +$color-core-green-600: #2bb656; +$color-core-green-500: #59cb59; +$color-core-green-400: #75dd66; +$color-core-green-300: #98e58e; +$color-core-green-200: #c2f2bd; +$color-core-green-100: #d7f4d7; +$color-core-green-0: #ebf9eb; +$color-font-success: $color-core-green-1000; +$color-font-warning: $color-core-orange-1000; +$color-font-danger: $color-core-red-1000; +$color-font-tertiary: $color-core-neutral-800; +$color-font-secondary: $color-core-neutral-900; +$color-font-primary: $color-core-neutral-1100; +$color-brand-secondary: $color-core-purple-700; +$color-brand-primary: $color-core-aqua-700; +$color-border-primary: $color-core-neutral-300; +$color-background-info: $color-core-blue-0; +$color-background-success: $color-core-green-0; +$color-background-warning: $color-core-orange-0; +$color-background-danger: $color-core-red-0; +$color-background-tertiary: $color-core-neutral-200; +$color-background-secondary: $color-core-neutral-100; +$color-background-primary: $color-core-neutral-0 !default; +$color-font-interactive-disabled: $color-font-tertiary; +$color-font-interactive-active: $color-brand-secondary; +$color-font-interactive-hover: $color-brand-primary; +$color-font-interactive: $color-brand-primary; +$color-background-disabled: $color-background-tertiary;" +`; diff --git a/__integration__/__snapshots__/showFileHeader.test.js.snap b/__integration__/__snapshots__/showFileHeader.test.js.snap new file mode 100644 index 000000000..9a1173c45 --- /dev/null +++ b/__integration__/__snapshots__/showFileHeader.test.js.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration showFileHeader with platform options set to false should not show file header if no file options set 1`] = ` +":root { + --size-padding-small: 0.5rem; + --size-padding-medium: 1rem; + --size-padding-large: 1rem; + --size-padding-xl: 1rem; +} +" +`; + +exports[`integration showFileHeader with platform options set to false should show file header if file options set to true 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --size-padding-small: 0.5rem; + --size-padding-medium: 1rem; + --size-padding-large: 1rem; + --size-padding-xl: 1rem; +} +" +`; + +exports[`integration showFileHeader without platform options should not show file header if file options set to false 1`] = ` +":root { + --size-padding-small: 0.5rem; + --size-padding-medium: 1rem; + --size-padding-large: 1rem; + --size-padding-xl: 1rem; +} +" +`; + +exports[`integration showFileHeader without platform options should show file header if no file options set 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --size-padding-small: 0.5rem; + --size-padding-medium: 1rem; + --size-padding-large: 1rem; + --size-padding-xl: 1rem; +} +" +`; diff --git a/__integration__/__snapshots__/swift.test.js.snap b/__integration__/__snapshots__/swift.test.js.snap new file mode 100644 index 000000000..6751f8fb6 --- /dev/null +++ b/__integration__/__snapshots__/swift.test.js.snap @@ -0,0 +1,359 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration swift ios-swift/class.swift should match snapshot 1`] = ` +" +// +// style_dictionary.swift +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +import UIKit + +public class StyleDictionary { + public static let colorBackgroundDanger = UIColor(red: 1.000, green: 0.918, blue: 0.914, alpha:1) + public static let colorBackgroundDisabled = UIColor(red: 0.871, green: 0.882, blue: 0.882, alpha:1) + public static let colorBackgroundInfo = UIColor(red: 0.914, green: 0.973, blue: 1.000, alpha:1) + public static let colorBackgroundPrimary = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha:1) + public static let colorBackgroundSecondary = UIColor(red: 0.953, green: 0.957, blue: 0.957, alpha:1) + public static let colorBackgroundSuccess = UIColor(red: 0.922, green: 0.976, blue: 0.922, alpha:1) + public static let colorBackgroundTertiary = UIColor(red: 0.871, green: 0.882, blue: 0.882, alpha:1) + public static let colorBackgroundWarning = UIColor(red: 1.000, green: 0.929, blue: 0.890, alpha:1) + public static let colorBorderPrimary = UIColor(red: 0.784, green: 0.800, blue: 0.800, alpha:1) + public static let colorBrandPrimary = UIColor(red: 0.043, green: 0.522, blue: 0.600, alpha:1) + public static let colorBrandSecondary = UIColor(red: 0.435, green: 0.369, blue: 0.827, alpha:1) + public static let colorCoreAqua0 = UIColor(red: 0.851, green: 0.988, blue: 0.984, alpha:1) + public static let colorCoreAqua100 = UIColor(red: 0.773, green: 0.976, blue: 0.976, alpha:1) + public static let colorCoreAqua1000 = UIColor(red: 0.031, green: 0.239, blue: 0.310, alpha:1) + public static let colorCoreAqua1100 = UIColor(red: 0.000, green: 0.157, blue: 0.220, alpha:1) + public static let colorCoreAqua200 = UIColor(red: 0.647, green: 0.949, blue: 0.949, alpha:1) + public static let colorCoreAqua300 = UIColor(red: 0.463, green: 0.898, blue: 0.886, alpha:1) + public static let colorCoreAqua400 = UIColor(red: 0.200, green: 0.839, blue: 0.886, alpha:1) + public static let colorCoreAqua500 = UIColor(red: 0.090, green: 0.722, blue: 0.808, alpha:1) + public static let colorCoreAqua600 = UIColor(red: 0.027, green: 0.592, blue: 0.682, alpha:1) + public static let colorCoreAqua700 = UIColor(red: 0.043, green: 0.522, blue: 0.600, alpha:1) + public static let colorCoreAqua800 = UIColor(red: 0.059, green: 0.431, blue: 0.518, alpha:1) + public static let colorCoreAqua900 = UIColor(red: 0.012, green: 0.369, blue: 0.451, alpha:1) + public static let colorCoreBlue0 = UIColor(red: 0.914, green: 0.973, blue: 1.000, alpha:1) + public static let colorCoreBlue100 = UIColor(red: 0.863, green: 0.949, blue: 1.000, alpha:1) + public static let colorCoreBlue1000 = UIColor(red: 0.039, green: 0.224, blue: 0.376, alpha:1) + public static let colorCoreBlue1100 = UIColor(red: 0.000, green: 0.129, blue: 0.220, alpha:1) + public static let colorCoreBlue200 = UIColor(red: 0.780, green: 0.894, blue: 0.976, alpha:1) + public static let colorCoreBlue300 = UIColor(red: 0.631, green: 0.824, blue: 0.973, alpha:1) + public static let colorCoreBlue400 = UIColor(red: 0.337, green: 0.678, blue: 0.961, alpha:1) + public static let colorCoreBlue500 = UIColor(red: 0.220, green: 0.588, blue: 0.890, alpha:1) + public static let colorCoreBlue600 = UIColor(red: 0.169, green: 0.529, blue: 0.827, alpha:1) + public static let colorCoreBlue700 = UIColor(red: 0.125, green: 0.475, blue: 0.765, alpha:1) + public static let colorCoreBlue800 = UIColor(red: 0.067, green: 0.427, blue: 0.667, alpha:1) + public static let colorCoreBlue900 = UIColor(red: 0.047, green: 0.337, blue: 0.537, alpha:1) + public static let colorCoreGreen0 = UIColor(red: 0.922, green: 0.976, blue: 0.922, alpha:1) + public static let colorCoreGreen100 = UIColor(red: 0.843, green: 0.957, blue: 0.843, alpha:1) + public static let colorCoreGreen1000 = UIColor(red: 0.031, green: 0.259, blue: 0.184, alpha:1) + public static let colorCoreGreen1100 = UIColor(red: 0.000, green: 0.169, blue: 0.125, alpha:1) + public static let colorCoreGreen200 = UIColor(red: 0.761, green: 0.949, blue: 0.741, alpha:1) + public static let colorCoreGreen300 = UIColor(red: 0.596, green: 0.898, blue: 0.557, alpha:1) + public static let colorCoreGreen400 = UIColor(red: 0.459, green: 0.867, blue: 0.400, alpha:1) + public static let colorCoreGreen500 = UIColor(red: 0.349, green: 0.796, blue: 0.349, alpha:1) + public static let colorCoreGreen600 = UIColor(red: 0.169, green: 0.714, blue: 0.337, alpha:1) + public static let colorCoreGreen700 = UIColor(red: 0.047, green: 0.655, blue: 0.314, alpha:1) + public static let colorCoreGreen800 = UIColor(red: 0.000, green: 0.545, blue: 0.275, alpha:1) + public static let colorCoreGreen900 = UIColor(red: 0.000, green: 0.420, blue: 0.251, alpha:1) + public static let colorCoreMagenta0 = UIColor(red: 0.996, green: 0.941, blue: 1.000, alpha:1) + public static let colorCoreMagenta100 = UIColor(red: 0.976, green: 0.890, blue: 0.988, alpha:1) + public static let colorCoreMagenta1000 = UIColor(red: 0.271, green: 0.082, blue: 0.318, alpha:1) + public static let colorCoreMagenta1100 = UIColor(red: 0.161, green: 0.098, blue: 0.176, alpha:1) + public static let colorCoreMagenta200 = UIColor(red: 0.957, green: 0.769, blue: 0.969, alpha:1) + public static let colorCoreMagenta300 = UIColor(red: 0.929, green: 0.678, blue: 0.949, alpha:1) + public static let colorCoreMagenta400 = UIColor(red: 0.949, green: 0.510, blue: 0.961, alpha:1) + public static let colorCoreMagenta500 = UIColor(red: 0.859, green: 0.380, blue: 0.859, alpha:1) + public static let colorCoreMagenta600 = UIColor(red: 0.769, green: 0.306, blue: 0.725, alpha:1) + public static let colorCoreMagenta700 = UIColor(red: 0.675, green: 0.267, blue: 0.659, alpha:1) + public static let colorCoreMagenta800 = UIColor(red: 0.561, green: 0.220, blue: 0.588, alpha:1) + public static let colorCoreMagenta900 = UIColor(red: 0.424, green: 0.133, blue: 0.467, alpha:1) + public static let colorCoreNeutral0 = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha:1) + public static let colorCoreNeutral100 = UIColor(red: 0.953, green: 0.957, blue: 0.957, alpha:1) + public static let colorCoreNeutral1000 = UIColor(red: 0.086, green: 0.125, blue: 0.125, alpha:1) + public static let colorCoreNeutral1100 = UIColor(red: 0.016, green: 0.016, blue: 0.016, alpha:1) + public static let colorCoreNeutral200 = UIColor(red: 0.871, green: 0.882, blue: 0.882, alpha:1) + public static let colorCoreNeutral300 = UIColor(red: 0.784, green: 0.800, blue: 0.800, alpha:1) + public static let colorCoreNeutral400 = UIColor(red: 0.690, green: 0.714, blue: 0.718, alpha:1) + public static let colorCoreNeutral500 = UIColor(red: 0.573, green: 0.604, blue: 0.608, alpha:1) + public static let colorCoreNeutral600 = UIColor(red: 0.431, green: 0.475, blue: 0.478, alpha:1) + public static let colorCoreNeutral700 = UIColor(red: 0.318, green: 0.369, blue: 0.373, alpha:1) + public static let colorCoreNeutral800 = UIColor(red: 0.212, green: 0.255, blue: 0.255, alpha:1) + public static let colorCoreNeutral900 = UIColor(red: 0.153, green: 0.200, blue: 0.200, alpha:1) + public static let colorCoreOrange0 = UIColor(red: 1.000, green: 0.929, blue: 0.890, alpha:1) + public static let colorCoreOrange100 = UIColor(red: 0.988, green: 0.863, blue: 0.800, alpha:1) + public static let colorCoreOrange1000 = UIColor(red: 0.376, green: 0.090, blue: 0.000, alpha:1) + public static let colorCoreOrange1100 = UIColor(red: 0.176, green: 0.075, blue: 0.055, alpha:1) + public static let colorCoreOrange200 = UIColor(red: 1.000, green: 0.776, blue: 0.643, alpha:1) + public static let colorCoreOrange300 = UIColor(red: 1.000, green: 0.694, blue: 0.502, alpha:1) + public static let colorCoreOrange400 = UIColor(red: 1.000, green: 0.612, blue: 0.365, alpha:1) + public static let colorCoreOrange500 = UIColor(red: 0.988, green: 0.537, blue: 0.263, alpha:1) + public static let colorCoreOrange600 = UIColor(red: 0.961, green: 0.490, blue: 0.200, alpha:1) + public static let colorCoreOrange700 = UIColor(red: 0.929, green: 0.439, blue: 0.141, alpha:1) + public static let colorCoreOrange800 = UIColor(red: 0.808, green: 0.333, blue: 0.067, alpha:1) + public static let colorCoreOrange900 = UIColor(red: 0.588, green: 0.173, blue: 0.043, alpha:1) + public static let colorCorePink0 = UIColor(red: 1.000, green: 0.914, blue: 0.953, alpha:1) + public static let colorCorePink100 = UIColor(red: 0.988, green: 0.859, blue: 0.922, alpha:1) + public static let colorCorePink1000 = UIColor(red: 0.337, green: 0.071, blue: 0.192, alpha:1) + public static let colorCorePink1100 = UIColor(red: 0.169, green: 0.090, blue: 0.129, alpha:1) + public static let colorCorePink200 = UIColor(red: 1.000, green: 0.710, blue: 0.835, alpha:1) + public static let colorCorePink300 = UIColor(red: 1.000, green: 0.584, blue: 0.757, alpha:1) + public static let colorCorePink400 = UIColor(red: 1.000, green: 0.463, blue: 0.682, alpha:1) + public static let colorCorePink500 = UIColor(red: 0.937, green: 0.345, blue: 0.545, alpha:1) + public static let colorCorePink600 = UIColor(red: 0.878, green: 0.267, blue: 0.486, alpha:1) + public static let colorCorePink700 = UIColor(red: 0.808, green: 0.212, blue: 0.396, alpha:1) + public static let colorCorePink800 = UIColor(red: 0.698, green: 0.184, blue: 0.357, alpha:1) + public static let colorCorePink900 = UIColor(red: 0.576, green: 0.094, blue: 0.278, alpha:1) + public static let colorCorePurple0 = UIColor(red: 0.949, green: 0.949, blue: 0.976, alpha:1) + public static let colorCorePurple100 = UIColor(red: 0.918, green: 0.918, blue: 0.976, alpha:1) + public static let colorCorePurple1000 = UIColor(red: 0.176, green: 0.141, blue: 0.420, alpha:1) + public static let colorCorePurple1100 = UIColor(red: 0.114, green: 0.114, blue: 0.220, alpha:1) + public static let colorCorePurple200 = UIColor(red: 0.847, green: 0.843, blue: 0.976, alpha:1) + public static let colorCorePurple300 = UIColor(red: 0.757, green: 0.757, blue: 0.969, alpha:1) + public static let colorCorePurple400 = UIColor(red: 0.631, green: 0.576, blue: 0.949, alpha:1) + public static let colorCorePurple500 = UIColor(red: 0.569, green: 0.502, blue: 0.957, alpha:1) + public static let colorCorePurple600 = UIColor(red: 0.506, green: 0.435, blue: 0.918, alpha:1) + public static let colorCorePurple700 = UIColor(red: 0.435, green: 0.369, blue: 0.827, alpha:1) + public static let colorCorePurple800 = UIColor(red: 0.369, green: 0.306, blue: 0.729, alpha:1) + public static let colorCorePurple900 = UIColor(red: 0.282, green: 0.227, blue: 0.612, alpha:1) + public static let colorCoreRed0 = UIColor(red: 1.000, green: 0.918, blue: 0.914, alpha:1) + public static let colorCoreRed100 = UIColor(red: 1.000, green: 0.835, blue: 0.824, alpha:1) + public static let colorCoreRed1000 = UIColor(red: 0.427, green: 0.075, blue: 0.075, alpha:1) + public static let colorCoreRed1100 = UIColor(red: 0.169, green: 0.067, blue: 0.067, alpha:1) + public static let colorCoreRed200 = UIColor(red: 1.000, green: 0.722, blue: 0.694, alpha:1) + public static let colorCoreRed300 = UIColor(red: 1.000, green: 0.612, blue: 0.561, alpha:1) + public static let colorCoreRed400 = UIColor(red: 1.000, green: 0.498, blue: 0.431, alpha:1) + public static let colorCoreRed500 = UIColor(red: 0.969, green: 0.376, blue: 0.329, alpha:1) + public static let colorCoreRed600 = UIColor(red: 0.929, green: 0.298, blue: 0.259, alpha:1) + public static let colorCoreRed700 = UIColor(red: 0.859, green: 0.243, blue: 0.243, alpha:1) + public static let colorCoreRed800 = UIColor(red: 0.776, green: 0.204, blue: 0.204, alpha:1) + public static let colorCoreRed900 = UIColor(red: 0.600, green: 0.133, blue: 0.133, alpha:1) + public static let colorCoreTeal0 = UIColor(red: 0.898, green: 0.976, blue: 0.961, alpha:1) + public static let colorCoreTeal100 = UIColor(red: 0.804, green: 0.969, blue: 0.937, alpha:1) + public static let colorCoreTeal1000 = UIColor(red: 0.031, green: 0.247, blue: 0.247, alpha:1) + public static let colorCoreTeal1100 = UIColor(red: 0.000, green: 0.145, blue: 0.157, alpha:1) + public static let colorCoreTeal200 = UIColor(red: 0.702, green: 0.949, blue: 0.902, alpha:1) + public static let colorCoreTeal300 = UIColor(red: 0.490, green: 0.918, blue: 0.835, alpha:1) + public static let colorCoreTeal400 = UIColor(red: 0.141, green: 0.878, blue: 0.773, alpha:1) + public static let colorCoreTeal500 = UIColor(red: 0.031, green: 0.769, blue: 0.698, alpha:1) + public static let colorCoreTeal600 = UIColor(red: 0.000, green: 0.663, blue: 0.612, alpha:1) + public static let colorCoreTeal700 = UIColor(red: 0.043, green: 0.588, blue: 0.561, alpha:1) + public static let colorCoreTeal800 = UIColor(red: 0.024, green: 0.486, blue: 0.486, alpha:1) + public static let colorCoreTeal900 = UIColor(red: 0.008, green: 0.400, blue: 0.380, alpha:1) + public static let colorCoreYellow0 = UIColor(red: 1.000, green: 0.973, blue: 0.886, alpha:1) + public static let colorCoreYellow100 = UIColor(red: 0.992, green: 0.937, blue: 0.804, alpha:1) + public static let colorCoreYellow1000 = UIColor(red: 0.329, green: 0.165, blue: 0.000, alpha:1) + public static let colorCoreYellow1100 = UIColor(red: 0.176, green: 0.102, blue: 0.020, alpha:1) + public static let colorCoreYellow200 = UIColor(red: 1.000, green: 0.914, blue: 0.604, alpha:1) + public static let colorCoreYellow300 = UIColor(red: 1.000, green: 0.882, blue: 0.431, alpha:1) + public static let colorCoreYellow400 = UIColor(red: 1.000, green: 0.851, blue: 0.263, alpha:1) + public static let colorCoreYellow500 = UIColor(red: 1.000, green: 0.804, blue: 0.110, alpha:1) + public static let colorCoreYellow600 = UIColor(red: 1.000, green: 0.737, blue: 0.000, alpha:1) + public static let colorCoreYellow700 = UIColor(red: 0.867, green: 0.600, blue: 0.012, alpha:1) + public static let colorCoreYellow800 = UIColor(red: 0.729, green: 0.459, blue: 0.024, alpha:1) + public static let colorCoreYellow900 = UIColor(red: 0.580, green: 0.298, blue: 0.047, alpha:1) + public static let colorFontDanger = UIColor(red: 0.427, green: 0.075, blue: 0.075, alpha:1) + public static let colorFontInteractive = UIColor(red: 0.043, green: 0.522, blue: 0.600, alpha:1) + public static let colorFontInteractiveActive = UIColor(red: 0.435, green: 0.369, blue: 0.827, alpha:1) + public static let colorFontInteractiveDisabled = UIColor(red: 0.212, green: 0.255, blue: 0.255, alpha:1) + public static let colorFontInteractiveHover = UIColor(red: 0.043, green: 0.522, blue: 0.600, alpha:1) + public static let colorFontPrimary = UIColor(red: 0.016, green: 0.016, blue: 0.016, alpha:1) + public static let colorFontSecondary = UIColor(red: 0.153, green: 0.200, blue: 0.200, alpha:1) + public static let colorFontSuccess = UIColor(red: 0.031, green: 0.259, blue: 0.184, alpha:1) + public static let colorFontTertiary = UIColor(red: 0.212, green: 0.255, blue: 0.255, alpha:1) + public static let colorFontWarning = UIColor(red: 0.376, green: 0.090, blue: 0.000, alpha:1) + public static let sizeBorderRadiusLarge = CGFloat(480.00) + public static let sizeFontLarge = CGFloat(24.00) + public static let sizeFontMedium = CGFloat(16.00) + public static let sizeFontSmall = CGFloat(12.00) + public static let sizeFontXl = CGFloat(36.00) + public static let sizePaddingLarge = CGFloat(16.00) + public static let sizePaddingMedium = CGFloat(16.00) + public static let sizePaddingSmall = CGFloat(8.00) + public static let sizePaddingXl = CGFloat(16.00) +} +" +`; + +exports[`integration swift ios-swift/class.swift with references should match snapshot 1`] = ` +" +// +// style_dictionary_with_references.swift +// + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + +import UIKit + +public class StyleDictionary { + public static let sizePaddingXl = CGFloat(16.00) + public static let sizePaddingLarge = CGFloat(16.00) + public static let sizePaddingMedium = CGFloat(16.00) + public static let sizePaddingSmall = CGFloat(8.00) + public static let sizeFontXl = CGFloat(36.00) + public static let sizeFontLarge = CGFloat(24.00) + public static let sizeFontMedium = CGFloat(16.00) + public static let sizeFontSmall = CGFloat(12.00) + public static let sizeBorderRadiusLarge = CGFloat(480.00) + public static let colorCoreYellow1100 = UIColor(red: 0.176, green: 0.102, blue: 0.020, alpha:1) + public static let colorCoreYellow1000 = UIColor(red: 0.329, green: 0.165, blue: 0.000, alpha:1) + public static let colorCoreYellow900 = UIColor(red: 0.580, green: 0.298, blue: 0.047, alpha:1) + public static let colorCoreYellow800 = UIColor(red: 0.729, green: 0.459, blue: 0.024, alpha:1) + public static let colorCoreYellow700 = UIColor(red: 0.867, green: 0.600, blue: 0.012, alpha:1) + public static let colorCoreYellow600 = UIColor(red: 1.000, green: 0.737, blue: 0.000, alpha:1) + public static let colorCoreYellow500 = UIColor(red: 1.000, green: 0.804, blue: 0.110, alpha:1) + public static let colorCoreYellow400 = UIColor(red: 1.000, green: 0.851, blue: 0.263, alpha:1) + public static let colorCoreYellow300 = UIColor(red: 1.000, green: 0.882, blue: 0.431, alpha:1) + public static let colorCoreYellow200 = UIColor(red: 1.000, green: 0.914, blue: 0.604, alpha:1) + public static let colorCoreYellow100 = UIColor(red: 0.992, green: 0.937, blue: 0.804, alpha:1) + public static let colorCoreYellow0 = UIColor(red: 1.000, green: 0.973, blue: 0.886, alpha:1) + public static let colorCoreNeutral1100 = UIColor(red: 0.016, green: 0.016, blue: 0.016, alpha:1) + public static let colorCoreNeutral1000 = UIColor(red: 0.086, green: 0.125, blue: 0.125, alpha:1) + public static let colorCoreNeutral900 = UIColor(red: 0.153, green: 0.200, blue: 0.200, alpha:1) + public static let colorCoreNeutral800 = UIColor(red: 0.212, green: 0.255, blue: 0.255, alpha:1) + public static let colorCoreNeutral700 = UIColor(red: 0.318, green: 0.369, blue: 0.373, alpha:1) + public static let colorCoreNeutral600 = UIColor(red: 0.431, green: 0.475, blue: 0.478, alpha:1) + public static let colorCoreNeutral500 = UIColor(red: 0.573, green: 0.604, blue: 0.608, alpha:1) + public static let colorCoreNeutral400 = UIColor(red: 0.690, green: 0.714, blue: 0.718, alpha:1) + public static let colorCoreNeutral300 = UIColor(red: 0.784, green: 0.800, blue: 0.800, alpha:1) + public static let colorCoreNeutral200 = UIColor(red: 0.871, green: 0.882, blue: 0.882, alpha:1) + public static let colorCoreNeutral100 = UIColor(red: 0.953, green: 0.957, blue: 0.957, alpha:1) + public static let colorCoreNeutral0 = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha:1) + public static let colorCoreOrange1100 = UIColor(red: 0.176, green: 0.075, blue: 0.055, alpha:1) + public static let colorCoreOrange1000 = UIColor(red: 0.376, green: 0.090, blue: 0.000, alpha:1) + public static let colorCoreOrange900 = UIColor(red: 0.588, green: 0.173, blue: 0.043, alpha:1) + public static let colorCoreOrange800 = UIColor(red: 0.808, green: 0.333, blue: 0.067, alpha:1) + public static let colorCoreOrange700 = UIColor(red: 0.929, green: 0.439, blue: 0.141, alpha:1) + public static let colorCoreOrange600 = UIColor(red: 0.961, green: 0.490, blue: 0.200, alpha:1) + public static let colorCoreOrange500 = UIColor(red: 0.988, green: 0.537, blue: 0.263, alpha:1) + public static let colorCoreOrange400 = UIColor(red: 1.000, green: 0.612, blue: 0.365, alpha:1) + public static let colorCoreOrange300 = UIColor(red: 1.000, green: 0.694, blue: 0.502, alpha:1) + public static let colorCoreOrange200 = UIColor(red: 1.000, green: 0.776, blue: 0.643, alpha:1) + public static let colorCoreOrange100 = UIColor(red: 0.988, green: 0.863, blue: 0.800, alpha:1) + public static let colorCoreOrange0 = UIColor(red: 1.000, green: 0.929, blue: 0.890, alpha:1) + public static let colorCoreRed1100 = UIColor(red: 0.169, green: 0.067, blue: 0.067, alpha:1) + public static let colorCoreRed1000 = UIColor(red: 0.427, green: 0.075, blue: 0.075, alpha:1) + public static let colorCoreRed900 = UIColor(red: 0.600, green: 0.133, blue: 0.133, alpha:1) + public static let colorCoreRed800 = UIColor(red: 0.776, green: 0.204, blue: 0.204, alpha:1) + public static let colorCoreRed700 = UIColor(red: 0.859, green: 0.243, blue: 0.243, alpha:1) + public static let colorCoreRed600 = UIColor(red: 0.929, green: 0.298, blue: 0.259, alpha:1) + public static let colorCoreRed500 = UIColor(red: 0.969, green: 0.376, blue: 0.329, alpha:1) + public static let colorCoreRed400 = UIColor(red: 1.000, green: 0.498, blue: 0.431, alpha:1) + public static let colorCoreRed300 = UIColor(red: 1.000, green: 0.612, blue: 0.561, alpha:1) + public static let colorCoreRed200 = UIColor(red: 1.000, green: 0.722, blue: 0.694, alpha:1) + public static let colorCoreRed100 = UIColor(red: 1.000, green: 0.835, blue: 0.824, alpha:1) + public static let colorCoreRed0 = UIColor(red: 1.000, green: 0.918, blue: 0.914, alpha:1) + public static let colorCorePink1100 = UIColor(red: 0.169, green: 0.090, blue: 0.129, alpha:1) + public static let colorCorePink1000 = UIColor(red: 0.337, green: 0.071, blue: 0.192, alpha:1) + public static let colorCorePink900 = UIColor(red: 0.576, green: 0.094, blue: 0.278, alpha:1) + public static let colorCorePink800 = UIColor(red: 0.698, green: 0.184, blue: 0.357, alpha:1) + public static let colorCorePink700 = UIColor(red: 0.808, green: 0.212, blue: 0.396, alpha:1) + public static let colorCorePink600 = UIColor(red: 0.878, green: 0.267, blue: 0.486, alpha:1) + public static let colorCorePink500 = UIColor(red: 0.937, green: 0.345, blue: 0.545, alpha:1) + public static let colorCorePink400 = UIColor(red: 1.000, green: 0.463, blue: 0.682, alpha:1) + public static let colorCorePink300 = UIColor(red: 1.000, green: 0.584, blue: 0.757, alpha:1) + public static let colorCorePink200 = UIColor(red: 1.000, green: 0.710, blue: 0.835, alpha:1) + public static let colorCorePink100 = UIColor(red: 0.988, green: 0.859, blue: 0.922, alpha:1) + public static let colorCorePink0 = UIColor(red: 1.000, green: 0.914, blue: 0.953, alpha:1) + public static let colorCoreMagenta1100 = UIColor(red: 0.161, green: 0.098, blue: 0.176, alpha:1) + public static let colorCoreMagenta1000 = UIColor(red: 0.271, green: 0.082, blue: 0.318, alpha:1) + public static let colorCoreMagenta900 = UIColor(red: 0.424, green: 0.133, blue: 0.467, alpha:1) + public static let colorCoreMagenta800 = UIColor(red: 0.561, green: 0.220, blue: 0.588, alpha:1) + public static let colorCoreMagenta700 = UIColor(red: 0.675, green: 0.267, blue: 0.659, alpha:1) + public static let colorCoreMagenta600 = UIColor(red: 0.769, green: 0.306, blue: 0.725, alpha:1) + public static let colorCoreMagenta500 = UIColor(red: 0.859, green: 0.380, blue: 0.859, alpha:1) + public static let colorCoreMagenta400 = UIColor(red: 0.949, green: 0.510, blue: 0.961, alpha:1) + public static let colorCoreMagenta300 = UIColor(red: 0.929, green: 0.678, blue: 0.949, alpha:1) + public static let colorCoreMagenta200 = UIColor(red: 0.957, green: 0.769, blue: 0.969, alpha:1) + public static let colorCoreMagenta100 = UIColor(red: 0.976, green: 0.890, blue: 0.988, alpha:1) + public static let colorCoreMagenta0 = UIColor(red: 0.996, green: 0.941, blue: 1.000, alpha:1) + public static let colorCorePurple1100 = UIColor(red: 0.114, green: 0.114, blue: 0.220, alpha:1) + public static let colorCorePurple1000 = UIColor(red: 0.176, green: 0.141, blue: 0.420, alpha:1) + public static let colorCorePurple900 = UIColor(red: 0.282, green: 0.227, blue: 0.612, alpha:1) + public static let colorCorePurple800 = UIColor(red: 0.369, green: 0.306, blue: 0.729, alpha:1) + public static let colorCorePurple700 = UIColor(red: 0.435, green: 0.369, blue: 0.827, alpha:1) + public static let colorCorePurple600 = UIColor(red: 0.506, green: 0.435, blue: 0.918, alpha:1) + public static let colorCorePurple500 = UIColor(red: 0.569, green: 0.502, blue: 0.957, alpha:1) + public static let colorCorePurple400 = UIColor(red: 0.631, green: 0.576, blue: 0.949, alpha:1) + public static let colorCorePurple300 = UIColor(red: 0.757, green: 0.757, blue: 0.969, alpha:1) + public static let colorCorePurple200 = UIColor(red: 0.847, green: 0.843, blue: 0.976, alpha:1) + public static let colorCorePurple100 = UIColor(red: 0.918, green: 0.918, blue: 0.976, alpha:1) + public static let colorCorePurple0 = UIColor(red: 0.949, green: 0.949, blue: 0.976, alpha:1) + public static let colorCoreBlue1100 = UIColor(red: 0.000, green: 0.129, blue: 0.220, alpha:1) + public static let colorCoreBlue1000 = UIColor(red: 0.039, green: 0.224, blue: 0.376, alpha:1) + public static let colorCoreBlue900 = UIColor(red: 0.047, green: 0.337, blue: 0.537, alpha:1) + public static let colorCoreBlue800 = UIColor(red: 0.067, green: 0.427, blue: 0.667, alpha:1) + public static let colorCoreBlue700 = UIColor(red: 0.125, green: 0.475, blue: 0.765, alpha:1) + public static let colorCoreBlue600 = UIColor(red: 0.169, green: 0.529, blue: 0.827, alpha:1) + public static let colorCoreBlue500 = UIColor(red: 0.220, green: 0.588, blue: 0.890, alpha:1) + public static let colorCoreBlue400 = UIColor(red: 0.337, green: 0.678, blue: 0.961, alpha:1) + public static let colorCoreBlue300 = UIColor(red: 0.631, green: 0.824, blue: 0.973, alpha:1) + public static let colorCoreBlue200 = UIColor(red: 0.780, green: 0.894, blue: 0.976, alpha:1) + public static let colorCoreBlue100 = UIColor(red: 0.863, green: 0.949, blue: 1.000, alpha:1) + public static let colorCoreBlue0 = UIColor(red: 0.914, green: 0.973, blue: 1.000, alpha:1) + public static let colorCoreAqua1100 = UIColor(red: 0.000, green: 0.157, blue: 0.220, alpha:1) + public static let colorCoreAqua1000 = UIColor(red: 0.031, green: 0.239, blue: 0.310, alpha:1) + public static let colorCoreAqua900 = UIColor(red: 0.012, green: 0.369, blue: 0.451, alpha:1) + public static let colorCoreAqua800 = UIColor(red: 0.059, green: 0.431, blue: 0.518, alpha:1) + public static let colorCoreAqua700 = UIColor(red: 0.043, green: 0.522, blue: 0.600, alpha:1) + public static let colorCoreAqua600 = UIColor(red: 0.027, green: 0.592, blue: 0.682, alpha:1) + public static let colorCoreAqua500 = UIColor(red: 0.090, green: 0.722, blue: 0.808, alpha:1) + public static let colorCoreAqua400 = UIColor(red: 0.200, green: 0.839, blue: 0.886, alpha:1) + public static let colorCoreAqua300 = UIColor(red: 0.463, green: 0.898, blue: 0.886, alpha:1) + public static let colorCoreAqua200 = UIColor(red: 0.647, green: 0.949, blue: 0.949, alpha:1) + public static let colorCoreAqua100 = UIColor(red: 0.773, green: 0.976, blue: 0.976, alpha:1) + public static let colorCoreAqua0 = UIColor(red: 0.851, green: 0.988, blue: 0.984, alpha:1) + public static let colorCoreTeal1100 = UIColor(red: 0.000, green: 0.145, blue: 0.157, alpha:1) + public static let colorCoreTeal1000 = UIColor(red: 0.031, green: 0.247, blue: 0.247, alpha:1) + public static let colorCoreTeal900 = UIColor(red: 0.008, green: 0.400, blue: 0.380, alpha:1) + public static let colorCoreTeal800 = UIColor(red: 0.024, green: 0.486, blue: 0.486, alpha:1) + public static let colorCoreTeal700 = UIColor(red: 0.043, green: 0.588, blue: 0.561, alpha:1) + public static let colorCoreTeal600 = UIColor(red: 0.000, green: 0.663, blue: 0.612, alpha:1) + public static let colorCoreTeal500 = UIColor(red: 0.031, green: 0.769, blue: 0.698, alpha:1) + public static let colorCoreTeal400 = UIColor(red: 0.141, green: 0.878, blue: 0.773, alpha:1) + public static let colorCoreTeal300 = UIColor(red: 0.490, green: 0.918, blue: 0.835, alpha:1) + public static let colorCoreTeal200 = UIColor(red: 0.702, green: 0.949, blue: 0.902, alpha:1) + public static let colorCoreTeal100 = UIColor(red: 0.804, green: 0.969, blue: 0.937, alpha:1) + public static let colorCoreTeal0 = UIColor(red: 0.898, green: 0.976, blue: 0.961, alpha:1) + public static let colorCoreGreen1100 = UIColor(red: 0.000, green: 0.169, blue: 0.125, alpha:1) + public static let colorCoreGreen1000 = UIColor(red: 0.031, green: 0.259, blue: 0.184, alpha:1) + public static let colorCoreGreen900 = UIColor(red: 0.000, green: 0.420, blue: 0.251, alpha:1) + public static let colorCoreGreen800 = UIColor(red: 0.000, green: 0.545, blue: 0.275, alpha:1) + public static let colorCoreGreen700 = UIColor(red: 0.047, green: 0.655, blue: 0.314, alpha:1) + public static let colorCoreGreen600 = UIColor(red: 0.169, green: 0.714, blue: 0.337, alpha:1) + public static let colorCoreGreen500 = UIColor(red: 0.349, green: 0.796, blue: 0.349, alpha:1) + public static let colorCoreGreen400 = UIColor(red: 0.459, green: 0.867, blue: 0.400, alpha:1) + public static let colorCoreGreen300 = UIColor(red: 0.596, green: 0.898, blue: 0.557, alpha:1) + public static let colorCoreGreen200 = UIColor(red: 0.761, green: 0.949, blue: 0.741, alpha:1) + public static let colorCoreGreen100 = UIColor(red: 0.843, green: 0.957, blue: 0.843, alpha:1) + public static let colorCoreGreen0 = UIColor(red: 0.922, green: 0.976, blue: 0.922, alpha:1) + public static let colorFontSuccess = colorCoreGreen1000 + public static let colorFontWarning = colorCoreOrange1000 + public static let colorFontDanger = colorCoreRed1000 + public static let colorFontTertiary = colorCoreNeutral800 + public static let colorFontSecondary = colorCoreNeutral900 + public static let colorFontPrimary = colorCoreNeutral1100 + public static let colorBrandSecondary = colorCorePurple700 + public static let colorBrandPrimary = colorCoreAqua700 + public static let colorBorderPrimary = colorCoreNeutral300 + public static let colorBackgroundInfo = colorCoreBlue0 + public static let colorBackgroundSuccess = colorCoreGreen0 + public static let colorBackgroundWarning = colorCoreOrange0 + public static let colorBackgroundDanger = colorCoreRed0 + public static let colorBackgroundTertiary = colorCoreNeutral200 + public static let colorBackgroundSecondary = colorCoreNeutral100 + public static let colorBackgroundPrimary = colorCoreNeutral0 + public static let colorFontInteractiveDisabled = colorFontTertiary + public static let colorFontInteractiveActive = colorBrandSecondary + public static let colorFontInteractiveHover = colorBrandPrimary + public static let colorFontInteractive = colorBrandPrimary + public static let colorBackgroundDisabled = colorBackgroundTertiary +} +" +`; diff --git a/__integration__/_constants.js b/__integration__/_constants.js new file mode 100644 index 000000000..6bdb7c823 --- /dev/null +++ b/__integration__/_constants.js @@ -0,0 +1,10 @@ +module.exports = { + buildPath: `__integration__/build/`, + cleanConsoleOutput: (str) => { + const arr = str.split(`\n`) + // Remove ANSI stuff from the console output so we get human-readable strings + // https://github.com/chalk/ansi-regex/blob/main/index.js#L3 + .map(s => s.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,'').trim()); + return arr.join(`\n`) + } +} \ No newline at end of file diff --git a/__integration__/android.test.js b/__integration__/android.test.js new file mode 100644 index 000000000..83f0d2c8b --- /dev/null +++ b/__integration__/android.test.js @@ -0,0 +1,75 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('android', () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + android: { + transformGroup: `android`, + buildPath, + files: [{ + destination: `resources.xml`, + format: `android/resources` + },{ + destination: `resourcesWithReferences.xml`, + format: `android/resources`, + options: { + outputReferences: true + } + },{ + destination: `colors.xml`, + format: `android/resources`, + filter: { + attributes: { category: `color` } + } + }] + } + } + }).buildAllPlatforms(); + + describe(`android/resources`, () => { + const output = fs.readFileSync(`${buildPath}resources.xml`, {encoding:'UTF-8'}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}resourcesWithReferences.xml`, {encoding:'UTF-8'}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + }); + + describe(`with filter`, () => { + const output = fs.readFileSync(`${buildPath}colors.xml`, {encoding:'UTF-8'}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/compose.test.js b/__integration__/compose.test.js new file mode 100644 index 000000000..6a6b88979 --- /dev/null +++ b/__integration__/compose.test.js @@ -0,0 +1,65 @@ +/* + * Copyright Target Corporation. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('compose', () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + compose: { + transformGroup: `compose`, + buildPath, + files: [{ + destination: "StyleDictionary.kt", + format: "compose/object", + className: "StyleDictionary", + packageName: "com.example.tokens" + },{ + destination: "StyleDictionaryWithReferences.kt", + format: "compose/object", + className: "StyleDictionary", + packageName: "com.example.tokens", + options: { + outputReferences: true + } + }] + }, + } + }).buildAllPlatforms(); + + describe(`compose/object`, () => { + const output = fs.readFileSync(`${buildPath}StyleDictionary.kt`, {encoding:`UTF-8`}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}StyleDictionaryWithReferences.kt`, {encoding:`UTF-8`}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/css.test.js b/__integration__/css.test.js new file mode 100644 index 000000000..cfc4dd50f --- /dev/null +++ b/__integration__/css.test.js @@ -0,0 +1,83 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('css', () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + // Testing proper string interpolation with multiple references here. + // This is a CSS/web-specific thing so only including them in this + // integration test. + properties: { + breakpoint: { + xs: { value: "304px" }, + sm: { value: "768px" }, + md: { value: "calc({breakpoint.xs.value} / {breakpoint.sm.value})"} + } + }, + platforms: { + css: { + transformGroup: 'css', + buildPath, + files: [{ + destination: 'variables.css', + format: 'css/variables' + },{ + destination: 'variablesWithReferences.css', + format: 'css/variables', + options: { + outputReferences: true + } + },{ + destination: 'variablesWithSelector.css', + format: 'css/variables', + options: { + selector: '.test' + } + }] + } + } + }).buildAllPlatforms(); + + describe('css/variables', () => { + const output = fs.readFileSync(`${buildPath}variables.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}variablesWithReferences.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + + describe(`with selector`, () => { + const output = fs.readFileSync(`${buildPath}variablesWithSelector.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + + // TODO: add css validator + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/customFileHeader.test.js b/__integration__/customFileHeader.test.js new file mode 100644 index 000000000..733e0a311 --- /dev/null +++ b/__integration__/customFileHeader.test.js @@ -0,0 +1,156 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe(`integration`, () => { + describe(`valid custom file headers`, () => { + // Adding a custom file header with the `.registerFileHeader` + StyleDictionary.registerFileHeader({ + name: `registeredFileHeader`, + fileHeader: (defaultMessage) => { + return [ + `hello`, + ...defaultMessage + ] + } + }); + + StyleDictionary.extend({ + fileHeader: { + configFileHeader: (defaultMessage) => { + return [ + ...defaultMessage, + 'hello, world!' + ]; + } + }, + + // only testing the file header in these tests so we are + // using a small properties object with a single token + properties: { + color: { + red: { value: '#ff0000' } + } + }, + + platforms: { + css: { + transformGroup: `css`, + buildPath, + files: [{ + destination: `registeredFileHeader.css`, + format: `css/variables`, + options: { + fileHeader: `registeredFileHeader` + } + },{ + destination: `configFileHeader.css`, + format: `css/variables`, + options: { + fileHeader: `configFileHeader` + } + },{ + destination: `inlineFileHeader.css`, + format: `css/variables`, + options: { + fileHeader: () => { + return [ + `build version 1.0.0` + ] + } + } + }] + }, + js: { + transformGroup: `js`, + buildPath, + options: { + fileHeader: `configFileHeader` + }, + files: [{ + destination: `noOptions.js`, + format: `javascript/module` + },{ + destination: `showFileHeader.js`, + format: `javascript/module`, + options: { + showFileHeader: false + } + },{ + destination: `fileHeaderOverride.js`, + format: `javascript/module`, + options: { + fileHeader: () => [`Header overridden`] + } + }] + } + } + }).buildAllPlatforms(); + + describe('file options', () => { + it(`registered file header should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}registeredFileHeader.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + + it(`config file header should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}configFileHeader.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + + it(`inline file header should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}inlineFileHeader.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + }); + + describe('platform options', () => { + it(`no file options should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}noOptions.js`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + + it(`showFileHeader should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}showFileHeader.js`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + + it(`file header override should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}fileHeaderOverride.js`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + }); + }); + describe(`invalid custom file headers`, () => { + it(`should throw if trying to use an undefined file header`, () => { + expect(() => { + StyleDictionary.extend({ + platforms: { + css: { + buildPath, + files: [{ + destination: `variables.css`, + options: { + fileHeader: `nonexistentFileHeader` + } + }] + } + } + }).buildAllPlatforms(); + }).toThrow(`Can't find fileHeader: nonexistentFileHeader`); + }); + }); +}); diff --git a/__integration__/customFormats.test.js b/__integration__/customFormats.test.js new file mode 100644 index 000000000..c63493b54 --- /dev/null +++ b/__integration__/customFormats.test.js @@ -0,0 +1,166 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('custom formats', () => { + const styleDictionary = StyleDictionary.extend({ + source: [`__integration__/tokens/size/padding.json`], + // Adding formats directly to SD + format: { + inlineCustomFormatWithOldArgs: (dictionary, platform, file) => { + return JSON.stringify({dictionary, platform, file}, null, 2); + }, + inlineCustomFormatWithNewArgs: (opts) => { + return JSON.stringify(opts, null, 2); + }, + }, + platforms: { + inlineCustomFormats: { + transformGroup: 'js', + buildPath, + options: { + otherOption: `platform option` + }, + files: [{ + destination: 'inlineCustomFormatWithOldArgs.json', + format: 'inlineCustomFormatWithOldArgs', + options: { + showFileHeader: true, + otherOption: 'Test' + } + },{ + destination: 'inlineCustomFormatWithNewArgs.json', + format: 'inlineCustomFormatWithNewArgs', + options: { + showFileHeader: true, + otherOption: 'Test' + } + }] + }, + customFormats: { + transformGroup: 'js', + buildPath, + options: { + otherOption: `platform option` + }, + files: [{ + destination: 'registerCustomFormatWithOldArgs.json', + format: 'registerCustomFormatWithOldArgs', + options: { + showFileHeader: true, + otherOption: 'Test' + } + },{ + destination: 'registerCustomFormatWithNewArgs.json', + format: 'registerCustomFormatWithNewArgs', + options: { + showFileHeader: true, + otherOption: 'Test' + } + }] + } + } + }); + + styleDictionary.registerFormat({ + name: 'registerCustomFormatWithOldArgs', + formatter: (dictionary, platform, file) => { + return JSON.stringify({dictionary, platform, file}, null, 2); + } + }); + + styleDictionary.registerFormat({ + name: 'registerCustomFormatWithNewArgs', + formatter: (opts) => { + return JSON.stringify(opts, null, 2); + } + }); + + styleDictionary.buildAllPlatforms(); + + describe(`inline custom with old args`, () => { + const output = fs.readFileSync(`${buildPath}inlineCustomFormatWithOldArgs.json`, {encoding:'UTF-8'}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + it(`should receive proper arguments`, () => { + const { dictionary, platform, file } = JSON.parse(output); + expect(dictionary).toHaveProperty(`properties`); + expect(dictionary).toHaveProperty(`allProperties`); + expect(platform).toHaveProperty(`options.otherOption`, `platform option`); + expect(file).toHaveProperty(`options.otherOption`, `Test`); + }); + }); + + describe(`inline custom with new args`, () => { + const output = fs.readFileSync(`${buildPath}inlineCustomFormatWithNewArgs.json`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + it(`should receive proper arguments`, () => { + const { dictionary, platform, file, options } = JSON.parse(output); + expect(dictionary).toHaveProperty(`properties`); + expect(dictionary).toHaveProperty(`allProperties`); + expect(platform).toHaveProperty(`options.otherOption`, `platform option`); + expect(file).toHaveProperty(`options.otherOption`, `Test`); + expect(options).toHaveProperty(`otherOption`, `Test`); + }); + }); + + + describe(`register custom format with old args`, () => { + const output = fs.readFileSync(`${buildPath}registerCustomFormatWithOldArgs.json`, {encoding:'UTF-8'}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + it(`should receive proper arguments`, () => { + const { dictionary, platform, file } = JSON.parse(output); + expect(dictionary).toHaveProperty(`properties`); + expect(dictionary).toHaveProperty(`allProperties`); + expect(platform).toHaveProperty(`options.otherOption`, `platform option`); + expect(file).toHaveProperty(`options.otherOption`, `Test`); + }); + }); + + describe(`register custom format with new args`, () => { + const output = fs.readFileSync(`${buildPath}registerCustomFormatWithNewArgs.json`, {encoding:'UTF-8'}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + it(`should receive proper arguments`, () => { + const { dictionary, platform, file, options } = JSON.parse(output); + expect(dictionary).toHaveProperty(`properties`); + expect(dictionary).toHaveProperty(`allProperties`); + expect(platform).toHaveProperty(`options.otherOption`, `platform option`); + expect(file).toHaveProperty(`options.otherOption`, `Test`); + expect(options).toHaveProperty(`otherOption`, `Test`); + }); + }); + + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/flutter.test.js b/__integration__/flutter.test.js new file mode 100644 index 000000000..f06f5994f --- /dev/null +++ b/__integration__/flutter.test.js @@ -0,0 +1,95 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('flutter', () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + flutter: { + transformGroup: `flutter`, + buildPath, + files: [{ + destination: "style_dictionary.dart", + format: "flutter/class.dart", + className: "StyleDictionary" + },{ + destination: "style_dictionary_with_references.dart", + format: "flutter/class.dart", + className: "StyleDictionary", + options: { + outputReferences: true + } + }] + }, + flutter_separate: { + transformGroup: `flutter-separate`, + buildPath, + files: [{ + destination: "style_dictionary_color.dart", + format: "flutter/class.dart", + className: "StyleDictionaryColor", + type: "color", + filter: { + attributes: { + category: "color" + } + } + },{ + destination: "style_dictionary_sizes.dart", + format: "flutter/class.dart", + className: "StyleDictionarySize", + type: "float", + filter: { + attributes: { + category: "size" + } + } + }] + } + } + }).buildAllPlatforms(); + + describe(`flutter/class.dart`, () => { + const output = fs.readFileSync(`${buildPath}style_dictionary.dart`, {encoding:`UTF-8`}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}style_dictionary_with_references.dart`, {encoding:`UTF-8`}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + }); + + describe(`separate`, () => { + const output = fs.readFileSync(`${buildPath}style_dictionary_color.dart`,{encoding:`UTF-8`}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }) + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/iOSObjectiveC.test.js b/__integration__/iOSObjectiveC.test.js new file mode 100644 index 000000000..3da74aedd --- /dev/null +++ b/__integration__/iOSObjectiveC.test.js @@ -0,0 +1,105 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('ios objective-c', () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + flutter: { + transformGroup: `ios`, + buildPath, + files: [{ + destination: "singleton.m", + format: "ios/singleton.m", + className: "StyleDictionary" + },{ + destination: "singleton.h", + format: "ios/singleton.h", + className: "StyleDictionary" + },{ + destination: "color.h", + format: "ios/colors.h", + className: "StyleDictionaryColor", + type: "StyleDictionaryColorName", + filter: (token) => token.attributes.category === 'color' + },{ + destination: "color.m", + format: "ios/colors.m", + className: "StyleDictionaryColor", + type: "StyleDictionaryColorName", + filter: (token) => token.attributes.category === 'color' + },{ + destination: "macros.h", + format: "ios/macros", + },{ + destination: "static.h", + format: "ios/static.h", + className: "StyleDictionaryStatic", + type: "CGFloat", + filter: (token) => token.attributes.category === 'size' + },{ + destination: "static.m", + format: "ios/static.m", + className: "StyleDictionaryStatic", + type: "CGFloat", + filter: (token) => token.attributes.category === 'size' + }] + }, + } + }).buildAllPlatforms(); + + it(`ios/singleton.m should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}singleton.m`, {encoding:`UTF-8`}); + expect(output).toMatchSnapshot(); + }); + + it(`ios/singleton.h should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}singleton.h`, {encoding:`UTF-8`}); + expect(output).toMatchSnapshot(); + }); + + it(`ios/color.m should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}color.m`, {encoding:`UTF-8`}); + expect(output).toMatchSnapshot(); + }); + + it(`ios/color.h should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}color.h`, {encoding:`UTF-8`}); + expect(output).toMatchSnapshot(); + }); + + it(`ios/macros.h should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}macros.h`, {encoding:`UTF-8`}); + expect(output).toMatchSnapshot(); + }); + + it(`ios/static.h should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}static.h`, {encoding:`UTF-8`}); + expect(output).toMatchSnapshot(); + }); + + it(`ios/static.m should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}static.m`, {encoding:`UTF-8`}); + expect(output).toMatchSnapshot(); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/logging/__snapshots__/config.test.js.snap b/__integration__/logging/__snapshots__/config.test.js.snap new file mode 100644 index 000000000..f4a2e2791 --- /dev/null +++ b/__integration__/logging/__snapshots__/config.test.js.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration > logging > config > property value collisions should not show warnings if given higher log level 1`] = ` +" +Property Value Collisions: +Collision detected at: size.padding.small! Original value: 0.5, New value: 0.5 +Collision detected at: size.padding.small! Original value: __integration__/tokens/size/padding.json, New value: __integration__/tokens/size/padding.json +Collision detected at: size.padding.small! Original value: true, New value: true +Collision detected at: size.padding.medium! Original value: 1, New value: 1 +Collision detected at: size.padding.medium! Original value: __integration__/tokens/size/padding.json, New value: __integration__/tokens/size/padding.json +Collision detected at: size.padding.medium! Original value: true, New value: true +Collision detected at: size.padding.large! Original value: 1, New value: 1 +Collision detected at: size.padding.large! Original value: __integration__/tokens/size/padding.json, New value: __integration__/tokens/size/padding.json +Collision detected at: size.padding.large! Original value: true, New value: true +Collision detected at: size.padding.xl! Original value: 1, New value: 1 +Collision detected at: size.padding.xl! Original value: __integration__/tokens/size/padding.json, New value: __integration__/tokens/size/padding.json +Collision detected at: size.padding.xl! Original value: true, New value: true + +" +`; + +exports[`integration > logging > config > property value collisions should not throw, but notify users by default 1`] = ` +" +Property Value Collisions: +Collision detected at: size.padding.small! Original value: 0.5, New value: 0.5 +Collision detected at: size.padding.small! Original value: __integration__/tokens/size/padding.json, New value: __integration__/tokens/size/padding.json +Collision detected at: size.padding.small! Original value: true, New value: true +Collision detected at: size.padding.medium! Original value: 1, New value: 1 +Collision detected at: size.padding.medium! Original value: __integration__/tokens/size/padding.json, New value: __integration__/tokens/size/padding.json +Collision detected at: size.padding.medium! Original value: true, New value: true +Collision detected at: size.padding.large! Original value: 1, New value: 1 +Collision detected at: size.padding.large! Original value: __integration__/tokens/size/padding.json, New value: __integration__/tokens/size/padding.json +Collision detected at: size.padding.large! Original value: true, New value: true +Collision detected at: size.padding.xl! Original value: 1, New value: 1 +Collision detected at: size.padding.xl! Original value: __integration__/tokens/size/padding.json, New value: __integration__/tokens/size/padding.json +Collision detected at: size.padding.xl! Original value: true, New value: true + +" +`; diff --git a/__integration__/logging/__snapshots__/file.test.js.snap b/__integration__/logging/__snapshots__/file.test.js.snap new file mode 100644 index 000000000..9691896ce --- /dev/null +++ b/__integration__/logging/__snapshots__/file.test.js.snap @@ -0,0 +1,401 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration logging file should not warn user of empty properties with log level set to error 1`] = ` +" +css +No properties for empty.css. File not created." +`; + +exports[`integration logging file should not warn user of filtered references with log level set to error 1`] = ` +" +css +⚠️ __integration__/build/filteredReferences.css +While building filteredReferences.css, filtered out token references were found; output may be unexpected. Here are the references that are used but not defined in the file +color.core.neutral.100 +color.core.neutral.0 +color.core.neutral.200 +color.core.red.0 +color.core.orange.0 +color.core.green.0 +color.core.blue.0 +This is caused when combining a filter and \`outputReferences\`." +`; + +exports[`integration logging file should not warn user of name collisions with log level set to error 1`] = ` +" +css +⚠️ __integration__/build/nameCollisions.css +While building nameCollisions.css, token collisions were found; output may be unexpected. +Output name 0 was generated by: +color.core.green.0 #ebf9eb +color.core.teal.0 #e5f9f5 +color.core.aqua.0 #d9fcfb +color.core.blue.0 #e9f8ff +color.core.purple.0 #f2f2f9 +color.core.magenta.0 #fef0ff +color.core.pink.0 #ffe9f3 +color.core.red.0 #ffeae9 +color.core.orange.0 #ffede3 +color.core.neutral.0 #FFFFFF +color.core.yellow.0 #fff8e2 +Output name 100 was generated by: +color.core.green.100 #d7f4d7 +color.core.teal.100 #cdf7ef +color.core.aqua.100 #c5f9f9 +color.core.blue.100 #dcf2ff +color.core.purple.100 #eaeaf9 +color.core.magenta.100 #f9e3fc +color.core.pink.100 #fcdbeb +color.core.red.100 #ffd5d2 +color.core.orange.100 #fcdccc +color.core.neutral.100 #f3f4f4 +color.core.yellow.100 #fdefcd +Output name 200 was generated by: +color.core.green.200 #c2f2bd +color.core.teal.200 #b3f2e6 +color.core.aqua.200 #a5f2f2 +color.core.blue.200 #c7e4f9 +color.core.purple.200 #d8d7f9 +color.core.magenta.200 #f4c4f7 +color.core.pink.200 #ffb5d5 +color.core.red.200 #ffb8b1 +color.core.orange.200 #ffc6a4 +color.core.neutral.200 #dee1e1 +color.core.yellow.200 #ffe99a +Output name 300 was generated by: +color.core.green.300 #98e58e +color.core.teal.300 #7dead5 +color.core.aqua.300 #76e5e2 +color.core.blue.300 #a1d2f8 +color.core.purple.300 #c1c1f7 +color.core.magenta.300 #edadf2 +color.core.pink.300 #ff95c1 +color.core.red.300 #ff9c8f +color.core.orange.300 #ffb180 +color.core.neutral.300 #c8cccc +color.core.yellow.300 #ffe16e +Output name 400 was generated by: +color.core.green.400 #75dd66 +color.core.teal.400 #24e0c5 +color.core.aqua.400 #33d6e2 +color.core.blue.400 #56adf5 +color.core.purple.400 #a193f2 +color.core.magenta.400 #f282f5 +color.core.pink.400 #ff76ae +color.core.red.400 #ff7f6e +color.core.orange.400 #ff9c5d +color.core.neutral.400 #b0b6b7 +color.core.yellow.400 #ffd943 +Output name 500 was generated by: +color.core.green.500 #59cb59 +color.core.teal.500 #08c4b2 +color.core.aqua.500 #17b8ce +color.core.blue.500 #3896e3 +color.core.purple.500 #9180f4 +color.core.magenta.500 #db61db +color.core.pink.500 #ef588b +color.core.red.500 #f76054 +color.core.orange.500 #fc8943 +color.core.neutral.500 #929a9b +color.core.yellow.500 #ffcd1c +Output name 600 was generated by: +color.core.green.600 #2bb656 +color.core.teal.600 #00a99c +color.core.aqua.600 #0797ae +color.core.blue.600 #2b87d3 +color.core.purple.600 #816fea +color.core.magenta.600 #c44eb9 +color.core.pink.600 #e0447c +color.core.red.600 #ed4c42 +color.core.orange.600 #f57d33 +color.core.neutral.600 #6e797a +color.core.yellow.600 #ffbc00 +Output name 700 was generated by: +color.core.green.700 #0ca750 +color.core.teal.700 #0b968f +color.core.aqua.700 #0b8599 +color.core.blue.700 #2079c3 +color.core.purple.700 #6f5ed3 +color.core.magenta.700 #ac44a8 +color.core.pink.700 #ce3665 +color.core.red.700 #db3e3e +color.core.orange.700 #ed7024 +color.core.neutral.700 #515e5f +color.core.yellow.700 #dd9903 +Output name 800 was generated by: +color.core.green.800 #008b46 +color.core.teal.800 #067c7c +color.core.aqua.800 #0f6e84 +color.core.blue.800 #116daa +color.core.purple.800 #5e4eba +color.core.magenta.800 #8f3896 +color.core.pink.800 #b22f5b +color.core.red.800 #c63434 +color.core.orange.800 #ce5511 +color.core.neutral.800 #364141 +color.core.yellow.800 #ba7506 +Output name 900 was generated by: +color.core.green.900 #006b40 +color.core.teal.900 #026661 +color.core.aqua.900 #035e73 +color.core.blue.900 #0c5689 +color.core.purple.900 #483a9c +color.core.magenta.900 #6c2277 +color.core.pink.900 #931847 +color.core.red.900 #992222 +color.core.orange.900 #962c0b +color.core.neutral.900 #273333 +color.core.yellow.900 #944c0c +Output name 1000 was generated by: +color.core.green.1000 #08422f +color.core.teal.1000 #083f3f +color.core.aqua.1000 #083d4f +color.core.blue.1000 #0a3960 +color.core.purple.1000 #2d246b +color.core.magenta.1000 #451551 +color.core.pink.1000 #561231 +color.core.red.1000 #6d1313 +color.core.orange.1000 #601700 +color.core.neutral.1000 #162020 +color.core.yellow.1000 #542a00 +Output name 1100 was generated by: +color.core.green.1100 #002b20 +color.core.teal.1100 #002528 +color.core.aqua.1100 #002838 +color.core.blue.1100 #002138 +color.core.purple.1100 #1d1d38 +color.core.magenta.1100 #29192d +color.core.pink.1100 #2b1721 +color.core.red.1100 #2b1111 +color.core.orange.1100 #2d130e +color.core.neutral.1100 #040404 +color.core.yellow.1100 #2d1a05 +Output name primary was generated by: +color.background.primary #FFFFFF +color.border.primary #c8cccc +color.brand.primary #0b8599 +color.font.primary #040404 +Output name secondary was generated by: +color.background.secondary #f3f4f4 +color.brand.secondary #6f5ed3 +color.font.secondary #273333 +Output name tertiary was generated by: +color.background.tertiary #dee1e1 +color.font.tertiary #364141 +Output name danger was generated by: +color.background.danger #ffeae9 +color.font.danger #6d1313 +Output name warning was generated by: +color.background.warning #ffede3 +color.font.warning #601700 +Output name success was generated by: +color.background.success #ebf9eb +color.font.success #08422f +Output name disabled was generated by: +color.background.disabled #dee1e1 +color.font.interactive.disabled #364141 +This many-to-one issue is usually caused by some combination of: +* conflicting or similar paths/names in property definitions +* platform transforms/transformGroups affecting names, especially when removing specificity +* overly inclusive file filters" +`; + +exports[`integration logging file should warn user empty properties 1`] = ` +" +css +No properties for empty.css. File not created." +`; + +exports[`integration logging file should warn user of filtered references 1`] = ` +" +css +⚠️ __integration__/build/filteredReferences.css +While building filteredReferences.css, filtered out token references were found; output may be unexpected. Here are the references that are used but not defined in the file +color.core.neutral.100 +color.core.neutral.0 +color.core.neutral.200 +color.core.red.0 +color.core.orange.0 +color.core.green.0 +color.core.blue.0 +This is caused when combining a filter and \`outputReferences\`." +`; + +exports[`integration logging file should warn user of name collisions 1`] = ` +" +css +⚠️ __integration__/build/nameCollisions.css +While building nameCollisions.css, token collisions were found; output may be unexpected. +Output name 0 was generated by: +color.core.green.0 #ebf9eb +color.core.teal.0 #e5f9f5 +color.core.aqua.0 #d9fcfb +color.core.blue.0 #e9f8ff +color.core.purple.0 #f2f2f9 +color.core.magenta.0 #fef0ff +color.core.pink.0 #ffe9f3 +color.core.red.0 #ffeae9 +color.core.orange.0 #ffede3 +color.core.neutral.0 #FFFFFF +color.core.yellow.0 #fff8e2 +Output name 100 was generated by: +color.core.green.100 #d7f4d7 +color.core.teal.100 #cdf7ef +color.core.aqua.100 #c5f9f9 +color.core.blue.100 #dcf2ff +color.core.purple.100 #eaeaf9 +color.core.magenta.100 #f9e3fc +color.core.pink.100 #fcdbeb +color.core.red.100 #ffd5d2 +color.core.orange.100 #fcdccc +color.core.neutral.100 #f3f4f4 +color.core.yellow.100 #fdefcd +Output name 200 was generated by: +color.core.green.200 #c2f2bd +color.core.teal.200 #b3f2e6 +color.core.aqua.200 #a5f2f2 +color.core.blue.200 #c7e4f9 +color.core.purple.200 #d8d7f9 +color.core.magenta.200 #f4c4f7 +color.core.pink.200 #ffb5d5 +color.core.red.200 #ffb8b1 +color.core.orange.200 #ffc6a4 +color.core.neutral.200 #dee1e1 +color.core.yellow.200 #ffe99a +Output name 300 was generated by: +color.core.green.300 #98e58e +color.core.teal.300 #7dead5 +color.core.aqua.300 #76e5e2 +color.core.blue.300 #a1d2f8 +color.core.purple.300 #c1c1f7 +color.core.magenta.300 #edadf2 +color.core.pink.300 #ff95c1 +color.core.red.300 #ff9c8f +color.core.orange.300 #ffb180 +color.core.neutral.300 #c8cccc +color.core.yellow.300 #ffe16e +Output name 400 was generated by: +color.core.green.400 #75dd66 +color.core.teal.400 #24e0c5 +color.core.aqua.400 #33d6e2 +color.core.blue.400 #56adf5 +color.core.purple.400 #a193f2 +color.core.magenta.400 #f282f5 +color.core.pink.400 #ff76ae +color.core.red.400 #ff7f6e +color.core.orange.400 #ff9c5d +color.core.neutral.400 #b0b6b7 +color.core.yellow.400 #ffd943 +Output name 500 was generated by: +color.core.green.500 #59cb59 +color.core.teal.500 #08c4b2 +color.core.aqua.500 #17b8ce +color.core.blue.500 #3896e3 +color.core.purple.500 #9180f4 +color.core.magenta.500 #db61db +color.core.pink.500 #ef588b +color.core.red.500 #f76054 +color.core.orange.500 #fc8943 +color.core.neutral.500 #929a9b +color.core.yellow.500 #ffcd1c +Output name 600 was generated by: +color.core.green.600 #2bb656 +color.core.teal.600 #00a99c +color.core.aqua.600 #0797ae +color.core.blue.600 #2b87d3 +color.core.purple.600 #816fea +color.core.magenta.600 #c44eb9 +color.core.pink.600 #e0447c +color.core.red.600 #ed4c42 +color.core.orange.600 #f57d33 +color.core.neutral.600 #6e797a +color.core.yellow.600 #ffbc00 +Output name 700 was generated by: +color.core.green.700 #0ca750 +color.core.teal.700 #0b968f +color.core.aqua.700 #0b8599 +color.core.blue.700 #2079c3 +color.core.purple.700 #6f5ed3 +color.core.magenta.700 #ac44a8 +color.core.pink.700 #ce3665 +color.core.red.700 #db3e3e +color.core.orange.700 #ed7024 +color.core.neutral.700 #515e5f +color.core.yellow.700 #dd9903 +Output name 800 was generated by: +color.core.green.800 #008b46 +color.core.teal.800 #067c7c +color.core.aqua.800 #0f6e84 +color.core.blue.800 #116daa +color.core.purple.800 #5e4eba +color.core.magenta.800 #8f3896 +color.core.pink.800 #b22f5b +color.core.red.800 #c63434 +color.core.orange.800 #ce5511 +color.core.neutral.800 #364141 +color.core.yellow.800 #ba7506 +Output name 900 was generated by: +color.core.green.900 #006b40 +color.core.teal.900 #026661 +color.core.aqua.900 #035e73 +color.core.blue.900 #0c5689 +color.core.purple.900 #483a9c +color.core.magenta.900 #6c2277 +color.core.pink.900 #931847 +color.core.red.900 #992222 +color.core.orange.900 #962c0b +color.core.neutral.900 #273333 +color.core.yellow.900 #944c0c +Output name 1000 was generated by: +color.core.green.1000 #08422f +color.core.teal.1000 #083f3f +color.core.aqua.1000 #083d4f +color.core.blue.1000 #0a3960 +color.core.purple.1000 #2d246b +color.core.magenta.1000 #451551 +color.core.pink.1000 #561231 +color.core.red.1000 #6d1313 +color.core.orange.1000 #601700 +color.core.neutral.1000 #162020 +color.core.yellow.1000 #542a00 +Output name 1100 was generated by: +color.core.green.1100 #002b20 +color.core.teal.1100 #002528 +color.core.aqua.1100 #002838 +color.core.blue.1100 #002138 +color.core.purple.1100 #1d1d38 +color.core.magenta.1100 #29192d +color.core.pink.1100 #2b1721 +color.core.red.1100 #2b1111 +color.core.orange.1100 #2d130e +color.core.neutral.1100 #040404 +color.core.yellow.1100 #2d1a05 +Output name primary was generated by: +color.background.primary #FFFFFF +color.border.primary #c8cccc +color.brand.primary #0b8599 +color.font.primary #040404 +Output name secondary was generated by: +color.background.secondary #f3f4f4 +color.brand.secondary #6f5ed3 +color.font.secondary #273333 +Output name tertiary was generated by: +color.background.tertiary #dee1e1 +color.font.tertiary #364141 +Output name danger was generated by: +color.background.danger #ffeae9 +color.font.danger #6d1313 +Output name warning was generated by: +color.background.warning #ffede3 +color.font.warning #601700 +Output name success was generated by: +color.background.success #ebf9eb +color.font.success #08422f +Output name disabled was generated by: +color.background.disabled #dee1e1 +color.font.interactive.disabled #364141 +This many-to-one issue is usually caused by some combination of: +* conflicting or similar paths/names in property definitions +* platform transforms/transformGroups affecting names, especially when removing specificity +* overly inclusive file filters" +`; diff --git a/__integration__/logging/__snapshots__/platform.test.js.snap b/__integration__/logging/__snapshots__/platform.test.js.snap new file mode 100644 index 000000000..282070757 --- /dev/null +++ b/__integration__/logging/__snapshots__/platform.test.js.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`integration logging platform property reference errors circular references should throw notify users 1`] = ` +" +css + +Property Reference Errors: +Circular definition cycle: color.foo.value, color.foo.value, color.foo.value +Circular definition cycle: color.teal.value, color.blue.value, color.green.value, color.teal.value + +" +`; + +exports[`integration logging platform property reference errors should throw and notify users of unknown references 1`] = ` +" +css + +Property Reference Errors: +Reference doesn't exist: color.danger.value tries to reference color.red.value, which is not defined + +" +`; + +exports[`integration logging platform should throw and notify users of unknown actions 1`] = ` +" +css" +`; + +exports[`integration logging platform should throw and notify users of unknown transformGroups 1`] = ` +" +css" +`; + +exports[`integration logging platform should throw and notify users of unknown transforms 1`] = ` +" +css" +`; diff --git a/__integration__/logging/config.test.js b/__integration__/logging/config.test.js new file mode 100644 index 000000000..7cb3bad61 --- /dev/null +++ b/__integration__/logging/config.test.js @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../../index'); +const {buildPath, cleanConsoleOutput} = require('../_constants'); + +// Spy on console.log and add all messages to an array +let consoleOutput = []; +const log = jest.spyOn(console, "log") + .mockImplementation(message => consoleOutput.push(message)) + +/** + * These integration tests will verify the behavior and logging at the *config* + * level. These messages happen when `.extend()` is called to verify + * proper configuration such as source being an array. This will also check + * for collisions in source files and any errors that happen when parsing + * and merging properties. This is the first of 3 phases of logging, the + * next two are: platform and file. + */ +describe(`integration >`, () => { + // before each test clear the mocked console.log and the output array + beforeEach(() => { + log.mockClear(); + consoleOutput = []; + }); + + describe(`logging >`, () => { + describe(`config >`, () => { + describe(`property value collisions`, () => { + it(`should not throw, but notify users by default`, () => { + StyleDictionary.extend({ + source: [ + // including a specific file twice will throw value collision warnings + `__integration__/tokens/size/padding.json`, + `__integration__/tokens/size/padding.json` + ], + platforms: { + } + }); + expect(consoleOutput.map(cleanConsoleOutput).join(`\n`)).toMatchSnapshot(); + }); + + it(`should not show warnings if given higher log level`, () => { + StyleDictionary.extend({ + logLevel: `error`, + source: [ + // including a specific file twice will throw value collision warnings + `__integration__/tokens/size/padding.json`, + `__integration__/tokens/size/padding.json` + ], + platforms: { + } + }); + expect(consoleOutput.map(cleanConsoleOutput).join(`\n`)).toMatchSnapshot(); + }); + }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/logging/file.test.js b/__integration__/logging/file.test.js new file mode 100644 index 000000000..5663a41b8 --- /dev/null +++ b/__integration__/logging/file.test.js @@ -0,0 +1,167 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../../index'); +const {buildPath, cleanConsoleOutput} = require('../_constants'); + +// Spy on console.log and add all messages to an array +let consoleOutput = []; +const log = jest.spyOn(console, "log") + .mockImplementation(message => consoleOutput.push(message)) + + +/** + * The last and final level of logging: file. + * These logs happen when a file is being built and will notify the user + * if there are issues generating a file. These issues might include + * skipping building an empty file, property name collisions, or filtered + * out references. + */ +describe(`integration`, () => { + // before each test clear the mocked console.log and the output array + beforeEach(() => { + log.mockClear(); + consoleOutput = []; + }); + + describe(`logging`, () => { + describe(`file`, () => { + it(`should warn user empty properties`, () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + css: { + transformGroup: `css`, + files: [{ + destination: `empty.css`, + format: `css/variables`, + filter: (token) => token.attributes.category === `foo` + }] + } + } + }).buildAllPlatforms(); + + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + + it(`should not warn user of empty properties with log level set to error`, () => { + StyleDictionary.extend({ + logLevel: `error`, + source: [`__integration__/tokens/**/*.json`], + platforms: { + css: { + transformGroup: `css`, + files: [{ + destination: `empty.css`, + format: `css/variables`, + filter: (token) => token.attributes.category === `foo` + }] + } + } + }).buildAllPlatforms(); + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + + it(`should warn user of name collisions`, () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + css: { + // no name transform means there will be name collisions + transforms: [`attribute/cti`], + buildPath, + files: [{ + destination: `nameCollisions.css`, + format: `css/variables`, + filter: (token) => token.attributes.category === `color` + }] + } + } + }).buildAllPlatforms(); + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + + it(`should not warn user of name collisions with log level set to error`, () => { + StyleDictionary.extend({ + logLevel: `error`, + source: [`__integration__/tokens/**/*.json`], + platforms: { + css: { + // no name transform means there will be name collisions + transforms: [`attribute/cti`], + buildPath, + files: [{ + destination: `nameCollisions.css`, + format: `css/variables`, + filter: (token) => token.attributes.category === `color` + }] + } + } + }).buildAllPlatforms(); + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + + it(`should warn user of filtered references`, () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + css: { + transformGroup: `css`, + buildPath, + files: [{ + destination: `filteredReferences.css`, + format: `css/variables`, + options: { + outputReferences: true + }, + // background colors have references, only including them + // should warn the user + filter: (token) => token.attributes.type === `background` + }] + } + } + }).buildAllPlatforms(); + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + + it(`should not warn user of filtered references with log level set to error`, () => { + StyleDictionary.extend({ + logLevel: `error`, + source: [`__integration__/tokens/**/*.json`], + platforms: { + css: { + transformGroup: `css`, + buildPath, + files: [{ + destination: `filteredReferences.css`, + format: `css/variables`, + options: { + outputReferences: true + }, + // background colors have references, only including them + // should warn the user + filter: (token) => token.attributes.type === `background` + }] + } + } + }).buildAllPlatforms(); + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/logging/platform.test.js b/__integration__/logging/platform.test.js new file mode 100644 index 000000000..6178b9af8 --- /dev/null +++ b/__integration__/logging/platform.test.js @@ -0,0 +1,125 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../../index'); +const {buildPath, cleanConsoleOutput} = require('../_constants'); + +// Spy on console.log and add all messages to an array +let consoleOutput = []; +const log = jest.spyOn(console, "log") + .mockImplementation(message => consoleOutput.push(message)) + +/** + * This is the 2nd phase of logging: the platform configuration. This happens + * after the Style Dictionary configuration is verified and property files are + * parsed and merged. The platform configuration phase will verify the configuration + * of the platform and turn references to transforms, transformGroups, formats, + * and actions into their actual implementation. This phase may warn or throw + * an error if a user tries to use an unknown transform. + * + */ +describe(`integration`, () => { + // before each test clear the mocked console.log and the output array + beforeEach(() => { + log.mockClear(); + consoleOutput = []; + }); + + describe(`logging`, () => { + describe(`platform`, () => { + it(`should throw and notify users of unknown actions`, () => { + // unknown actions should throw + expect(() => { + StyleDictionary.extend({ + properties: {}, + platforms: { + css: { + actions: [`foo`] + } + } + }).buildAllPlatforms(); + }).toThrow(); + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + + it(`should throw and notify users of unknown transforms`, () => { + expect(() => { + StyleDictionary.extend({ + platforms: { + css: { + transforms: [`foo`,`bar`] + } + } + }).buildAllPlatforms(); + }).toThrow(); + expect(consoleOutput.map(cleanConsoleOutput).join(`\n`)).toMatchSnapshot(); + }); + + it(`should throw and notify users of unknown transformGroups`, () => { + expect(() => { + StyleDictionary.extend({ + platforms: { + css: { + transformGroup: `foo` + } + } + }).buildAllPlatforms(); + }).toThrow(); + expect(consoleOutput.map(cleanConsoleOutput).join(`\n`)).toMatchSnapshot(); + }); + + describe(`property reference errors`, () => { + it(`should throw and notify users of unknown references`, () => { + expect(() => { + StyleDictionary.extend({ + properties: { + color: { + danger: { value: "{color.red.value}" }, + } + }, + platforms: { + css: {} + } + }).buildAllPlatforms(); + }).toThrow(); + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + + it(`circular references should throw notify users`, () => { + expect(() => { + StyleDictionary.extend({ + properties: { + color: { + foo: { value: "{color.foo.value}" }, + teal: { value: "{color.blue.value}" }, + blue: { value: "{color.green.value}" }, + green: { value: "{color.teal.value}" }, + purple: { value: "{color.teal.value}" } + } + }, + platforms: { + css: {} + } + }).buildAllPlatforms(); + }).toThrow(); + expect(consoleOutput.map(cleanConsoleOutput).join('\n')).toMatchSnapshot(); + }); + }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/nameCollisions.test.js b/__integration__/nameCollisions.test.js new file mode 100644 index 000000000..7cdf0fb0e --- /dev/null +++ b/__integration__/nameCollisions.test.js @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const chalk = require('chalk'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +const properties = { + color: { + red: { value: '#f00' }, + background: { + red: { value: '{color.red.value}' } + } + } +} + +describe('integration', () => { + describe('name collisions', () => { + it(`should warn users of name collisions for flat files`, () => { + console.log = jest.fn(); + StyleDictionary.extend({ + // we are only testing name collision warnings options so we don't need + // the full source. + properties, + platforms: { + web: { + buildPath, + files: [{ + destination: 'variables.css', + format: 'css/variables', + }] + }, + } + }).buildAllPlatforms(); + expect(console.log).toHaveBeenCalledWith(`⚠️ ${buildPath}variables.css`); + }); + + it(`should not warn users of name collisions for nested files`, () => { + console.log = jest.fn(); + StyleDictionary.extend({ + // we are only testing name collision warnings options so we don't need + // the full source. + properties, + platforms: { + web: { + buildPath, + files: [{ + destination: 'tokens.json', + format: 'json/nested' + }] + }, + } + }).buildAllPlatforms(); + expect(console.log).toHaveBeenCalledWith(chalk.bold.green(`✔︎ ${buildPath}tokens.json`)); + }); + + + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/objectValues.test.js b/__integration__/objectValues.test.js new file mode 100644 index 000000000..addad4e3d --- /dev/null +++ b/__integration__/objectValues.test.js @@ -0,0 +1,211 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const Color = require('tinycolor2'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +const options = { + outputReferences: true +} + +describe('integration', () => { + describe('object values', () => { + StyleDictionary.extend({ + properties: { + hue: `120`, + saturation: `50%`, + lightness: `50%`, + color: { + red: { value: "#f00" }, + green: { + value: { + h: "{hue}", + s: "{saturation}", + l: "{lightness}" + } + } + }, + size: { + border: { value: 0.125 } + }, + border: { + primary: { + // getReferences should work on objects like this: + value: { + color: "{color.red.value}", + width: "{size.border.value}", + style: "solid" + } + }, + } + }, + transform: { + hsl: { + type: 'value', + transitive: true, + matcher: (token) => token.original.value.h, + transformer: (token) => { + return `hsl(${token.value.h}, ${token.value.s}, ${token.value.l})` + } + }, + hslToHex: { + type: 'value', + transitive: true, + matcher: (token) => token.original.value.h, + transformer: (token) => { + return Color(`hsl(${token.value.h}, ${token.value.s}, ${token.value.l})`).toHexString(); + } + }, + cssBorder: { + type: 'value', + transitive: true, + matcher: (token) => token.path[0] === `border`, + transformer: (token) => { + return `${token.value.width} ${token.value.style} ${token.value.color}` + } + } + }, + platforms: { + // This will test to see if a value object for an hsl color works + // with and without `outputReferences` + cssHsl: { + buildPath, + transforms: StyleDictionary.transformGroup.css.concat([`hsl`]), + files: [{ + destination: `hsl.css`, + format: `css/variables`, + filter: (token) => token.attributes.category === `color` + },{ + destination: `hslWithReferences.css`, + format: `css/variables`, + filter: (token) => token.attributes.category === `color`, + options + }] + }, + + // This will test to see if a value object for an hsl that has been + // transformed to a hex color works with and without `outputReferences` + cssHex: { + buildPath, + transforms: StyleDictionary.transformGroup.css.concat([`cssBorder`,`hslToHex`]), + files: [{ + destination: 'hex.css', + format: 'css/variables', + filter: (token) => token.attributes.category === `color`, + },{ + destination: 'hexWithReferences.css', + format: 'css/variables', + filter: (token) => token.attributes.category === `color`, + options + }] + }, + + // This will test to see if a value object for a border + // works with and without `outputReferences` + cssBorder: { + buildPath, + transforms: StyleDictionary.transformGroup.css.concat([`cssBorder`]), + files: [{ + destination: 'border.css', + format: 'css/variables', + filter: (token) => token.attributes.category === `border`, + },{ + destination: 'borderWithReferences.css', + format: 'css/variables', + filter: (token) => token.attributes.category === `border`, + options + }] + }, + + scss: { + buildPath, + transforms: StyleDictionary.transformGroup.css.concat([`cssBorder`,`hslToHex`]), + files: [{ + destination: 'border.scss', + format: 'scss/variables', + filter: (token) => token.attributes.category === `border`, + },{ + destination: 'borderWithReferences.scss', + format: 'scss/variables', + filter: (token) => token.attributes.category === `border`, + options + }] + }, + } + }).buildAllPlatforms(); + + describe('css/variables', () => { + describe(`hsl syntax`, () => { + const output = fs.readFileSync(`${buildPath}hsl.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}hslWithReferences.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); + + describe(`hex syntax`, () => { + const output = fs.readFileSync(`${buildPath}hex.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}hexWithReferences.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); + + describe(`border`, () => { + const output = fs.readFileSync(`${buildPath}border.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}borderWithReferences.css`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); + }); + + describe('scss/variables', () => { + const output = fs.readFileSync(`${buildPath}border.scss`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}borderWithReferences.scss`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/outputReferences.test.js b/__integration__/outputReferences.test.js new file mode 100644 index 000000000..afa172b64 --- /dev/null +++ b/__integration__/outputReferences.test.js @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('output references', () => { + it('should warn the user if filters out references', () => { + console.log = jest.fn(); + StyleDictionary.extend({ + // we are only testing showFileHeader options so we don't need + // the full source. + source: [`__integration__/tokens/**/*.json`], + platforms: { + css: { + transformGroup: 'css', + buildPath, + files: [{ + destination: 'filteredVariables.css', + format: 'css/variables', + // filter tokens and use outputReferences + // Style Dictionary should build this file ok + // but warn the user + filter: (token) => token.attributes.type === 'background', + options: { + outputReferences: true + } + }] + } + } + }).buildAllPlatforms(); + + expect(console.log).toHaveBeenCalledWith(`⚠️ ${buildPath}filteredVariables.css`); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/scss.test.js b/__integration__/scss.test.js new file mode 100644 index 000000000..f6e442ae9 --- /dev/null +++ b/__integration__/scss.test.js @@ -0,0 +1,126 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const scss = require('node-sass'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe(`integration`, () => { + describe(`scss`, () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + css: { + transformGroup: `scss`, + buildPath, + files: [{ + destination: `variables.scss`, + format: `scss/variables` + },{ + destination: `variablesWithReferences.scss`, + format: `scss/variables`, + options: { + outputReferences: true + } + },{ + destination: `filteredVariablesWithReferences.scss`, + format: `scss/variables`, + filter: (token) => token.path[1] === 'background', + options: { + outputReferences: true + } + },{ + destination: `map-flat.scss`, + format: `scss/map-flat`, + mapName: 'design-system-tokens' + },{ + destination: `map-deep.scss`, + format: `scss/map-deep`, + mapName: 'design-system-tokens' + }] + } + } + }).buildAllPlatforms(); + + describe(`scss/variables`, () => { + const output = fs.readFileSync(`${buildPath}variables.scss`, {encoding:'UTF-8'}); + + it(`should have a valid scss syntax`, () => { + const result = scss.renderSync({ + data: output, + }); + expect(result.css).toBeDefined(); + }); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with outputReferences`, () => { + const output = fs.readFileSync(`${buildPath}variablesWithReferences.scss`, {encoding:'UTF-8'}); + it(`should have a valid scss syntax`, () => { + const result = scss.renderSync({ + data: output, + }); + expect(result.css).toBeDefined(); + }); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + + describe(`with filter and output references`, () => { + const output = fs.readFileSync(`${buildPath}filteredVariablesWithReferences.scss`, {encoding:'UTF-8'}); + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); + + describe(`scss/map-flat`, () => { + const output = fs.readFileSync(`${buildPath}map-flat.scss`, {encoding:'UTF-8'}); + + it(`should have a valid scss syntax`, () => { + const result = scss.renderSync({ + data: output, + }); + expect(result.css).toBeDefined(); + }); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + + describe(`scss/map-deep`, () => { + const output = fs.readFileSync(`${buildPath}map-deep.scss`, {encoding:'UTF-8'}); + + it(`should have a valid scss syntax`, () => { + const result = scss.renderSync({ + data: output, + }); + expect(result.css).toBeDefined(); + }); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/showFileHeader.test.js b/__integration__/showFileHeader.test.js new file mode 100644 index 000000000..8459bef30 --- /dev/null +++ b/__integration__/showFileHeader.test.js @@ -0,0 +1,87 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('showFileHeader', () => { + StyleDictionary.extend({ + // we are only testing showFileHeader options so we don't need + // the full source. + source: [`__integration__/tokens/size/padding.json`], + platforms: { + css: { + transformGroup: 'css', + buildPath, + files: [{ + destination: 'platform-none-file-none.css', + format: 'css/variables' + },{ + destination: 'platform-none-file-false.css', + format: 'css/variables', + options: { + showFileHeader: false + } + }] + }, + fileHeader: { + transformGroup: 'css', + buildPath, + options: { + showFileHeader: false + }, + files: [{ + destination: 'platform-false-file-none.css', + format: 'css/variables' + },{ + destination: 'platform-false-file-true.css', + format: 'css/variables', + options: { + showFileHeader: true + } + }] + } + } + }).buildAllPlatforms(); + + describe(`without platform options`, () => { + it(`should show file header if no file options set`, () => { + const output = fs.readFileSync(`${buildPath}platform-none-file-none.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + + it(`should not show file header if file options set to false`, () => { + const output = fs.readFileSync(`${buildPath}platform-none-file-false.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + }); + + describe(`with platform options set to false`, () => { + it(`should not show file header if no file options set`, () => { + const output = fs.readFileSync(`${buildPath}platform-false-file-none.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + + it(`should show file header if file options set to true`, () => { + const output = fs.readFileSync(`${buildPath}platform-false-file-true.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/swift.test.js b/__integration__/swift.test.js new file mode 100644 index 000000000..44bd170fd --- /dev/null +++ b/__integration__/swift.test.js @@ -0,0 +1,70 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const StyleDictionary = require('../index'); +const {buildPath} = require('./_constants'); + +describe('integration', () => { + describe('swift', () => { + StyleDictionary.extend({ + source: [`__integration__/tokens/**/*.json`], + platforms: { + flutter: { + transformGroup: `ios-swift`, + buildPath, + files: [{ + destination: "style_dictionary.swift", + format: "ios-swift/class.swift", + className: "StyleDictionary" + },{ + destination: "style_dictionary_with_references.swift", + format: "ios-swift/class.swift", + className: "StyleDictionary", + options: { + outputReferences: true + } + }] + }, + } + }).buildAllPlatforms(); + + describe(`ios-swift/class.swift`, () => { + const output = fs.readFileSync(`${buildPath}style_dictionary.swift`, {encoding:`UTF-8`}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + describe(`with references`, () => { + const output = fs.readFileSync(`${buildPath}style_dictionary_with_references.swift`, {encoding:`UTF-8`}); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + + }); + + // describe(`separate`, () => { + // const output = fs.readFileSync(`${buildPath}style_dictionary_color.dart`); + // it(`should match snapshot`, () => { + // expect(output).toMatchSnapshot(); + // }); + // }); + }); + }); +}); + +afterAll(() => { + fs.emptyDirSync(buildPath); +}); \ No newline at end of file diff --git a/__integration__/tokens/color/background.json b/__integration__/tokens/color/background.json new file mode 100644 index 000000000..066b22fbb --- /dev/null +++ b/__integration__/tokens/color/background.json @@ -0,0 +1,14 @@ +{ + "color": { + "background": { + "primary": { "value": "{color.core.neutral.0.value}", "themeable": true }, + "secondary": { "value": "{color.core.neutral.100.value}" }, + "tertiary": { "value": "{color.core.neutral.200.value}" }, + "danger": { "value": "{color.core.red.0.value}" }, + "warning": { "value": "{color.core.orange.0.value}" }, + "success": { "value": "{color.core.green.0.value}" }, + "info": { "value": "{color.core.blue.0.value}" }, + "disabled": { "value": "{color.background.tertiary.value}" } + } + } +} \ No newline at end of file diff --git a/__integration__/tokens/color/border.json b/__integration__/tokens/color/border.json new file mode 100644 index 000000000..c344aae51 --- /dev/null +++ b/__integration__/tokens/color/border.json @@ -0,0 +1,9 @@ +{ + "color": { + "border": { + "primary": { "value": "{color.core.neutral.300.value}" }, + "secondary": {}, + "tertiary": {} + } + } +} \ No newline at end of file diff --git a/__integration__/tokens/color/brand.json b/__integration__/tokens/color/brand.json new file mode 100644 index 000000000..66cde45ce --- /dev/null +++ b/__integration__/tokens/color/brand.json @@ -0,0 +1,13 @@ +{ + "color": { + "brand": { + "primary": { + "value": "{color.core.aqua.700.value}" + }, + + "secondary": { + "value": "{color.core.purple.700.value}" + } + } + } +} \ No newline at end of file diff --git a/__integration__/tokens/color/core.json b/__integration__/tokens/color/core.json new file mode 100644 index 000000000..e3294792a --- /dev/null +++ b/__integration__/tokens/color/core.json @@ -0,0 +1,170 @@ +{ + "color": { + "core": { + "green": { + "0": { "value": "#ebf9eb" }, + "100" : { "value": "#d7f4d7" }, + "200" : { "value": "#c2f2bd" }, + "300" : { "value": "#98e58e" }, + "400" : { "value": "#75dd66" }, + "500" : { "value": "#59cb59" }, + "600" : { "value": "#2bb656" }, + "700" : { "value": "#0ca750" }, + "800" : { "value": "#008b46" }, + "900" : { "value": "#006b40" }, + "1000" : { "value": "#08422f" }, + "1100" : { "value": "#002b20" } + }, + + "teal": { + "0": { "value": "#e5f9f5" }, + "100" : { "value": "#cdf7ef" }, + "200" : { "value": "#b3f2e6" }, + "300" : { "value": "#7dead5" }, + "400" : { "value": "#24e0c5" }, + "500" : { "value": "#08c4b2" }, + "600" : { "value": "#00a99c" }, + "700" : { "value": "#0b968f" }, + "800" : { "value": "#067c7c" }, + "900" : { "value": "#026661" }, + "1000" : { "value": "#083f3f" }, + "1100" : { "value": "#002528" } + }, + + "aqua": { + "0": { "value": "#d9fcfb" }, + "100" : { "value": "#c5f9f9" }, + "200" : { "value": "#a5f2f2" }, + "300" : { "value": "#76e5e2" }, + "400" : { "value": "#33d6e2" }, + "500" : { "value": "#17b8ce" }, + "600" : { "value": "#0797ae" }, + "700" : { "value": "#0b8599" }, + "800" : { "value": "#0f6e84" }, + "900" : { "value": "#035e73" }, + "1000" : { "value": "#083d4f" }, + "1100" : { "value": "#002838" } + }, + + "blue": { + "0": { "value": "#e9f8ff" }, + "100" : { "value": "#dcf2ff" }, + "200" : { "value": "#c7e4f9" }, + "300" : { "value": "#a1d2f8" }, + "400" : { "value": "#56adf5" }, + "500" : { "value": "#3896e3" }, + "600" : { "value": "#2b87d3" }, + "700" : { "value": "#2079c3" }, + "800" : { "value": "#116daa" }, + "900" : { "value": "#0c5689" }, + "1000" : { "value": "#0a3960" }, + "1100" : { "value": "#002138" } + }, + + "purple": { + "0": { "value": "#f2f2f9" }, + "100" : { "value": "#eaeaf9" }, + "200" : { "value": "#d8d7f9" }, + "300" : { "value": "#c1c1f7" }, + "400" : { "value": "#a193f2" }, + "500" : { "value": "#9180f4" }, + "600" : { "value": "#816fea" }, + "700" : { "value": "#6f5ed3" }, + "800" : { "value": "#5e4eba" }, + "900" : { "value": "#483a9c" }, + "1000" : { "value": "#2d246b" }, + "1100" : { "value": "#1d1d38" } + }, + + "magenta": { + "0": { "value": "#fef0ff" }, + "100" : { "value": "#f9e3fc" }, + "200" : { "value": "#f4c4f7" }, + "300" : { "value": "#edadf2" }, + "400" : { "value": "#f282f5" }, + "500" : { "value": "#db61db" }, + "600" : { "value": "#c44eb9" }, + "700" : { "value": "#ac44a8" }, + "800" : { "value": "#8f3896" }, + "900" : { "value": "#6c2277" }, + "1000" : { "value": "#451551" }, + "1100" : { "value": "#29192d" } + }, + + "pink": { + "0": { "value": "#ffe9f3" }, + "100" : { "value": "#fcdbeb" }, + "200" : { "value": "#ffb5d5" }, + "300" : { "value": "#ff95c1" }, + "400" : { "value": "#ff76ae" }, + "500" : { "value": "#ef588b" }, + "600" : { "value": "#e0447c" }, + "700" : { "value": "#ce3665" }, + "800" : { "value": "#b22f5b" }, + "900" : { "value": "#931847" }, + "1000" : { "value": "#561231" }, + "1100" : { "value": "#2b1721" } + }, + + "red": { + "0": { "value": "#ffeae9" }, + "100" : { "value": "#ffd5d2" }, + "200" : { "value": "#ffb8b1" }, + "300" : { "value": "#ff9c8f" }, + "400" : { "value": "#ff7f6e" }, + "500" : { "value": "#f76054" }, + "600" : { "value": "#ed4c42" }, + "700" : { "value": "#db3e3e" }, + "800" : { "value": "#c63434" }, + "900" : { "value": "#992222" }, + "1000" : { "value": "#6d1313" }, + "1100" : { "value": "#2b1111" } + }, + + "orange": { + "0": { "value": "#ffede3" }, + "100" : { "value": "#fcdccc" }, + "200" : { "value": "#ffc6a4" }, + "300" : { "value": "#ffb180" }, + "400" : { "value": "#ff9c5d" }, + "500" : { "value": "#fc8943" }, + "600" : { "value": "#f57d33" }, + "700" : { "value": "#ed7024" }, + "800" : { "value": "#ce5511" }, + "900" : { "value": "#962c0b" }, + "1000" : { "value": "#601700" }, + "1100" : { "value": "#2d130e" } + }, + + "neutral": { + "0" : { "value": "#FFFFFF" }, + "100" : { "value": "#f3f4f4" }, + "200" : { "value": "#dee1e1" }, + "300" : { "value": "#c8cccc" }, + "400" : { "value": "#b0b6b7" }, + "500" : { "value": "#929a9b" }, + "600" : { "value": "#6e797a" }, + "700" : { "value": "#515e5f" }, + "800" : { "value": "#364141" }, + "900" : { "value": "#273333" }, + "1000" : { "value": "#162020" }, + "1100" : { "value": "#040404" } + }, + + "yellow": { + "0": { "value": "#fff8e2" }, + "100" : { "value": "#fdefcd" }, + "200" : { "value": "#ffe99a" }, + "300" : { "value": "#ffe16e" }, + "400" : { "value": "#ffd943" }, + "500" : { "value": "#ffcd1c" }, + "600" : { "value": "#ffbc00" }, + "700" : { "value": "#dd9903" }, + "800" : { "value": "#ba7506" }, + "900" : { "value": "#944c0c" }, + "1000" : { "value": "#542a00" }, + "1100" : { "value": "#2d1a05" } + } + } + } +} \ No newline at end of file diff --git a/__integration__/tokens/color/font.json b/__integration__/tokens/color/font.json new file mode 100644 index 000000000..d15b7cc29 --- /dev/null +++ b/__integration__/tokens/color/font.json @@ -0,0 +1,20 @@ +{ + "color": { + "font": { + "primary": { "value": "{color.core.neutral.1100.value}" }, + "secondary": { "value": "{color.core.neutral.900.value}" }, + "tertiary": { "value": "{color.core.neutral.800.value}" }, + + "interactive": { + "_": { "value": "{color.brand.primary.value}" }, + "hover": { "value": "{color.brand.primary.value}" }, + "active": { "value": "{color.brand.secondary.value}" }, + "disabled": { "value": "{color.font.tertiary.value}" } + }, + + "danger": { "value": "{color.core.red.1000.value}" }, + "warning": { "value": "{color.core.orange.1000.value}" }, + "success": { "value": "{color.core.green.1000.value}" } + } + } +} \ No newline at end of file diff --git a/__integration__/tokens/size/border.json b/__integration__/tokens/size/border.json new file mode 100644 index 000000000..d70a7cd0c --- /dev/null +++ b/__integration__/tokens/size/border.json @@ -0,0 +1,9 @@ +{ + "size": { + "border": { + "radius": { + "large": { "value": 30 } + } + } + } +} \ No newline at end of file diff --git a/__integration__/tokens/size/font.json b/__integration__/tokens/size/font.json new file mode 100644 index 000000000..3056392aa --- /dev/null +++ b/__integration__/tokens/size/font.json @@ -0,0 +1,10 @@ +{ + "size": { + "font": { + "small": { "value": 0.75 }, + "medium": { "value": 1 }, + "large": { "value": 1.5 }, + "xl": { "value": 2.25 } + } + } +} \ No newline at end of file diff --git a/__integration__/tokens/size/padding.json b/__integration__/tokens/size/padding.json new file mode 100644 index 000000000..6d2358d71 --- /dev/null +++ b/__integration__/tokens/size/padding.json @@ -0,0 +1,10 @@ +{ + "size": { + "padding": { + "small": { "value": 0.5 }, + "medium": { "value": 1 }, + "large": { "value": 1 }, + "xl": { "value": 1 } + } + } +} \ No newline at end of file diff --git a/__tests__/__configs/test.json b/__tests__/__configs/test.json index feab04c97..b5240d53c 100644 --- a/__tests__/__configs/test.json +++ b/__tests__/__configs/test.json @@ -77,6 +77,16 @@ "format": "ios/macros" } ] + }, + "react-native": { + "transformGroup": "react-native", + "buildPath": "__tests__/__output/react-native/", + "files": [ + { + "destination": "style_dictionary.js", + "format": "javascript/es6" + } + ] } } } diff --git a/__tests__/__configs/test.json5 b/__tests__/__configs/test.json5 index 9c3a206d2..062efc323 100644 --- a/__tests__/__configs/test.json5 +++ b/__tests__/__configs/test.json5 @@ -84,5 +84,15 @@ }, ], }, + 'react-native': { + transformGroup: 'react-native', + buildPath: '__tests__/__output/react-native/', + files: [ + { + destination: 'style_dictionary.js', + format: 'javascript/es6' + } + ] + } }, } diff --git a/__tests__/__json_files/yaml.yaml b/__tests__/__json_files/yaml.yaml new file mode 100644 index 000000000..71a193daa --- /dev/null +++ b/__tests__/__json_files/yaml.yaml @@ -0,0 +1,2 @@ +foo: "bar" +bar: "{foo}" diff --git a/__tests__/__properties/colors.json b/__tests__/__properties/colors.json index 3be148829..733922b05 100644 --- a/__tests__/__properties/colors.json +++ b/__tests__/__properties/colors.json @@ -85,6 +85,16 @@ "font": { "link": { "value": "{color.base.blue.100.value}" } + }, + + "button": { + "base": { "value": "{color.base.blue.100.value}" }, + "active": { "value": "{color.button.base.value}", "transformColor": { + "darken": 0.5 + } }, + "hover": { "value": "{color.button.active.value}", "transformColor": { + "darken": 0.2 + } } } } } diff --git a/__tests__/__properties/paddings.1.json b/__tests__/__properties/paddings.1.json new file mode 100644 index 000000000..4ca03cfcc --- /dev/null +++ b/__tests__/__properties/paddings.1.json @@ -0,0 +1,24 @@ +{ + "size": { + "padding": { + "tiny": { + "value": "3" + }, + "small": { + "value": "5" + }, + "base": { + "value": "10" + }, + "large": { + "value": "15" + }, + "xl": { + "value": "20" + }, + "xxl": { + "value": "30" + } + } + } +} \ No newline at end of file diff --git a/__tests__/__properties/paddings.json b/__tests__/__properties/paddings.json index 4ca03cfcc..0ba5cc545 100644 --- a/__tests__/__properties/paddings.json +++ b/__tests__/__properties/paddings.json @@ -1,6 +1,9 @@ { "size": { "padding": { + "zero": { + "value": 0 + }, "tiny": { "value": "3" }, diff --git a/__tests__/__setup.js b/__tests__/__setup.js new file mode 100644 index 000000000..0d5db7dc2 --- /dev/null +++ b/__tests__/__setup.js @@ -0,0 +1,3 @@ +const constantDate = new Date('2000-01-01'); +global.Date = function() { return constantDate }; +global.Date.now = function() { return constantDate }; \ No newline at end of file diff --git a/__tests__/buildFile.test.js b/__tests__/buildFile.test.js index 225aa9774..fb770ac31 100644 --- a/__tests__/buildFile.test.js +++ b/__tests__/buildFile.test.js @@ -20,6 +20,12 @@ function format() { return "hi"; } +function nestedFormat() { + return "hi"; +} + +nestedFormat.nested = true; + describe('buildFile', () => { beforeEach(() => { @@ -32,31 +38,31 @@ describe('buildFile', () => { it('should error if format doesnt exist or isnt a function', () => { expect( - buildFile.bind(null, '__tests__/__output/test.txt', {}, {}, {}) + buildFile.bind(null, {destination: '__tests__/__output/test.txt'}, {}, {}) ).toThrow('Please enter a valid file format'); expect( - buildFile.bind(null, '__tests__/__output/test.txt', [], {}, {}) + buildFile.bind(null, {destination: '__tests__/__output/test.txt', format: {}}, {}, {}) ).toThrow('Please enter a valid file format'); expect( - buildFile.bind(null, '__tests__/__output/test.txt', null, {}, {}) + buildFile.bind(null, {destination: '__tests__/__output/test.txt', format: []}, {}, {}) ).toThrow('Please enter a valid file format'); }); it('should error if destination doesnt exist or isnt a string', () => { expect( - buildFile.bind(null, {}, format, {}, {}) + buildFile.bind(null, {format}, {}, {}) ).toThrow('Please enter a valid destination'); expect( - buildFile.bind(null, [], format, {}, {}) + buildFile.bind(null, {format, destination: []}, {}, {}) ).toThrow('Please enter a valid destination'); expect( - buildFile.bind(null, null, format, {}, {}) + buildFile.bind(null, {format, destination: {}}, {}, {}) ).toThrow('Please enter a valid destination'); }); - let dest = './__tests__/__output/test.collisions'; - var PROPERTY_NAME_COLLISION_WARNINGS = GroupMessages.GROUP.PropertyNameCollisionWarnings + ":" + dest; - it('should generate warning messages for output name collisions', () => { + describe('name collisions', () => { + let destination = './__tests__/__output/test.collisions'; + let PROPERTY_NAME_COLLISION_WARNINGS = GroupMessages.GROUP.PropertyNameCollisionWarnings + ":" + destination; let name = 'someName'; let properties = { allProperties: [{ @@ -69,24 +75,61 @@ describe('buildFile', () => { value: 'value2' }] }; + it('should generate warning messages for output name collisions', () => { + GroupMessages.clear(PROPERTY_NAME_COLLISION_WARNINGS); + buildFile({destination, format}, {}, properties); + + let collisions = properties.allProperties.map((properties) => { + let propertyPathText = chalk.keyword('orangered')(properties.path.join('.')); + let valueText = chalk.keyword('darkorange')(properties.value); + return propertyPathText + ' ' + valueText; + }).join('\n '); + let output = `Output name ${chalk.keyword('orangered').bold(name)} was generated by:\n ${collisions}`; + let expectJSON = JSON.stringify([output]); + + expect(GroupMessages.count(PROPERTY_NAME_COLLISION_WARNINGS)).toBe(1); + expect(JSON.stringify(GroupMessages.fetchMessages(PROPERTY_NAME_COLLISION_WARNINGS))).toBe(expectJSON); + }); + + it('should not warn users if the format is a nested format', () => { + console.log = jest.fn(); + buildFile({destination, format: nestedFormat}, {}, properties); + expect(console.log).toHaveBeenCalledWith(chalk.bold.green(`✔︎ ${destination}`)); + }); + }); + - GroupMessages.clear(PROPERTY_NAME_COLLISION_WARNINGS); - buildFile(dest, format, {}, properties); + let destEmptyProperties = './__tests__/__output/test.emptyProperties'; + it('should warn when a file is not created because of empty properties', () => { + let dictionary = { + allProperties: [{ + name: 'someName', + attributes: { category: 'category1' }, + path: ['some', 'name', 'path1'], + value: 'value1' + }] + }; - let collisions = properties.allProperties.map((properties) => { - let propertyPathText = chalk.keyword('orangered')(properties.path.join('.')); - let valueText = chalk.keyword('darkorange')(properties.value); - return propertyPathText + ' ' + valueText; - }).join('\n '); - let output = `Output name ${chalk.keyword('orangered').bold(name)} was generated by:\n ${collisions}`; - let expectJSON = JSON.stringify([output]); + let filter = function(prop) { + return prop.attributes.category === 'category2'; + } - expect(GroupMessages.count(PROPERTY_NAME_COLLISION_WARNINGS)).toBe(1); - expect(JSON.stringify(GroupMessages.fetchMessages(PROPERTY_NAME_COLLISION_WARNINGS))).toBe(expectJSON); + buildFile({ + destination: destEmptyProperties, + format, + filter + }, {}, dictionary); + expect(helpers.fileExists('./__tests__/__output/test.emptyProperties')).toBeFalsy(); }); it('should write to a file properly', () => { - buildFile('test.txt', format, {buildPath: '__tests__/__output/'}, {}); + buildFile({ + destination: 'test.txt', + format + },{ + buildPath: '__tests__/__output/' + },{} + ); expect(helpers.fileExists('./__tests__/__output/test.txt')).toBeTruthy(); }); }); diff --git a/__tests__/buildFiles.test.js b/__tests__/buildFiles.test.js index 7897a9f2c..fdd7b4e9e 100644 --- a/__tests__/buildFiles.test.js +++ b/__tests__/buildFiles.test.js @@ -13,7 +13,7 @@ var buildFiles = require('../lib/buildFiles'); var helpers = require('./__helpers'); -var _ = require('lodash'); +var _ = require('../lib/utils/es6_'); var dictionary = { properties: { @@ -93,13 +93,13 @@ describe('buildFiles', () => { it('should throw if build path doesn\'t have a trailing slash', () => { expect( - buildFiles.bind(null, dictionary, platformWithBadBuildPath), + buildFiles.bind(null, dictionary, platformWithBadBuildPath) ).toThrow('Build path must end in a trailing slash or you will get weird file names.'); }); it('should throw if missing a format', () => { expect( - buildFiles.bind(null, dictionary, platformWithoutFormatter), + buildFiles.bind(null, dictionary, platformWithoutFormatter) ).toThrow('Please supply a format'); }); diff --git a/__tests__/buildPlatform.test.js b/__tests__/buildPlatform.test.js index fc90b70c0..065665df4 100644 --- a/__tests__/buildPlatform.test.js +++ b/__tests__/buildPlatform.test.js @@ -24,7 +24,7 @@ describe('buildPlatform', () => { it('should throw if passed a platform that doesn\'t exist', () => { expect( - StyleDictionaryExtended.buildPlatform.bind(test, 'foobar'), + StyleDictionaryExtended.buildPlatform.bind(test, 'foobar') ).toThrow('Platform "foobar" does not exist'); expect( @@ -171,7 +171,7 @@ Unknown transformGroup "bar" found in platform "foo": `; expect( - StyleDictionaryExtended.buildPlatform.bind(StyleDictionaryExtended, 'foo'), + StyleDictionaryExtended.buildPlatform.bind(StyleDictionaryExtended, 'foo') ).toThrow(err); }); diff --git a/__tests__/cleanDir.test.js b/__tests__/cleanDir.test.js index 57508e165..180c6a95a 100644 --- a/__tests__/cleanDir.test.js +++ b/__tests__/cleanDir.test.js @@ -31,9 +31,9 @@ describe('cleanDir', () => { }); it('should delete a dir properly', () => { - buildFile('test.txt', format, {buildPath: '__tests__/__output/extradir1/extradir2/'}, {}); - cleanFile('test.txt', format, {buildPath: '__tests__/__output/extradir1/extradir2/'}, {}); - cleanDir('test.txt', format, {buildPath: '__tests__/__output/extradir1/extradir2/'}, {}); + buildFile({destination:'test.txt', format}, {buildPath: '__tests__/__output/extradir1/extradir2/'}, {}); + cleanFile({destination:'test.txt', format}, {buildPath: '__tests__/__output/extradir1/extradir2/'}, {}); + cleanDir({destination:'test.txt', format}, {buildPath: '__tests__/__output/extradir1/extradir2/'}, {}); expect(helpers.dirDoesNotExist('./__tests__/__output/extradir1/extradir2')).toBeTruthy(); expect(helpers.dirDoesNotExist('./__tests__/__output/extradir1')).toBeTruthy(); }); diff --git a/__tests__/cleanDirs.test.js b/__tests__/cleanDirs.test.js index eb547fd0b..3726410f9 100644 --- a/__tests__/cleanDirs.test.js +++ b/__tests__/cleanDirs.test.js @@ -70,4 +70,14 @@ describe('cleanDirs', () => { expect(helpers.dirDoesNotExist('./__tests__/__output/extradir1/extradir2')).toBeTruthy(); expect(helpers.dirDoesNotExist('./__tests__/__output/extradir1')).toBeTruthy(); }); + + it('should throw if buildPath does not end in a trailing slash', () => { + expect( + function() { + cleanDirs( {}, { + buildPath: "foo" + }) + } + ).toThrow('Build path must end in a trailing slash or you will get weird file names.') + }) }); diff --git a/__tests__/cleanFile.test.js b/__tests__/cleanFile.test.js index 87052d2c9..8f806c79a 100644 --- a/__tests__/cleanFile.test.js +++ b/__tests__/cleanFile.test.js @@ -30,14 +30,14 @@ describe('cleanFile', () => { }); it('should delete a file properly', () => { - buildFile('test.txt', format, {buildPath: '__tests__/__output/'}, {}); - cleanFile('test.txt', format, {buildPath: '__tests__/__output/'}, {}); + buildFile({destination:'test.txt', format}, {buildPath: '__tests__/__output/'}, {}); + cleanFile({destination:'test.txt', format}, {buildPath: '__tests__/__output/'}, {}); expect(helpers.fileDoesNotExist('./__tests__/__output/test.txt')).toBeTruthy(); }); describe('if a file does not exist', () => { it('should not throw', () => { - expect(() => cleanFile('non-existent.txt', format, { buildPath: '__tests__/__output/' }, {})).not.toThrow(); + expect(() => cleanFile({destination: 'non-existent.txt', format}, { buildPath: '__tests__/__output/' }, {})).not.toThrow(); }) }) diff --git a/__tests__/common/formatHelpers/fileHeader.test.js b/__tests__/common/formatHelpers/fileHeader.test.js new file mode 100644 index 000000000..6474241b8 --- /dev/null +++ b/__tests__/common/formatHelpers/fileHeader.test.js @@ -0,0 +1,125 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fileHeader = require('../../../lib/common/formatHelpers/fileHeader'); + +const defaultLine1 = `Do not edit directly`; +const defaultLine2 = `Generated on Sat, 01 Jan 2000 00:00:00 GMT`; + +describe('common', () => { + describe('formatHelpers', () => { + + describe('fileHeader', () => { + it(`should default to /**/ comment style`, () => { + const comment = fileHeader({}); + expect(comment).toEqual( +`/** + * ${defaultLine1} + * ${defaultLine2} + */ + +`); + }); + + it(`should handle commentStyle short`, () => { + const comment = fileHeader({commentStyle: 'short'}); + expect(comment).toEqual( +` +// ${defaultLine1} +// ${defaultLine2} + +`); + }); + + it(`should handle commentStyle xml`, () => { + const comment = fileHeader({commentStyle: 'xml'}); + expect(comment).toEqual( +``); + }); + + it(`should handle showFileHeader option`, () => { + const comment = fileHeader({ + file: { + options: { + showFileHeader: false + } + } + }); + expect(comment).toEqual(''); + }); + + it(`should handle custom fileHeader function`, () => { + const comment = fileHeader({ + file: { + options: { + fileHeader: () => { + return [ + `Never gonna give you up`, + `Never gonna let you down` + ] + } + } + } + }); + expect(comment).toEqual( +`/** + * Never gonna give you up + * Never gonna let you down + */ + +`); + }); + + it(`should handle custom fileHeader function with default`, () => { + const comment = fileHeader({ + file: { + options: { + fileHeader: (defaultMessage) => { + return [ + ...defaultMessage, + `Never gonna give you up`, + `Never gonna let you down` + ] + } + } + } + }); + expect(comment).toEqual( +`/** + * ${defaultLine1} + * ${defaultLine2} + * Never gonna give you up + * Never gonna let you down + */ + +`); + }); + + it('should handle custom formatting', () => { + const comment = fileHeader({formatting: { + prefix: ` `, + header: `{#\n`, + footer: `\n#}` + }}); + expect(comment).toEqual( +`{# + ${defaultLine1} + ${defaultLine2} +#}`); + }); + }); + }); +}); \ No newline at end of file diff --git a/__tests__/common/transforms.test.js b/__tests__/common/transforms.test.js index 691e2ef2f..3aa097ebe 100644 --- a/__tests__/common/transforms.test.js +++ b/__tests__/common/transforms.test.js @@ -281,15 +281,11 @@ describe('common', () => { expect(value).toBe("#aaaaaaff"); }); - it('should handle rgb colors', () => { + it('should handle rgba colors', () => { var value = transforms["color/hex8"].transformer({ - value: "rgb(170,170,170)" - }); - var value2 = transforms["color/hex8"].transformer({ value: "rgba(170,170,170,0.6)" }); - expect(value).toBe("#aaaaaaff"); - expect(value2).toBe("#aaaaaa99"); + expect(value).toBe("#aaaaaa99"); }); }); @@ -357,6 +353,23 @@ describe('common', () => { }); }); + describe('color/composeColor', () => { + it('should handle color without alpha', () => { + var value = transforms["color/composeColor"].transformer({ + value: "#aaaaaa" + }); + expect(value).toBe("Color(0xffaaaaaa)"); + }); + + it('should handle color with alpha', () => { + var value = transforms["color/composeColor"].transformer({ + value: "#aaaaaaff" + }); + expect(value).toBe("Color(0xffaaaaaa)"); + }); + + }); + describe('color/UIColor', () => { it('should handle normal colors', () => { var value = transforms["color/UIColor"].transformer({ @@ -484,6 +497,28 @@ describe('common', () => { }); }); + describe("size/object", () => { + it("should work", () => { + var value = transforms["size/object"].transformer({ + value: "1px" + }); + expect(value.original).toBe("1px"); + expect(value.number).toBe(1); + expect(value.decimal).toEqual(0.01); + expect(value.scale).toBe(16); + }); + it('should work with custom base font', () => { + var value = transforms["size/object"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value.original).toBe("1"); + expect(value.number).toBe(1); + expect(value.decimal).toEqual(0.01); + expect(value.scale).toBe(14); + }) + it('should throw an error if prop value is NaN', () => { + expect( () => transforms["size/object"].transformer({value: "a"})).toThrow(); + }) + }); + describe('size/remToSp', () => { it('should work', () => { var value = transforms["size/remToSp"].transformer({ @@ -491,6 +526,10 @@ describe('common', () => { }); expect(value).toBe("16.00sp"); }); + it('converts rem to sp using custom base font', () => { + var value = transforms["size/remToSp"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value).toBe("14.00sp"); + }); it('should throw an error if prop value is Nan', () => { expect( () => transforms["size/dp"].transformer({value: "a"})).toThrow(); }); @@ -503,6 +542,10 @@ describe('common', () => { }); expect(value).toBe("16.00dp"); }); + it('converts rem to dp using custom base font', () => { + var value = transforms["size/remToDp"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value).toBe("14.00dp"); + }); it('should throw an error if prop value is Nan', () => { expect( () => transforms["size/dp"].transformer({value: "a"})).toThrow(); }); @@ -527,11 +570,75 @@ describe('common', () => { }); expect(value).toBe("16.00f"); }); + it('converts rem to pt using custom base font', () => { + var value = transforms["size/remToPt"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value).toBe("14.00f"); + }); it('should throw an error if prop value is Nan', () => { expect( () => transforms["size/dp"].transformer({value: "a"})).toThrow(); }); }); + describe('size/compose/remToSp', () => { + it('should work', () => { + var value = transforms["size/compose/remToSp"].transformer({ + value: "1" + }); + expect(value).toBe("16.00.sp"); + }); + it('converts rem to sp using custom base font', () => { + var value = transforms["size/compose/remToSp"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value).toBe("14.00.sp"); + }); + it('should throw an error if prop value is Nan', () => { + expect( () => transforms["size/compose/remToSp"].transformer({value: "a"})).toThrow(); + }); + }); + + describe('size/compose/em', () => { + it('should work', () => { + var value = transforms["size/compose/em"].transformer({ + value: "10" + }); + expect(value).toBe("10.em"); + }); + it('should throw an error if prop value is Nan', () => { + expect( () => transforms["size/compose/em"].transformer({value: "a"})).toThrow(); + }); + }); + + describe('size/compose/remToDp', () => { + it('should work', () => { + var value = transforms["size/compose/remToDp"].transformer({ + value: "1" + }); + expect(value).toBe("16.00.dp"); + }); + it('converts rem to dp using custom base font', () => { + var value = transforms["size/compose/remToDp"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value).toBe("14.00.dp"); + }); + it('should throw an error if prop value is Nan', () => { + expect( () => transforms["size/compose/remToDp"].transformer({value: "a"})).toThrow(); + }); + }); + + describe('size/swift/remToCGFloat', () => { + it('should work', () => { + var value = transforms["size/swift/remToCGFloat"].transformer({ + value: "1" + }); + expect(value).toBe("CGFloat(16.00)"); + }); + it('converts rem to CGFloat using custom base font', () => { + var value = transforms["size/swift/remToCGFloat"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value).toBe("CGFloat(14.00)"); + }); + it('should throw an error if prop value is Nan', () => { + expect( () => transforms["size/rem/remToCGFloat"].transformer({value: "a"})).toThrow(); + }); + }); + describe('size/remToPx', () => { it('should work', () => { var value = transforms["size/remToPx"].transformer({ @@ -539,11 +646,36 @@ describe('common', () => { }); expect(value).toBe("16px"); }); + it('converts rem to px using custom base font', () => { + var value = transforms["size/remToPx"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value).toBe("14px"); + }); it('should throw an error if prop value is Nan', () => { expect( () => transforms["size/dp"].transformer({value: "a"})).toThrow(); }); }); + describe('size/pxToRem', () => { + const pxToRemTransformer = transforms["size/pxToRem"].transformer; + + ['12', '12px', '12rem'].forEach((value) => { + it(`ignoring unit, scales "${value}" to rem`, () => { + expect(pxToRemTransformer({value})).toBe('0.75rem'); + }); + }); + it('converts pixel to rem using custom base font', () => { + expect(pxToRemTransformer({value: '14px'}, {basePxFontSize: 14})).toBe('1rem'); + }); + ['0', '0px', '0rem'].forEach((value) => { + it(`zero value "${value}" is returned without a unit`, () => { + expect(pxToRemTransformer({value})).toBe('0'); + }); + }); + it('should throw an error if prop value is Nan', () => { + expect( () => pxToRemTransformer({value: "a"})).toThrow(); + }); + }); + describe('size/rem', () => { it('should work', () => { var value = transforms["size/rem"].transformer({ @@ -563,6 +695,10 @@ describe('common', () => { }); expect(value).toBe("16.00"); }); + it('converts rem to double using custom base font', () => { + var value = transforms["size/flutter/remToDouble"].transformer({value: "1"}, {basePxFontSize: 14}); + expect(value).toBe("14.00"); + }); }); describe('content/quote', () => { diff --git a/__tests__/exportPlatform.test.js b/__tests__/exportPlatform.test.js index 62f961805..6602f6472 100644 --- a/__tests__/exportPlatform.test.js +++ b/__tests__/exportPlatform.test.js @@ -11,17 +11,17 @@ * and limitations under the License. */ -var helpers = require('./__helpers'); -var keys = require('lodash/keys'); -var config = helpers.fileToJSON(__dirname + '/__configs/test.json'); -var StyleDictionary = require('../index').extend(config); +const helpers = require('./__helpers'); +const config = helpers.fileToJSON(__dirname + '/__configs/test.json'); +const StyleDictionary = require('../index'); +const styleDictionary = StyleDictionary.extend(config); describe('exportPlatform', () => { it('should throw if not given a platform', () => { expect( function(){ - StyleDictionary.exportPlatform() + styleDictionary.exportPlatform() } ).toThrow(); }); @@ -29,7 +29,7 @@ describe('exportPlatform', () => { it('should throw if not given a proper platform', () => { expect( function(){ - StyleDictionary.exportPlatform('foo'); + styleDictionary.exportPlatform('foo'); } ).toThrow(); }); @@ -37,43 +37,154 @@ describe('exportPlatform', () => { it('should not throw if given a proper platform', () => { expect( function(){ - StyleDictionary.exportPlatform('web'); + styleDictionary.exportPlatform('web'); } ).not.toThrow(); }); it('should return an object', () => { - var dictionary = StyleDictionary.exportPlatform('web'); + var dictionary = styleDictionary.exportPlatform('web'); expect(typeof dictionary).toBe('object'); }); it('should have the same structure as the original properties', () => { - var dictionary = StyleDictionary.exportPlatform('web'); - expect(keys(dictionary)).toEqual(keys(StyleDictionary.properties)); + var dictionary = styleDictionary.exportPlatform('web'); + expect(Object.keys(dictionary)).toEqual(Object.keys(styleDictionary.properties)); }); it('should have resolved references', () => { - var dictionary = StyleDictionary.exportPlatform('web'); + var dictionary = styleDictionary.exportPlatform('web'); expect(dictionary.color.font.link.value).toEqual(dictionary.color.base.blue['100'].value); }); it('should have applied transforms', () => { - var dictionary = StyleDictionary.exportPlatform('web'); + var dictionary = styleDictionary.exportPlatform('web'); expect(dictionary.size.padding.base.value.indexOf('px')).toBeGreaterThan(0); }); + it('should have applied transforms for props with refs in it', () => { + const StyleDictionaryExtended = styleDictionary.extend({ + platforms: { + test: { + transforms: ['color/css','color/darken'] + } + } + }); + + StyleDictionaryExtended.registerTransform({ + type: 'value', + name: 'color/darken', + transitive: true, + matcher: function(prop) { return !!prop.original.transformColor; }, + transformer: function(prop) { return prop.value + '-darker'; } + }); + + const dictionary = StyleDictionaryExtended.exportPlatform('test'); + + expect(dictionary.color.button.active.value).toEqual('#0077CC-darker'); + expect(dictionary.color.button.hover.value).toEqual('#0077CC-darker-darker'); + }); + it('should not have mutated the original properties', () => { - var dictionary = StyleDictionary.exportPlatform('web'); - expect(dictionary.color.font.link.value).not.toEqual(StyleDictionary.properties.color.font.link.value); - expect(StyleDictionary.properties.size.padding.base.value.indexOf('px')).toBe(-1); + var dictionary = styleDictionary.exportPlatform('web'); + expect(dictionary.color.font.link.value).not.toEqual(styleDictionary.properties.color.font.link.value); + expect(styleDictionary.properties.size.padding.base.value.indexOf('px')).toBe(-1); }); // Make sure when we perform transforms and resolve references // we don't mutate the original object added to the property. it('properties should have original value untouched', () => { - var dictionary = StyleDictionary.exportPlatform('web'); + var dictionary = styleDictionary.exportPlatform('web'); var properties = helpers.fileToJSON(__dirname + '/__properties/colors.json'); expect(dictionary.color.font.link.original.value).toEqual(properties.color.font.link.value); }); + it('should not mutate original value if value is an object', () => { + const dictionary = StyleDictionary.extend({ + properties: { + color: { + red: { + value: { + h: "{hue.red}", + s: 50, + l: 50 + } + } + }, + hue: { + red: 20 + } + }, + platforms: { + web: { + transformGroup: 'web' + } + } + }).exportPlatform('web'); + expect(dictionary.color.red.original.value.h).toEqual("{hue.red}"); + expect(dictionary.color.red.value.h).toEqual(20); + }); + + describe('reference warnings', () => { + const errorMessage = `Problems were found when trying to resolve property references`; + const platforms = { + css: { + transformGroup: `css` + } + } + + it('should throw if there are simple property reference errors', () => { + const properties = { + a: "#ff0000", + b: "{c}" + } + expect( + function() { + StyleDictionary.extend({ + properties, + platforms + }).exportPlatform('css') + } + ).toThrow(errorMessage); + }); + + it('should throw if there are circular reference errors', () => { + const properties = { + a: "{b}", + b: "{a}" + } + expect( + function() { + StyleDictionary.extend({ + properties, + platforms + }).exportPlatform('css') + } + ).toThrow(errorMessage); + }); + + it('should throw if there are complex property reference errors', () => { + const properties = { + color: { + core: { + red: { valuer: "#ff0000" }, // notice misspelling + blue: { "value:": "#0000ff" } + }, + danger: { value: "{color.core.red.value}" }, + warning: { value: "{color.base.red.valuer}" }, + info: { value: "{color.core.blue.value}" }, + error: { value: "{color.danger.value}" } + } + } + expect( + function() { + StyleDictionary.extend({ + properties, + platforms + }).exportPlatform('css') + } + ).toThrow(errorMessage); + }); + }); + }); diff --git a/__tests__/extend.test.js b/__tests__/extend.test.js index 0bce2ad76..fda698d13 100644 --- a/__tests__/extend.test.js +++ b/__tests__/extend.test.js @@ -13,7 +13,16 @@ var helpers = require('./__helpers'); var StyleDictionary = require('../index'); -var _ = require('lodash'); +var _ = require('../lib/utils/es6_'); + +function traverseObj(obj, fn) { + for (let key in obj) { + fn.apply(this, [obj, key, obj[key]]); + if (obj[key] && typeof obj[key] === 'object') { + traverseObj(obj[key], fn); + } + } +} var test_props = { size: { @@ -24,7 +33,6 @@ var test_props = { }; describe('extend', () => { - describe('method signature', () => { it('should accept a string as a path to a JSON file', () => { var StyleDictionaryExtended = StyleDictionary.extend(__dirname + '/__configs/test.json'); @@ -77,17 +85,31 @@ describe('extend', () => { it('should build the properties object if an include is given', () => { var StyleDictionaryExtended = StyleDictionary.extend({ - "include": [__dirname + "/__properties/paddings.json"] + include: [__dirname + "/__properties/paddings.json"] }); - expect(StyleDictionaryExtended.properties).toEqual(helpers.fileToJSON(__dirname + "/__properties/paddings.json")); + var output = helpers.fileToJSON(__dirname + "/__properties/paddings.json"); + traverseObj(output, (obj) => { + if (obj.hasOwnProperty('value') && !obj.filePath) { + obj.filePath = __dirname + "/__properties/paddings.json"; + obj.isSource = false; + } + }); + expect(StyleDictionaryExtended.properties).toEqual(output); }); it('should override existing properties if include is given', () => { var StyleDictionaryExtended = StyleDictionary.extend({ properties: test_props, - include: [__dirname + "/__properties/paddings.json"] + "include": [__dirname + "/__properties/paddings.json"] }); - expect(StyleDictionaryExtended.properties).toEqual(helpers.fileToJSON(__dirname + "/__properties/paddings.json")); + var output = helpers.fileToJSON(__dirname + "/__properties/paddings.json"); + traverseObj(output, (obj) => { + if (obj.hasOwnProperty('value') && !obj.filePath) { + obj.filePath = __dirname + "/__properties/paddings.json"; + obj.isSource = false; + } + }); + expect(StyleDictionaryExtended.properties).toEqual(output); }); it('should update properties if there are includes', () => { @@ -106,7 +128,6 @@ describe('extend', () => { }); }); - describe('source', () => { it('should throw if source isnt an array', () => { expect( @@ -125,7 +146,29 @@ describe('extend', () => { var StyleDictionaryExtended = StyleDictionary.extend({ "source": [__dirname + "/__properties/paddings.json"] }); - expect(StyleDictionaryExtended.properties).toEqual(helpers.fileToJSON(__dirname + "/__properties/paddings.json")); + var output = helpers.fileToJSON(__dirname + "/__properties/paddings.json"); + traverseObj(output, (obj) => { + if (obj.hasOwnProperty('value') && !obj.filePath) { + obj.filePath = __dirname + "/__properties/paddings.json"; + obj.isSource = true; + } + }); + expect(StyleDictionaryExtended.properties).toEqual(output); + }); + + it('should use relative filePaths for the filePath property', () => { + var filePath = "__tests__/__properties/paddings.json"; + var StyleDictionaryExtended = StyleDictionary.extend({ + "source": [filePath] + }); + var output = helpers.fileToJSON(__dirname + "/__properties/paddings.json"); + traverseObj(output, (obj) => { + if (obj.hasOwnProperty('value') && !obj.filePath) { + obj.filePath = filePath; + obj.isSource = true; + } + }); + expect(StyleDictionaryExtended.properties).toEqual(output); }); it('should override existing properties source is given', () => { @@ -133,26 +176,39 @@ describe('extend', () => { properties: test_props, source: [__dirname + "/__properties/paddings.json"] }); - expect(StyleDictionaryExtended.properties).toEqual(helpers.fileToJSON(__dirname + "/__properties/paddings.json")); + var output = helpers.fileToJSON(__dirname + "/__properties/paddings.json"); + traverseObj(output, (obj) => { + if (obj.hasOwnProperty('value') && !obj.filePath) { + obj.filePath = __dirname + "/__properties/paddings.json"; + obj.isSource = true; + } + }); + expect(StyleDictionaryExtended.properties).toEqual(output); }); }); - // This is to allow style dictionaries to depend on other style dictionaries and // override properties. Useful for skinning it('should not throw a collision error if a source file collides with an include', () => { var StyleDictionaryExtended = StyleDictionary.extend({ - include: [__dirname + "/__properties/paddings.json"], + include: [__dirname + "/__properties/paddings.1.json"], source: [__dirname + "/__properties/paddings.json"], log: 'error' }); - expect(StyleDictionaryExtended.properties).toEqual(helpers.fileToJSON(__dirname + "/__properties/paddings.json")); + var output = helpers.fileToJSON(__dirname + "/__properties/paddings.json"); + traverseObj(output, (obj) => { + if (obj.hasOwnProperty('value') && !obj.filePath) { + obj.filePath = __dirname + "/__properties/paddings.json"; + obj.isSource = true; + } + }); + expect(StyleDictionaryExtended.properties).toEqual(output); }); it('should throw a error if the collision is in source files and log is set to error', () => { expect( StyleDictionary.extend.bind(null, { - source: [__dirname + "/__properties/paddings.json", __dirname + "/__properties/paddings.json"], + source: [__dirname + "/__properties/paddings.1.json", __dirname + "/__properties/paddings.json"], log: 'error' }) ).toThrow('Collisions detected'); diff --git a/__tests__/filterProperties.test.js b/__tests__/filterProperties.test.js index 157629d8f..c435bbf29 100644 --- a/__tests__/filterProperties.test.js +++ b/__tests__/filterProperties.test.js @@ -14,7 +14,7 @@ var filterProperties = require('../lib/filterProperties'); var helpers = require('./__helpers'); var flattenProperties = require("../lib/utils/flattenProperties"); -var _ = require('lodash'); +var _ = require('../lib/utils/es6_'); var colorRed = { "value": "#FF0000", diff --git a/__tests__/formats/__constants.js b/__tests__/formats/__constants.js new file mode 100644 index 000000000..de6c91b27 --- /dev/null +++ b/__tests__/formats/__constants.js @@ -0,0 +1,64 @@ +const createDictionary = require("../../lib/utils/createDictionary"); + +const colorPropertyName = "color-base-red-400"; +const colorPropertyValue = "#EF5350"; + +const colorProperties = { + color: { + base: { + red: { + 400: { + "name": colorPropertyName, + "value": colorPropertyValue, + "original": { + "value": colorPropertyValue + }, + "attributes": { + "category": "color", + "type": "base", + "item": "red", + "subitem": "400" + }, + "path": [ + "color", + "base", + "red", + "400" + ] + } + } + } + } +}; + +const iconPropertyName = "content-icon-email"; +const iconPropertyValue = "'\\E001'"; +const itemClass = "3d_rotation"; + +const iconProperties = { + content: { + icon: { + email: { + "name": iconPropertyName, + "value": iconPropertyValue, + "original": { + "value": iconPropertyValue + }, + "attributes": { + "category": "content", + "type": "icon", + "item": itemClass + }, + path: ['content','icon','email'] + } + } + } +}; + +const colorDictionary = createDictionary({ properties: colorProperties }); +const iconDictionary = createDictionary({ properties: iconProperties }); + +module.exports = { + colorDictionary, + iconDictionary +} \ No newline at end of file diff --git a/__tests__/formats/__snapshots__/all.test.js.snap b/__tests__/formats/__snapshots__/all.test.js.snap index 86f5b33de..42cc329bd 100644 --- a/__tests__/formats/__snapshots__/all.test.js.snap +++ b/__tests__/formats/__snapshots__/all.test.js.snap @@ -53,6 +53,20 @@ exports[`formats all should match android/integers snapshot 1`] = ` " `; +exports[`formats all should match android/resources snapshot 1`] = ` +" + + + + #FF0000 + + +" +`; + exports[`formats all should match android/strings snapshot 1`] = ` " @@ -66,6 +80,27 @@ exports[`formats all should match android/strings snapshot 1`] = ` " `; +exports[`formats all should match compose/object snapshot 1`] = ` +" + +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + + + +package ; + + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.* + +object { + /** comment */ + val color_red = #FF0000 +} +" +`; + exports[`formats all should match css/fonts.css snapshot 1`] = ` " " @@ -88,17 +123,18 @@ exports[`formats all should match flutter/class.dart snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// + import 'dart:ui'; class { ._(); - - static const color_red = #FF0000; + + static const color_red = #FF0000; /* comment */ }" `; @@ -107,12 +143,12 @@ exports[`formats all should match ios/colors.h snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// -#import +#import typedef NS_ENUM(NSInteger, ) { color_red @@ -130,12 +166,12 @@ exports[`formats all should match ios/colors.m snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// -#import \\".h\\" +#import \\".h\\" @implementation @@ -165,15 +201,14 @@ exports[`formats all should match ios/macros snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// + #import #import - - #define color_red #FF0000 " @@ -211,9 +246,10 @@ exports[`formats all should match ios/singleton.h snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// + #import #import @@ -233,9 +269,10 @@ exports[`formats all should match ios/singleton.m snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// + #import \\".h\\" @@ -279,12 +316,12 @@ exports[`formats all should match ios/static.h snapshot 1`] = ` " // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// -#import +#import extern const color_red; @@ -296,12 +333,12 @@ exports[`formats all should match ios/static.m snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// -#import \\".h\\" +#import \\".h\\" const color_red = #FF0000; @@ -313,12 +350,12 @@ exports[`formats all should match ios/strings.h snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// -#import +#import extern NSString * const color_red; @@ -334,12 +371,12 @@ exports[`formats all should match ios/strings.m snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// -#import \\".h\\" +#import \\".h\\" NSString * const color_red = #FF0000; @@ -375,15 +412,15 @@ exports[`formats all should match ios-swift/class.swift snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// import UIKit public class { - public static let color_red = #FF0000 + public static let color_red = #FF0000 /* comment */ } " `; @@ -393,14 +430,15 @@ exports[`formats all should match ios-swift/enum.swift snapshot 1`] = ` // // __output/ // + // Do not edit directly // Generated on Sat, 01 Jan 2000 00:00:00 GMT -// + import UIKit public enum { - public static let color_red = #FF0000 + public static let color_red = #FF0000 /* comment */ } " `; @@ -442,6 +480,17 @@ module.exports = { };" `; +exports[`formats all should match javascript/module-flat snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +module.exports = { + \\"color_red\\": \\"#FF0000\\" +};" +`; + exports[`formats all should match javascript/object snapshot 1`] = ` "/** * Do not edit directly @@ -568,10 +617,10 @@ exports[`formats all should match less/variables snapshot 1`] = ` exports[`formats all should match sass/map-deep snapshot 1`] = ` " -/* - Do not edit directly - Generated on Sat, 01 Jan 2000 00:00:00 GMT -*/ +/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ $color_red: #FF0000 !default; // comment @@ -585,10 +634,10 @@ $tokens: ( exports[`formats all should match sass/map-flat snapshot 1`] = ` " -/* - Do not edit directly - Generated on Sat, 01 Jan 2000 00:00:00 GMT -*/ +/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ $tokens: ( // comment @@ -607,10 +656,10 @@ exports[`formats all should match scss/icons snapshot 1`] = ` exports[`formats all should match scss/map-deep snapshot 1`] = ` " -/* - Do not edit directly - Generated on Sat, 01 Jan 2000 00:00:00 GMT -*/ +/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ $color_red: #FF0000 !default; // comment @@ -624,10 +673,10 @@ $tokens: ( exports[`formats all should match scss/map-flat snapshot 1`] = ` " -/* - Do not edit directly - Generated on Sat, 01 Jan 2000 00:00:00 GMT -*/ +/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ $tokens: ( // comment @@ -670,3 +719,51 @@ exports[`formats all should match sketch/palette/v2 snapshot 1`] = ` ] }" `; + +exports[`formats all should match stylus/variables snapshot 1`] = ` +" +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + +$color_red= #FF0000; // comment" +`; + +exports[`formats all should match typescript/es6-declarations snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +export const color_red : string; // comment" +`; + +exports[`formats all should match typescript/module-declarations snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +export default tokens; + +declare interface DesignToken { + value: any; + name?: string; + comment?: string; + themeable?: boolean; + attributes?: { + category?: string; + type?: string; + item?: string; + subitem?: string; + state?: string; + [key: string]: any; + }; + [key: string]: any; +} + +declare const tokens: { + \\"color\\": { + \\"red\\": DesignToken + } +}" +`; diff --git a/__tests__/formats/__snapshots__/androidResources.test.js.snap b/__tests__/formats/__snapshots__/androidResources.test.js.snap new file mode 100644 index 000000000..b172aa532 --- /dev/null +++ b/__tests__/formats/__snapshots__/androidResources.test.js.snap @@ -0,0 +1,50 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`formats android/resources should match default snapshot 1`] = ` +" + + + + 12rem + 18rem + #ff0000 + #ffffff + + +" +`; + +exports[`formats android/resources with resourceMap override should match snapshot 1`] = ` +" + + + + #F2F3F4 + #000000 + + +" +`; + +exports[`formats android/resources with resourceType override should match snapshot 1`] = ` +" + + + + 12rem + 18rem + #ff0000 + #ffffff + + +" +`; diff --git a/__tests__/formats/__snapshots__/scssMaps.test.js.snap b/__tests__/formats/__snapshots__/scssMaps.test.js.snap index 2c19142cf..8a24215f5 100644 --- a/__tests__/formats/__snapshots__/scssMaps.test.js.snap +++ b/__tests__/formats/__snapshots__/scssMaps.test.js.snap @@ -2,10 +2,10 @@ exports[`formats scss/map-deep scss/map-deep snapshot 1`] = ` " -/* - Do not edit directly - Generated on Sat, 01 Jan 2000 00:00:00 GMT -*/ +/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ $size-font-small: 12rem !default; $size-font-large: 18rem !default; @@ -37,10 +37,10 @@ $tokens: ( exports[`formats scss/map-flat scss/map-flat snapshot 1`] = ` " -/* - Do not edit directly - Generated on Sat, 01 Jan 2000 00:00:00 GMT -*/ +/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ $tokens: ( 'size-font-small': 12rem, diff --git a/__tests__/formats/all.test.js b/__tests__/formats/all.test.js index 417033b56..d24c16520 100644 --- a/__tests__/formats/all.test.js +++ b/__tests__/formats/all.test.js @@ -12,7 +12,9 @@ */ var formats = require('../../lib/common/formats'); -var _ = require('lodash'); +var createDictionary = require('../../lib/utils/createDictionary'); +var createFormatArgs = require('../../lib/utils/createFormatArgs'); +var _ = require('../../lib/utils/es6_'); var file = { "destination": "__output/", @@ -24,37 +26,21 @@ var file = { } }; -var dictionary = { - "allProperties": [{ +var properties = { + "color": { + "red": { value: '#FF0000', original: { value: '#FF0000' }, name: 'color_red', comment: 'comment', attributes: { - category: 'color', - type: 'red', - item: undefined, - subitem: undefined, - state: undefined + category: 'color', + type: 'red', + item: undefined, + subitem: undefined, + state: undefined }, path: ['color','red'] - }], - "properties": { - "color": { - "red": { - value: '#FF0000', - original: { value: '#FF0000' }, - name: 'color_red', - comment: 'comment', - attributes: { - category: 'color', - type: 'red', - item: undefined, - subitem: undefined, - state: undefined - }, - path: ['color','red'] - } } } }; @@ -62,15 +48,13 @@ var dictionary = { describe('formats', () => { _.each(_.keys(formats), function(key) { - const constantDate = new Date('2000-01-01'); - const globalDate = global.Date; - global.Date = function() { return constantDate }; - var formatter = formats[key].bind(file); - var output = formatter(dictionary, file); - - // reset the global Date object - global.Date = globalDate; + const dictionary = createDictionary({ properties }); + var output = formatter(createFormatArgs({ + dictionary, + file, + platform: {}, + }), {}, file); describe('all', () => { diff --git a/__tests__/formats/androidResources.test.js b/__tests__/formats/androidResources.test.js new file mode 100644 index 000000000..49d4780ba --- /dev/null +++ b/__tests__/formats/androidResources.test.js @@ -0,0 +1,167 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const formats = require('../../lib/common/formats'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); + +const properties = { + "size": { + "font": { + "small": { + "value": "12rem", + "original": { + "value": "12px" + }, + "name": "size-font-small", + "attributes": { + "category": "size", + "type": "font", + "item": "small" + }, + "path": [ + "size", + "font", + "small" + ] + }, + "large": { + "value": "18rem", + "original": { + "value": "18px" + }, + "name": "size-font-large", + "attributes": { + "category": "size", + "type": "font", + "item": "large" + }, + "path": [ + "size", + "font", + "large" + ] + } + } + }, + "color": { + "base": { + "red": { + "value": "#ff0000", + "comment": "comment", + "original": { + "value": "#FF0000", + "comment": "comment" + }, + "name": "color-base-red", + "attributes": { + "category": "color", + "type": "base", + "item": "red" + }, + "path": [ + "color", + "base", + "red" + ] + } + }, + "white": { + "value": "#ffffff", + "original": { + "value": "#ffffff" + }, + "name": "color-white", + "attributes": { + "category": "color", + "type": "white" + }, + "path": [ + "color", + "white" + ] + } + }, +}; + +const customProperties = { + backgroundColor: { + secondary: { + name: "backgroundColorSecondary", + value: "#F2F3F4", + attributes: { + category: "backgroundColor" + } + } + }, + fontColor: { + primary: { + name: "fontColorPrimary", + value: "#000000", + attributes: { + category: "fontColor" + } + } + }, +}; + +const format = formats['android/resources']; +const file = { + "destination": "__output/", + "format": 'android/resources' +}; + +const dictionary = createDictionary({ properties }); +const customDictionary = createDictionary({ properties: customProperties }); + +describe('formats', () => { + + describe(`android/resources`, () => { + + it('should match default snapshot', () => { + expect(format(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file)).toMatchSnapshot(); + }); + + it('with resourceType override should match snapshot', () => { + const file = {resourceType: "dimen"} + expect(format(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file)).toMatchSnapshot(); + }); + + it('with resourceMap override should match snapshot', () => { + const file = { + resourceMap: { + color: 'color', + fontColor: 'color', + backgroundColor: 'color' + } + }; + expect( + format(createFormatArgs({ + dictionary: customDictionary, + file, + platform: {} + }), {}, file) + ).toMatchSnapshot(); + }); + + }); + +}); diff --git a/__tests__/formats/es6Constants.test.js b/__tests__/formats/es6Constants.test.js index c0728424d..c2db78ac0 100644 --- a/__tests__/formats/es6Constants.test.js +++ b/__tests__/formats/es6Constants.test.js @@ -10,11 +10,13 @@ * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -var fs = require('fs-extra'); -var helpers = require('../__helpers'); -var formats = require('../../lib/common/formats'); +const fs = require('fs-extra'); +const helpers = require('../__helpers'); +const formats = require('../../lib/common/formats'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { "destination": "__output/", "format": "javascript/es6", "filter": { @@ -24,29 +26,32 @@ var file = { } }; -var dictionary = { - "allProperties": [{ - "name": "red", - "value": "#EF5350", - "original": { - "value": "#EF5350" - }, - "attributes": { - "category": "color", - "type": "base", - "item": "red", - "subitem": "400" - }, - "path": [ - "color", - "base", - "red", - "400" - ] - }] +const properties = { + color: { + red: { + "name": "red", + "value": "#EF5350", + "original": { + "value": "#EF5350" + }, + "attributes": { + "category": "color", + "type": "base", + "item": "red", + "subitem": "400" + }, + "path": [ + "color", + "base", + "red", + "400" + ] + } + } }; -var formatter = formats['javascript/es6'].bind(file); +const formatter = formats['javascript/es6'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', () => { describe('javascript/es6', () => { @@ -59,8 +64,12 @@ describe('formats', () => { }); it('should be a valid JS file', () => { - fs.writeFileSync('./__tests__/__output/output.js', formatter(dictionary) ); - var test = require('../__output/output.js'); + fs.writeFileSync('./__tests__/__output/output.js', formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file) ); + const test = require('../__output/output.js'); expect(test.red).toEqual(dictionary.allProperties[0].value); }); }); diff --git a/__tests__/formats/javascriptModule.test.js b/__tests__/formats/javascriptModule.test.js index 6d561ff12..8f24f4b59 100644 --- a/__tests__/formats/javascriptModule.test.js +++ b/__tests__/formats/javascriptModule.test.js @@ -11,11 +11,13 @@ * and limitations under the License. */ -var fs = require('fs-extra'); -var helpers = require('../__helpers'); -var formats = require('../../lib/common/formats'); +const fs = require('fs-extra'); +const helpers = require('../__helpers'); +const formats = require('../../lib/common/formats'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { "destination": "__output/", "format": "javascript/module", "filter": { @@ -25,15 +27,14 @@ var file = { } }; -var dictionary = { - "properties": { - "color": { - "red": {"value": "#FF0000"} - } +const properties = { + "color": { + "red": {"value": "#FF0000"} } }; -var formatter = formats['javascript/module'].bind(file); +const formatter = formats['javascript/module'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', () => { describe('javascript/module', () => { @@ -47,8 +48,12 @@ describe('formats', () => { }); it('should be a valid JS file', () => { - fs.writeFileSync('./__tests__/__output/output.js', formatter(dictionary) ); - var test = require('../__output/output.js'); + fs.writeFileSync('./__tests__/__output/output.js', formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file) ); + const test = require('../__output/output.js'); expect(test.color.red.value).toEqual(dictionary.properties.color.red.value); }); diff --git a/__tests__/formats/javascriptModuleFlat.test.js b/__tests__/formats/javascriptModuleFlat.test.js new file mode 100644 index 000000000..47378aeac --- /dev/null +++ b/__tests__/formats/javascriptModuleFlat.test.js @@ -0,0 +1,69 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const fs = require('fs-extra'); +const helpers = require('../__helpers'); +const formats = require('../../lib/common/formats'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); + +const file = { + "destination": "__output/", + "format": "javascript/module-flat", +}; +const properties = { + color: { + red: { + value: "#EF5350", + name: "ColorRed", + original: { + value: "#EF5350" + }, + attributes: { + category: "color", + type: "red" + }, + path: [ + "color", + "red" + ] + } + } +}; + +const formatter = formats['javascript/module-flat'].bind(file); +const dictionary = createDictionary({ properties }); + +describe('formats', () => { + describe('javascript/module-flat', () => { + + beforeEach(() => { + helpers.clearOutput(); + }); + + afterEach(() => { + helpers.clearOutput(); + }); + + it('should be a valid JS file', () => { + fs.writeFileSync('./__tests__/__output/output.js', formatter(createFormatArgs({ + dictionary, + file: {}, + platform: {} + }), {}, {}) ); + const test = require('../__output/output.js'); + expect(test.ColorRed).toEqual(dictionary.allProperties[0].value); + }); + + }); +}); diff --git a/__tests__/formats/javascriptObject.test.js b/__tests__/formats/javascriptObject.test.js index 94ad8500f..50276a2d6 100644 --- a/__tests__/formats/javascriptObject.test.js +++ b/__tests__/formats/javascriptObject.test.js @@ -11,35 +11,38 @@ * and limitations under the License. */ -var formats = require('../../lib/common/formats'); -var vm = require('vm'); +const formats = require('../../lib/common/formats'); +const vm = require('vm'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { "destination": "__output/", "format": "javascript/object", "name": "foo" }; -var dictionary = { - "properties": { - "color": { - "red": {"value": "#FF0000"} - } +const properties = { + "color": { + "red": {"value": "#FF0000"} } }; -var formatter = formats['javascript/object'].bind(file); +const formatter = formats['javascript/object'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', () => { describe('javascript/object', () => { - it('should be valid JS syntax', done => { - try { - vm.runInNewContext(formatter(dictionary)) - return done(); - } catch (err) { - return done(new Error(err)); - } + it('should be valid JS syntax', () => { + const script = new vm.Script(formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file)); + const context = {}; + script.runInNewContext(context); + expect(context.foo.color.red.value).toEqual(dictionary.properties.color.red.value); }); }); diff --git a/__tests__/formats/javascriptUmd.test.js b/__tests__/formats/javascriptUmd.test.js index 91752177e..59ff5c7c5 100644 --- a/__tests__/formats/javascriptUmd.test.js +++ b/__tests__/formats/javascriptUmd.test.js @@ -11,11 +11,13 @@ * and limitations under the License. */ -var formats = require('../../lib/common/formats'); -var fs = require('fs-extra'); -var helpers = require('../__helpers'); +const formats = require('../../lib/common/formats'); +const fs = require('fs-extra'); +const helpers = require('../__helpers'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { "destination": "__output/", "format": "javascript/umd", "filter": { @@ -25,15 +27,14 @@ var file = { } }; -var dictionary = { - "properties": { - "color": { - "red": {"value": "#FF0000"} - } +const properties = { + "color": { + "red": {"value": "#FF0000"} } }; -var formatter = formats['javascript/umd'].bind(file); +const formatter = formats['javascript/umd'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', () => { describe('javascript/umd', () => { @@ -47,8 +48,12 @@ describe('formats', () => { }); it('should be a valid JS file', () => { - fs.writeFileSync('./__tests__/__output/umd.js', formatter(dictionary) ); - var test = require('../__output/umd.js'); + fs.writeFileSync('./__tests__/__output/umd.js', formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file) ); + const test = require('../__output/umd.js'); expect(test.color.red.value).toEqual(dictionary.properties.color.red.value); }); diff --git a/__tests__/formats/json.test.js b/__tests__/formats/json.test.js index b59991b88..422ad6bb6 100644 --- a/__tests__/formats/json.test.js +++ b/__tests__/formats/json.test.js @@ -11,24 +11,25 @@ * and limitations under the License. */ -var formats = require('../../lib/common/formats'); -var fs = require('fs-extra'); -var helpers = require('../__helpers'); +const formats = require('../../lib/common/formats'); +const fs = require('fs-extra'); +const helpers = require('../__helpers'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { "destination": "__output/", "format": "json" }; -var dictionary = { - "properties": { - "color": { - "red": {"value": "#FF0000"} - } +const properties = { + "color": { + "red": {"value": "#FF0000"} } }; -var formatter = formats['json'].bind(file); +const formatter = formats['json'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', () => { describe('json', () => { @@ -42,8 +43,12 @@ describe('formats', () => { }); it('should be a valid JSON file', () => { - fs.writeFileSync('./__tests__/__output/output.json', formatter(dictionary) ); - var test = require('../__output/output.json'); + fs.writeFileSync('./__tests__/__output/output.json', formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file) ); + const test = require('../__output/output.json'); expect(test.color.red.value).toEqual(dictionary.properties.color.red.value); }); }); diff --git a/__tests__/formats/jsonFlat.test.js b/__tests__/formats/jsonFlat.test.js index 2bf19a0e6..565b68348 100644 --- a/__tests__/formats/jsonFlat.test.js +++ b/__tests__/formats/jsonFlat.test.js @@ -11,36 +11,18 @@ * and limitations under the License. */ -var formats = require('../../lib/common/formats'); -var fs = require('fs-extra'); -var helpers = require('../__helpers'); +const formats = require('../../lib/common/formats'); +const fs = require('fs-extra'); +const helpers = require('../__helpers'); +const { colorDictionary } = require('./__constants'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { "destination": "__output/", "format": "json/flat" }; -var dictionary = { - "allProperties": [{ - "name": "color-base-red", - "value": "#EF5350", - "original": { - "value": "#EF5350" - }, - "attributes": { - "category": "color", - "type": "base", - "item": "red" - }, - "path": [ - "color", - "base", - "red" - ] - }] -}; - -var formatter = formats['json/flat'].bind(file); +const formatter = formats['json/flat'].bind(file); describe('formats', () => { describe('json/flat', () => { @@ -54,9 +36,13 @@ describe('formats', () => { }); it('should be a valid JSON file', () => { - fs.writeFileSync('./__tests__/__output/output.flat.json', formatter(dictionary) ); - var test = require('../__output/output.flat.json'); - expect(test['color-base-red']).toEqual(dictionary.allProperties[0].value); + fs.writeFileSync('./__tests__/__output/output.flat.json', formatter(createFormatArgs({ + dictionary: colorDictionary, + file, + platform: {} + }), {}, file) ); + const test = require('../__output/output.flat.json'); + expect(test['color-base-red-400']).toEqual(colorDictionary.allProperties[0].value); }); }); diff --git a/__tests__/formats/jsonNested.test.js b/__tests__/formats/jsonNested.test.js index 7449f0aed..32ba7709a 100644 --- a/__tests__/formats/jsonNested.test.js +++ b/__tests__/formats/jsonNested.test.js @@ -11,33 +11,34 @@ * and limitations under the License. */ -var formats = require('../../lib/common/formats'); -var fs = require('fs-extra'); -var helpers = require('../__helpers'); +const formats = require('../../lib/common/formats'); +const fs = require('fs-extra'); +const helpers = require('../__helpers'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { destination: 'output/', format: 'json/nested', }; -var dictionary = { - properties: { - color: { - base: { - comment: 'This is a comment', - metadata: [1,2,3], - red: { - primary: { value: '#611D1C' }, - secondary: { - inverse: { value: '#000000' }, - }, +const properties = { + color: { + base: { + comment: 'This is a comment', + metadata: [1,2,3], + red: { + primary: { value: '#611D1C' }, + secondary: { + inverse: { value: '#000000' }, }, }, }, }, }; -var formatter = formats['json/nested'].bind(file); +const formatter = formats['json/nested'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', function() { describe('json/nested', function() { @@ -50,8 +51,12 @@ describe('formats', function() { }); it('should be a valid JSON file', function() { - fs.writeFileSync('./__tests__/__output/json-nested.json', formatter(dictionary)); - var test = require('../__output/json-nested.json'); + fs.writeFileSync('./__tests__/__output/json-nested.json', formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file)); + const test = require('../__output/json-nested.json'); expect(test.color.base.red.primary) .toEqual(dictionary.properties.color.base.red.primary.value); expect(test.color.base.red.secondary.inverse) @@ -62,8 +67,12 @@ describe('formats', function() { // non-token data is anything in the dictionary object that is not a token object // i.e. anything in the rest of the object that doesn't have a 'value' - fs.writeFileSync('./__tests__/__output/json-nested.json', formatter(dictionary)); - var test = require('../__output/json-nested.json'); + fs.writeFileSync('./__tests__/__output/json-nested.json', formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file)); + const test = require('../__output/json-nested.json'); expect(test.color.base.comment) .toEqual(dictionary.properties.color.base.comment); expect(test.color.base.metadata) diff --git a/__tests__/formats/lessIcons.test.js b/__tests__/formats/lessIcons.test.js index 545b008b9..ab920b830 100644 --- a/__tests__/formats/lessIcons.test.js +++ b/__tests__/formats/lessIcons.test.js @@ -11,52 +11,58 @@ * and limitations under the License. */ -var formats = require('../../lib/common/formats'); -var less = require('less'); +const formats = require('../../lib/common/formats'); +const less = require('less'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { "destination": "__output/", "format": "less/icons", "name": "foo" }; -var propertyName = "content-icon-email"; -var propertyValue = "'\\E001'"; -var itemClass = "3d_rotation"; - -var dictionary = { - "allProperties": [{ - "name": propertyName, - "value": propertyValue, - "original": { - "value": propertyValue - }, - "attributes": { - "category": "content", - "type": "icon", - "item": itemClass +const propertyName = "content-icon-email"; +const propertyValue = "'\\E001'"; +const itemClass = "3d_rotation"; + +const properties = { + content: { + icon: { + email: { + "name": propertyName, + "value": propertyValue, + "original": { + "value": propertyValue + }, + "attributes": { + "category": "content", + "type": "icon", + "item": itemClass + }, + path: ['content','icon','email'] + } } - }] + } }; -var config = { +const platform = { prefix: 'sd' // Style-Dictionary Prefix }; -var formatter = formats['less/icons'].bind(file); +const formatter = formats['less/icons'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', () => { describe('less/icons', () => { - it('should have a valid less syntax', done => { - less.render(formatter(dictionary, config)) - .then(function(output) { - expect(output).toBeDefined(); - done(); - }) - .catch(function(err) { - done(new Error(err)) - }); + it('should have a valid less syntax', () => { + expect.assertions(1); + return expect(less.render(formatter(createFormatArgs({ + dictionary, + file, + platform + }), platform, file))).resolves.toBeDefined(); }); }); diff --git a/__tests__/formats/lessVariables.test.js b/__tests__/formats/lessVariables.test.js index 4b229b033..ab652672d 100644 --- a/__tests__/formats/lessVariables.test.js +++ b/__tests__/formats/lessVariables.test.js @@ -13,6 +13,8 @@ var formats = require('../../lib/common/formats'); var less = require('less'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); var file = { "destination": "__output/", @@ -20,45 +22,50 @@ var file = { "name": "foo" }; -var propertyName = "color-base-red-400"; -var propertyValue = "#EF5350"; +const propertyName = "color-base-red-400"; +const propertyValue = "#EF5350"; -var dictionary = { - "allProperties": [{ - "name": propertyName, - "value": propertyValue, - "original": { - "value": propertyValue - }, - "attributes": { - "category": "color", - "type": "base", - "item": "red", - "subitem": "400" - }, - "path": [ - "color", - "base", - "red", - "400" - ] - }] +const properties = { + color: { + base: { + red: { + 400: { + "name": propertyName, + "value": propertyValue, + "original": { + "value": propertyValue + }, + "attributes": { + "category": "color", + "type": "base", + "item": "red", + "subitem": "400" + }, + "path": [ + "color", + "base", + "red", + "400" + ] + } + } + } + } }; -var formatter = formats['less/variables'].bind(file); +const formatter = formats['less/variables'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', () => { describe('less/variables', () => { - it('should have a valid less syntax', done => { - less.render(formatter(dictionary)) - .then(function(output) { - expect(output).toBeDefined(); - done(); - }) - .catch(function(err) { - done(new Error(err)) - }); + it('should have a valid less syntax', () => { + expect.assertions(1); + return expect(less.render(formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file))).resolves.toBeDefined(); }); }); diff --git a/__tests__/formats/scssIcons.test.js b/__tests__/formats/scssIcons.test.js index ec95d3dc3..84a87b92c 100644 --- a/__tests__/formats/scssIcons.test.js +++ b/__tests__/formats/scssIcons.test.js @@ -11,53 +11,60 @@ * and limitations under the License. */ -var formats = require('../../lib/common/formats'); -var scss = require('node-sass'); +const formats = require('../../lib/common/formats'); +const scss = require('node-sass'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); -var file = { +const file = { "destination": "__output/", "format": "scss/icons", "name": "foo" }; -var propertyName = "content-icon-email"; -var propertyValue = "'\\E001'"; -var itemClass = "3d_rotation"; +const propertyName = "content-icon-email"; +const propertyValue = "'\\E001'"; +const itemClass = "3d_rotation"; -var dictionary = { - "allProperties": [{ - "name": propertyName, - "value": propertyValue, - "original": { - "value": propertyValue - }, - "attributes": { - "category": "content", - "type": "icon", - "item": itemClass +const properties = { + content: { + icon: { + email: { + "name": propertyName, + "value": propertyValue, + "original": { + "value": propertyValue + }, + "attributes": { + "category": "content", + "type": "icon", + "item": itemClass + }, + path: ['content','icon','email'] + } } - }] + } }; -var config = { +const platform = { prefix: 'sd' // Style-Dictionary Prefix }; -var formatter = formats['scss/icons'].bind(file); +const formatter = formats['scss/icons'].bind(file); +const dictionary = createDictionary({ properties }); describe('formats', () => { describe('scss/icons', () => { - it('should have a valid scss syntax', done => { - scss.render({ - data: formatter(dictionary, config), - }, function(err, result) { - if(err) { - return done(new Error(err)); - } - expect(result.css).toBeDefined(); - return done(); + it('should have a valid scss syntax', () => { + const result = scss.renderSync({ + data: formatter(createFormatArgs({ + dictionary, + file, + platform + }), platform, file), }); + expect(result.css).toBeDefined(); }); }); diff --git a/__tests__/formats/scssMaps.test.js b/__tests__/formats/scssMaps.test.js index a7f2e9e64..c4d9c2d1f 100644 --- a/__tests__/formats/scssMaps.test.js +++ b/__tests__/formats/scssMaps.test.js @@ -13,163 +13,72 @@ var formats = require('../../lib/common/formats'); var scss = require('node-sass'); -var _ = require('lodash'); +var _ = require('../../lib/utils/es6_'); +var createDictionary = require('../../lib/utils/createDictionary'); +var createFormatArgs = require('../../lib/utils/createFormatArgs'); -var dictionary = { - "properties": { - "size": { - "font": { - "small": { - "value": "12rem", - "original": { - "value": "12px" - }, - "name": "size-font-small", - "attributes": { - "category": "size", - "type": "font", - "item": "small" - }, - "path": [ - "size", - "font", - "small" - ] +var properties = { + "size": { + "font": { + "small": { + "value": "12rem", + "original": { + "value": "12px" }, - "large": { - "value": "18rem", - "original": { - "value": "18px" - }, - "name": "size-font-large", - "attributes": { - "category": "size", - "type": "font", - "item": "large" - }, - "path": [ - "size", - "font", - "large" - ] - } - } - }, - "color": { - "base": { - "red": { - "value": "#ff0000", - "comment": "comment", - "original": { - "value": "#FF0000", - "comment": "comment" - }, - "name": "color-base-red", - "attributes": { - "category": "color", - "type": "base", - "item": "red" - }, - "path": [ - "color", - "base", - "red" - ] - } + "name": "size-font-small", + "attributes": { + "category": "size", + "type": "font", + "item": "small" + }, + "path": [ + "size", + "font", + "small" + ] }, - "white": { - "value": "#ffffff", + "large": { + "value": "18rem", "original": { - "value": "#ffffff" + "value": "18px" }, - "name": "color-white", + "name": "size-font-large", "attributes": { - "category": "color", - "type": "white" + "category": "size", + "type": "font", + "item": "large" }, "path": [ - "color", - "white" + "size", + "font", + "large" ] } - }, - "asset": { - "icon": { - "book": { - "value": "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItYm9vayI+PHBhdGggZD0iTTQgMTkuNUEyLjUgMi41IDAgMCAxIDYuNSAxN0gyMCI+PC9wYXRoPjxwYXRoIGQ9Ik02LjUgMkgyMHYyMEg2LjVBMi41IDIuNSAwIDAgMSA0IDE5LjV2LTE1QTIuNSAyLjUgMCAwIDEgNi41IDJ6Ij48L3BhdGg+PC9zdmc+", - "original": { - "value": "./test/__assets/icons/book.svg" - }, - "name": "asset-icon-book", - "attributes": { - "category": "asset", - "type": "icon", - "item": "book" - }, - "path": [ - "asset", - "icon", - "book" - ] - } - } } }, - "allProperties": [ - { - "value": "12rem", - "original": { - "value": "12px" - }, - "name": "size-font-small", - "attributes": { - "category": "size", - "type": "font", - "item": "small" - }, - "path": [ - "size", - "font", - "small" - ] - }, - { - "value": "18rem", - "original": { - "value": "18px" - }, - "name": "size-font-large", - "attributes": { - "category": "size", - "type": "font", - "item": "large" - }, - "path": [ - "size", - "font", - "large" - ] - }, - { - "value": "#ff0000", - "comment": "comment", - "original": { - "value": "#FF0000", - "comment": "comment" - }, - "name": "color-base-red", - "attributes": { - "category": "color", - "type": "base", - "item": "red" - }, - "path": [ - "color", - "base", - "red" - ] + "color": { + "base": { + "red": { + "value": "#ff0000", + "comment": "comment", + "original": { + "value": "#FF0000", + "comment": "comment" + }, + "name": "color-base-red", + "attributes": { + "category": "color", + "type": "base", + "item": "red" + }, + "path": [ + "color", + "base", + "red" + ] + } }, - { + "white": { "value": "#ffffff", "original": { "value": "#ffffff" @@ -183,25 +92,29 @@ var dictionary = { "color", "white" ] - }, - { - "value": "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItYm9vayI+PHBhdGggZD0iTTQgMTkuNUEyLjUgMi41IDAgMCAxIDYuNSAxN0gyMCI+PC9wYXRoPjxwYXRoIGQ9Ik02LjUgMkgyMHYyMEg2LjVBMi41IDIuNSAwIDAgMSA0IDE5LjV2LTE1QTIuNSAyLjUgMCAwIDEgNi41IDJ6Ij48L3BhdGg+PC9zdmc+", - "original": { - "value": "./test/__assets/icons/book.svg" - }, - "name": "asset-icon-book", - "attributes": { - "category": "asset", - "type": "icon", - "item": "book" - }, - "path": [ - "asset", - "icon", - "book" - ] } - ] + }, + "asset": { + "icon": { + "book": { + "value": "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItYm9vayI+PHBhdGggZD0iTTQgMTkuNUEyLjUgMi41IDAgMCAxIDYuNSAxN0gyMCI+PC9wYXRoPjxwYXRoIGQ9Ik02LjUgMkgyMHYyMEg2LjVBMi41IDIuNSAwIDAgMSA0IDE5LjV2LTE1QTIuNSAyLjUgMCAwIDEgNi41IDJ6Ij48L3BhdGg+PC9zdmc+", + "original": { + "value": "./test/__assets/icons/book.svg" + }, + "name": "asset-icon-book", + "attributes": { + "category": "asset", + "type": "icon", + "item": "book" + }, + "path": [ + "asset", + "icon", + "book" + ] + } + } + } }; describe('formats', () => { @@ -214,31 +127,23 @@ describe('formats', () => { "format": key }; - // mock the Date.now() call to a fixed value - const constantDate = new Date('2000-01-01'); - const globalDate = global.Date; - global.Date = function() { return constantDate }; - var formatter = formats[key].bind(file); - var output = formatter(dictionary, file); - - // reset the global Date object (or node-sass will complain!) - global.Date = globalDate; + const dictionary = createDictionary({ properties }); + var output = formatter(createFormatArgs({ + dictionary, + file, + platform: {}, + }), {}, file); it('should return ' + key + ' as a string', () => { expect(typeof output).toBe('string'); }); - it('should have a valid scss syntax', done => { - scss.render({ + it('should have a valid scss syntax', () => { + const result = scss.renderSync({ data: output, - }, function(err, result) { - if(err) { - return done(new Error(err)); - } - expect(result.css).toBeDefined(); - return done(); }); + expect(result.css).toBeDefined(); }); it(key + ' snapshot', () => { diff --git a/__tests__/formats/scssVariables.test.js b/__tests__/formats/scssVariables.test.js index 3cf3dd7ec..3e501b680 100644 --- a/__tests__/formats/scssVariables.test.js +++ b/__tests__/formats/scssVariables.test.js @@ -13,6 +13,9 @@ var formats = require('../../lib/common/formats'); var scss = require('node-sass'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); +var _ = require('../../lib/utils/es6_'); var file = { "destination": "__output/", @@ -20,47 +23,73 @@ var file = { "name": "foo" }; -var propertyName = "color-base-red-400"; -var propertyValue = "#EF5350"; +const propertyName = "color-base-red-400"; +const propertyValue = "#EF5350"; -var dictionary = { - "allProperties": [{ - "name": propertyName, - "value": propertyValue, - "original": { - "value": propertyValue - }, - "attributes": { - "category": "color", - "type": "base", - "item": "red", - "subitem": "400" - }, - "path": [ - "color", - "base", - "red", - "400" - ] - }] +const properties = { + color: { + base: { + red: { + 400: { + "name": propertyName, + "value": propertyValue, + "original": { + "value": propertyValue + }, + "attributes": { + "category": "color", + "type": "base", + "item": "red", + "subitem": "400" + }, + "path": [ + "color", + "base", + "red", + "400" + ] + } + } + } + } }; var formatter = formats['scss/variables'].bind(file); +const dictionary = createDictionary({properties}); describe('formats', () => { describe('scss/variables', () => { - it('should have a valid scss syntax', done => { - scss.render({ - data: formatter(dictionary), - }, function(err, result) { - if(err) { - return done(new Error(err)); - } - expect(result.css).toBeDefined(); - return done(); + it('should have a valid scss syntax', () => { + const result = scss.renderSync({ + data: formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file), }); + expect(result.css).toBeDefined(); }); + it('should optionally use !default', () => { + var themeableDictionary = _.cloneDeep(dictionary), + formattedScss = formatter(createFormatArgs({ + dictionary, + file, + platform: {} + }), {}, file), + themeableScss = ""; + + expect(formattedScss).not.toMatch("!default"); + + themeableDictionary.allTokens[0].themeable = true; + themeableScss = formatter(createFormatArgs({ + dictionary: themeableDictionary, + file, + platform: {} + }), {}, file); + + expect(themeableScss).toMatch("#EF5350 !default;"); + }); }); }); diff --git a/__tests__/formats/stylusVariable.test.js b/__tests__/formats/stylusVariable.test.js new file mode 100644 index 000000000..8d8295e6e --- /dev/null +++ b/__tests__/formats/stylusVariable.test.js @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +var formats = require('../../lib/common/formats'); +var stylus = require('stylus'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); + +var file = { + "destination": "__output/", + "format": "stylus/variables", + "name": "foo" +}; + +const propertyName = "color-base-red-400"; +const propertyValue = "#EF5350"; + +const properties = { + color: { + base: { + red: { + 400: { + "name": propertyName, + "value": propertyValue, + "original": { + "value": propertyValue + }, + "attributes": { + "category": "color", + "type": "base", + "item": "red", + "subitem": "400" + }, + "path": [ + "color", + "base", + "red", + "400" + ] + } + } + } + } +}; + +const formatter = formats['stylus/variables'].bind(file); +const dictionary = createDictionary({ properties }); + +describe('formats', () => { + describe('stylus/variables', () => { + + it('should have a valid stylus syntax', () => { + const stylusArguments = createFormatArgs({ + dictionary, + file, + platform: {} + }); + stylus.render(formatter(stylusArguments, {}, file), + function (err, css) { + if (err) { + throw new Error(err); + } + expect(css).toBeDefined(); + }); + }); + + }); +}); diff --git a/__tests__/formats/typeScriptEs6Declarations.test.js b/__tests__/formats/typeScriptEs6Declarations.test.js new file mode 100644 index 000000000..62affb73e --- /dev/null +++ b/__tests__/formats/typeScriptEs6Declarations.test.js @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +const formats = require('../../lib/common/formats'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); + +const file = { + "destination": "__output/", + "format": "typescript/es6-declarations", + "filter": { + "attributes": { + "category": "color" + } + } +}; + +const properties = { + "color": { + "red": {"value": "#FF0000"} + } +}; + +const formatter = formats['typescript/es6-declarations'].bind(file); + +describe('formats', () => { + describe('typescript/es6-declarations', () => { + it('should be a valid TS file', () => { + const dictionary = createDictionary({ properties }); + const output = formatter(createFormatArgs({ + dictionary, + file, + platform: {}, + }), {}, file); + + // get all lines that begin with export + const lines = output + .split('\n') + .filter(l => l.indexOf('export') >= 0); + + // assert that any lines have a string type definition + lines.forEach(l => { + expect(l.match(/^export.* : string;$/g).length).toEqual(1); + }); + }); + }); + +}); diff --git a/__tests__/formats/typeScriptModuleDeclarations.test.js b/__tests__/formats/typeScriptModuleDeclarations.test.js new file mode 100644 index 000000000..73ac8fb25 --- /dev/null +++ b/__tests__/formats/typeScriptModuleDeclarations.test.js @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +const formats = require('../../lib/common/formats'); +const createDictionary = require('../../lib/utils/createDictionary'); +const createFormatArgs = require('../../lib/utils/createFormatArgs'); + +const file = { + "destination": "__output/", + "format": "typescript/module-declarations", + "filter": { + "attributes": { + "category": "color" + } + } +}; + +const properties = { + "color": { + "red": {"value": "#FF0000"} + } +}; + + +var formatter = formats['typescript/module-declarations'].bind(file); + +describe('formats', () => { + describe('typescript/module-declarations', () => { + it('should be a valid TS file', () => { + const dictionary = createDictionary({ properties }); + const output = formatter(createFormatArgs({ + dictionary, + file, + platform: {}, + }), {}, file); + + // get all lines that have DesignToken + const lines = output + .split('\n') + .filter(l => l.indexOf(': DesignToken') >= 0); + + // assert that any lines have a DesignToken type definition + lines.forEach(l => { + expect(l.match(/^.*: DesignToken$/g).length).toEqual(1); + }); + }); + }); +}); diff --git a/__tests__/register/fileHeader.test.js b/__tests__/register/fileHeader.test.js new file mode 100644 index 000000000..219359879 --- /dev/null +++ b/__tests__/register/fileHeader.test.js @@ -0,0 +1,99 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +var StyleDictionary = require('../../index'); +var StyleDictionaryExtended = StyleDictionary.extend({}); + +describe('register', () => { + describe('fileHeader', () => { + + it('should error if name is not a string', () => { + expect( + StyleDictionaryExtended.registerFileHeader.bind(null, { + fileHeader: function () {} + }) + ).toThrow('name must be a string'); + + expect( + StyleDictionaryExtended.registerFileHeader.bind(null, { + name: 1, + fileHeader: function () {} + }) + ).toThrow('name must be a string'); + + expect( + StyleDictionaryExtended.registerFileHeader.bind(null, { + name: [], + fileHeader: function () {} + }) + ).toThrow('name must be a string'); + + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: {}, + matcher: function () {} + }) + ).toThrow('name must be a string'); + }); + + it('should error if fileHeader is not a function', () => { + expect( + StyleDictionaryExtended.registerFileHeader.bind(null, { + name: 'myCustomHeader' + }) + ).toThrow('fileHeader must be a function'); + + expect( + StyleDictionaryExtended.registerFileHeader.bind(null, { + name: 'myCustomHeader', + fileHeader: 1 + }) + ).toThrow('fileHeader must be a function'); + + expect( + StyleDictionaryExtended.registerFileHeader.bind(null, { + name: 'myCustomHeader', + fileHeader: 'name' + }) + ).toThrow('fileHeader must be a function'); + + expect( + StyleDictionaryExtended.registerFileHeader.bind(null, { + name: 'myCustomHeader', + fileHeader: [] + }) + ).toThrow('fileHeader must be a function'); + + expect( + StyleDictionaryExtended.registerFileHeader.bind(null, { + name: 'myCustomHeader', + fileHeader: {} + }) + ).toThrow('fileHeader must be a function'); + }); + + it('should work if name and matcher are good', () => { + StyleDictionaryExtended.registerFileHeader({ + name: 'myCustomHeader', + fileHeader: function() {} + }); + expect(typeof StyleDictionaryExtended.fileHeader['myCustomHeader']).toBe('function'); + }); + + it('should properly pass the registered fileHeader to instances', () => { + var SDE2 = StyleDictionaryExtended.extend({}); + expect(typeof SDE2.fileHeader['myCustomHeader']).toBe('function'); + }); + + }); +}); diff --git a/__tests__/register/filter.test.js b/__tests__/register/filter.test.js new file mode 100644 index 000000000..49487aa61 --- /dev/null +++ b/__tests__/register/filter.test.js @@ -0,0 +1,99 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +var StyleDictionary = require('../../index'); +var StyleDictionaryExtended = StyleDictionary.extend({}); + +describe('register', () => { + describe('filter', () => { + + it('should error if name is not a string', () => { + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + matcher: function () {} + }) + ).toThrow('name must be a string'); + + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: 1, + matcher: function () {} + }) + ).toThrow('name must be a string'); + + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: [], + matcher: function () {} + }) + ).toThrow('name must be a string'); + + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: {}, + matcher: function () {} + }) + ).toThrow('name must be a string'); + }); + + it('should error if matcher is not a function', () => { + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: 'test' + }) + ).toThrow('matcher must be a function'); + + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: 'test', + matcher: 1 + }) + ).toThrow('matcher must be a function'); + + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: 'test', + matcher: 'name' + }) + ).toThrow('matcher must be a function'); + + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: 'test', + matcher: [] + }) + ).toThrow('matcher must be a function'); + + expect( + StyleDictionaryExtended.registerFilter.bind(null, { + name: 'test', + matcher: {} + }) + ).toThrow('matcher must be a function'); + }); + + it('should work if name and matcher are good', () => { + StyleDictionaryExtended.registerFilter({ + name: 'scss', + matcher: function() {} + }); + expect(typeof StyleDictionaryExtended.filter['scss']).toBe('function'); + }); + + it('should properly pass the registered filter to instances', () => { + var SDE2 = StyleDictionaryExtended.extend({}); + expect(typeof SDE2.filter['scss']).toBe('function'); + }); + + }); +}); diff --git a/__tests__/register/format.test.js b/__tests__/register/format.test.js index 97acf8197..a6cebdbaf 100644 --- a/__tests__/register/format.test.js +++ b/__tests__/register/format.test.js @@ -18,68 +18,70 @@ describe('register', () => { describe('format', () => { it('should error if name is not a string', () => { + const errorMessage = `Can't register format; format.name must be a string` expect( StyleDictionaryExtended.registerFormat.bind(null, { formatter: function() {} }) - ).toThrow('Can\'t register format; format.name must be a string'); + ).toThrow(errorMessage); expect( StyleDictionaryExtended.registerFormat.bind(null, { name: 1, formatter: function() {} }) - ).toThrow('Can\'t register format; format.name must be a string'); + ).toThrow(errorMessage); expect( StyleDictionaryExtended.registerFormat.bind(null, { name: [], formatter: function() {} }) - ); + ).toThrow(errorMessage); expect( StyleDictionaryExtended.registerFormat.bind(null, { name: {}, formatter: function() {} }) - ).toThrow('Can\'t register format; format.name must be a string'); + ).toThrow(errorMessage); }); it('should error if format is not a function', () => { + const errorMessage = `Can't register format; format.formatter must be a function` expect( StyleDictionaryExtended.registerFormat.bind(null, { name: 'test' }) - ).toThrow('Can\'t register format; format.formatter must be a function'); + ).toThrow(errorMessage); expect( StyleDictionaryExtended.registerFormat.bind(null, { name: 'test', formatter: 1 }) - ).toThrow('Can\'t register format; format.formatter must be a function'); + ).toThrow(errorMessage); expect( StyleDictionaryExtended.registerFormat.bind(null, { name: 'test', formatter: 'name' }) - ).toThrow('Can\'t register format; format.formatter must be a function'); + ).toThrow(errorMessage); expect( StyleDictionaryExtended.registerFormat.bind(null, { name: 'test', formatter: [] }) - ).toThrow('Can\'t register format; format.formatter must be a function'); + ).toThrow(errorMessage); expect( StyleDictionaryExtended.registerFormat.bind(null, { name: 'test', formatter: {} }) - ).toThrow('Can\'t register format; format.formatter must be a function'); + ).toThrow(errorMessage); }); it('should work if name and format are good', () => { diff --git a/__tests__/register/parser.test.js b/__tests__/register/parser.test.js new file mode 100644 index 000000000..b38475a9d --- /dev/null +++ b/__tests__/register/parser.test.js @@ -0,0 +1,99 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +var StyleDictionary = require('../../index'); +var StyleDictionaryExtended = StyleDictionary.extend({}); + +describe('register', () => { + describe('parser', () => { + + it('should error if pattern is not a regex', () => { + expect( + StyleDictionaryExtended.registerParser.bind(null, { + parse: function () {} + }) + ).toThrow('pattern must be a regular expression'); + + expect( + StyleDictionaryExtended.registerParser.bind(null, { + pattern: 1, + parse: function () {} + }) + ).toThrow('pattern must be a regular expression'); + + expect( + StyleDictionaryExtended.registerParser.bind(null, { + pattern: [], + parse: function () {} + }) + ).toThrow('pattern must be a regular expression'); + + expect( + StyleDictionaryExtended.registerParser.bind(null, { + pattern: {}, + parse: function () {} + }) + ).toThrow('pattern must be a regular expression'); + }); + + it('should error if parser is not a function', () => { + expect( + StyleDictionaryExtended.registerParser.bind(null, { + pattern: /$.json/ + }) + ).toThrow('parse must be a function'); + + expect( + StyleDictionaryExtended.registerParser.bind(null, { + pattern: /$.json/, + parse: 1 + }) + ).toThrow('parse must be a function'); + + expect( + StyleDictionaryExtended.registerParser.bind(null, { + pattern: /$.json/, + parse: 'name' + }) + ).toThrow('parse must be a function'); + + expect( + StyleDictionaryExtended.registerParser.bind(null, { + pattern: /$.json/, + parse: [] + }) + ).toThrow('parse must be a function'); + + expect( + StyleDictionaryExtended.registerParser.bind(null, { + pattern: /$.json/, + parse: {} + }) + ).toThrow('parse must be a function'); + }); + + it('should work if pattern and parser are good', () => { + StyleDictionaryExtended.registerParser({ + pattern: /$.json/, + parse: function() {} + }); + expect(typeof StyleDictionaryExtended.parsers[0].parse).toBe('function'); + }); + + it('should properly pass the registered filter to instances', () => { + var SDE2 = StyleDictionaryExtended.extend({}); + expect(typeof SDE2.parsers[0].parse).toBe('function'); + }); + + }); +}); diff --git a/__tests__/transform/object.test.js b/__tests__/transform/object.test.js index af70b60b5..8618cd429 100644 --- a/__tests__/transform/object.test.js +++ b/__tests__/transform/object.test.js @@ -33,6 +33,14 @@ const options = { transformer: function() { return "transformer result"; } + }, { + type: 'value', + matcher: function(prop) { + return prop.path[0] === 'spacing'; + }, + transformer: function(val) { + return val + 'px'; + } } ] }; @@ -85,7 +93,31 @@ describe('transform', () => { const actual = transformObject(objectToTransform, options); expect(actual).toEqual(expected); - }) + }); + + it('fills the transformationContext with transformed and deferred transforms', () => { + const transformedPropRefs = []; + const deferredPropValueTransforms = []; + const transformationContext = { + transformedPropRefs, + deferredPropValueTransforms + }; + + const objectToTransform = { + "spacing": { + "base": { + "value": "16" + }, + "medium": { + "value": "{spacing.base.value}" + } + } + }; + transformObject(objectToTransform, options, transformationContext); + + expect(transformedPropRefs).toEqual(['spacing.base']); + expect(deferredPropValueTransforms).toEqual(['spacing.medium']); + }) }); }); diff --git a/__tests__/transform/propertySetup.test.js b/__tests__/transform/propertySetup.test.js index aabc43abe..837af06b0 100644 --- a/__tests__/transform/propertySetup.test.js +++ b/__tests__/transform/propertySetup.test.js @@ -42,7 +42,6 @@ describe('transform', () => { ["color","base"] ); expect(typeof test).toBe('object'); - expect(test); expect(test).toHaveProperty('value'); expect(test).toHaveProperty('original'); expect(test).toHaveProperty('attributes'); @@ -89,5 +88,15 @@ describe('transform', () => { expect(test).toHaveProperty('name', 'white'); }); + it('should handle objects', () => { + const test = propertySetup({ + value: { + h: 20, s: 50, l: 50 + } + }, 'red', ['color','red']); + expect(test).toHaveProperty('value.h', 20); + expect(test).toHaveProperty('original.value.h', 20); + }) + }); }); diff --git a/__tests__/utils/combineJSON.test.js b/__tests__/utils/combineJSON.test.js index f143e2f22..44532b259 100644 --- a/__tests__/utils/combineJSON.test.js +++ b/__tests__/utils/combineJSON.test.js @@ -13,6 +13,7 @@ var combineJSON = require('../../lib/utils/combineJSON'); var path = require('path'); +var yaml = require('yaml'); describe('utils', () => { describe('combineJSON', () => { @@ -64,7 +65,7 @@ describe('utils', () => { expect(opts.target[opts.key]).toBe(1); expect(opts.copy[opts.key]).toBe(2); throw new Error('test'); - }) + }, true) ).toThrow(/test/); }); @@ -73,5 +74,35 @@ describe('utils', () => { expect(test).toHaveProperty('json5A', 5); expect(test.d).toHaveProperty('json5e', 1); }); + + describe('custom parsers', () => { + it('should support yaml.parse', () => { + const parsers = [{ + pattern: /\.yaml$/, + // yaml.parse function matches the intended function signature + parse: ({contents}) => yaml.parse(contents) + }]; + const output = combineJSON([`__tests__/__json_files/yaml.yaml`], false, null, false, parsers); + expect(output).toHaveProperty('foo', 'bar'); + expect(output).toHaveProperty('bar', '{foo}'); + }); + + it('should multiple parsers on the same file', () => { + const testOutput = { test: 'test' }; + const parsers = [{ + pattern: /.json$/, + parse: () => { + return { test: 'foo' } + } + },{ + pattern: /.json$/, + parse: () => { + return testOutput + } + }]; + const output = combineJSON([`__tests__/__json_files/simple.json`], false, null, false, parsers); + expect(output).toHaveProperty('test', 'test'); + }); + }); }); }); diff --git a/__tests__/utils/convertToBase64.test.js b/__tests__/utils/convertToBase64.test.js index 13d5ad122..c79005f64 100644 --- a/__tests__/utils/convertToBase64.test.js +++ b/__tests__/utils/convertToBase64.test.js @@ -36,5 +36,10 @@ describe('utils', () => { it('should return a string', () => { expect(typeof convertToBase64('__tests__/__configs/test.json')).toBe('string'); }); + + it('should be a valid base64 string', () => { + expect(convertToBase64('__tests__/__json_files/simple.json')) + .toEqual('ewogICJmb28iOiAiYmFyIiwKICAiYmFyIjogIntmb299Igp9'); + }); }); }); diff --git a/__tests__/utils/deepExtend.test.js b/__tests__/utils/deepExtend.test.js index d2bde878e..16eb847d7 100644 --- a/__tests__/utils/deepExtend.test.js +++ b/__tests__/utils/deepExtend.test.js @@ -29,7 +29,7 @@ describe('utils', () => { expect(test2).toHaveProperty('foo', 'blah'); }); - it('should override nested properties', () => { + it('overrides nested properties', () => { var test = deepExtend([{foo: {foo:'bar'}}, {foo: {foo:'baz'}}]); expect(test).toHaveProperty('foo.foo', 'baz'); @@ -37,7 +37,7 @@ describe('utils', () => { expect(test2).toHaveProperty('foo.foo', 'blah'); }); - it('should override nested properties', () => { + it('properly merges nested properties', () => { var test = deepExtend([{foo: {bar:'bar'}}, {foo: {baz:'baz'}}]); expect(test).toHaveProperty('foo.baz', 'baz'); expect(test).toHaveProperty('foo.bar', 'bar'); diff --git a/__tests__/utils/flattenProperties.test.js b/__tests__/utils/flattenProperties.test.js index a81ce0af6..cd42bf23a 100644 --- a/__tests__/utils/flattenProperties.test.js +++ b/__tests__/utils/flattenProperties.test.js @@ -12,7 +12,9 @@ */ var flattenProperties = require('../../lib/utils/flattenProperties'); -var _ = require('lodash'); +const sortBy = (key) => { + return (a, b) => (a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0); +}; describe('utils', () => { describe('flattenProperties', () => { @@ -43,9 +45,9 @@ describe('utils', () => { properties.white ]; - var sortedExpectedRet = _.sortBy(expected_ret, ['value']); + var sortedExpectedRet = expected_ret.sort(sortBy('value')); var ret = flattenProperties(properties); - var sortedRet = _.sortBy(ret, ['value']); + var sortedRet = ret.sort(sortBy('value')); expect(sortedRet).toEqual(sortedExpectedRet); }); @@ -66,9 +68,9 @@ describe('utils', () => { properties.color.white ]; - var sortedExpectedRet = _.sortBy(expected_ret, ['value']); + var sortedExpectedRet = expected_ret.sort(sortBy('value')); var ret = flattenProperties(properties); - var sortedRet = _.sortBy(ret, ['value']); + var sortedRet = ret.sort(sortBy('value')); expect(sortedRet).toEqual(sortedExpectedRet); }); }); diff --git a/__tests__/utils/reference/getReferences.test.js b/__tests__/utils/reference/getReferences.test.js new file mode 100644 index 000000000..900f11063 --- /dev/null +++ b/__tests__/utils/reference/getReferences.test.js @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +// `.getReferences` is bound to a dictionary object, so to test it we will +// create a dictionary object and then call `.getReferences` on it. +const createDictionary = require('../../../lib/utils/createDictionary'); + +const properties = { + color: { + red: { value: "#f00" }, + danger: { value: "{color.red.value}" } + }, + size: { + border: { value: "2px" } + }, + border: { + primary: { + // getReferences should work on objects like this: + value: { + color: "{color.red.value}", + width: "{size.border.value}", + style: "solid" + } + }, + secondary: { + // getReferences should work on interpolated values like this: + value: "{size.border.value} solid {color.red.value}" + } + } +} + +const dictionary = createDictionary({ properties }); + +describe('utils', () => { + describe('reference', () => { + describe('getReferences()', () => { + it(`should return an empty array if the value has no references`, () => { + expect(dictionary.getReferences(properties.color.red.value)).toEqual([]); + }); + + it(`should work with a single reference`, () => { + expect(dictionary.getReferences(properties.color.danger.value)).toEqual( + expect.arrayContaining([ + {value: "#f00"} + ]) + ); + }); + + it(`should work with object values`, () => { + expect(dictionary.getReferences(properties.border.primary.value)).toEqual( + expect.arrayContaining([ + {value: "2px"}, + {value: "#f00"} + ]) + ); + }); + + it(`should work with interpolated values`, () => { + expect(dictionary.getReferences(properties.border.secondary.value)).toEqual( + expect.arrayContaining([ + {value: "2px"}, + {value: "#f00"} + ]) + ); + }); + }); + }); +}); diff --git a/__tests__/utils/reference/resolveReference.test.js b/__tests__/utils/reference/resolveReference.test.js new file mode 100644 index 000000000..f3b2e4290 --- /dev/null +++ b/__tests__/utils/reference/resolveReference.test.js @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const resolveReference = require('../../../lib/utils/references/resolveReference'); + +const dictionary = { + color: { + palette: { + neutral: { + 0: { value: "#ffffff" }, + 5: { value: "#f2f3f4" } + } + }, + background: { + primary: { value: "{color.palette.neutral.0.value}" } + } + }, + arr: [ + 'one', + 'two' + ] +} + +describe('resolveReference()', () => { + it(`returns undefined for non-strings`, () => { + expect(resolveReference(42, dictionary)).toBe(undefined); + }); + + it(`returns undefined if it does not find the path in the object`, () => { + expect(resolveReference(['color','foo'], dictionary)).toBe(undefined); + expect(resolveReference(['color','foo','bar'], dictionary)).toBe(undefined); + }); + + it(`returns the part of the object if referenced path exists`, () => { + expect( + resolveReference(['color','palette','neutral','0','value'], dictionary) + ).toEqual(dictionary.color.palette.neutral['0'].value); + expect( + resolveReference(['color'], dictionary) + ).toEqual(dictionary.color); + }); + + it(`works with arrays`, () => { + expect( + resolveReference(['arr'], dictionary) + ).toEqual(dictionary.arr); + }); + + it(`works with array indices`, () => { + expect( + resolveReference(['arr','0'], dictionary) + ).toEqual(dictionary.arr[0]); + }); +}); diff --git a/__tests__/utils/reference/usesReference.test.js b/__tests__/utils/reference/usesReference.test.js new file mode 100644 index 000000000..d64af1af0 --- /dev/null +++ b/__tests__/utils/reference/usesReference.test.js @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +const usesReference = require('../../../lib/utils/references/usesReference'); + +describe('usesReference()', () => { + it(`returns false for non-strings`, () => { + expect(usesReference(42)).toBe(false); + }); + + it(`returns false if value uses no reference`, () => { + expect(usesReference('foo.bar')).toBe(false); + }); + + it(`returns true if value is a reference`, () => { + expect(usesReference('{foo.bar}')).toBe(true); + }); + + it(`should return true if value uses a reference`, () => { + expect(usesReference('baz {foo.bar}')).toBe(true); + }); + + it(`returns true if an object uses a reference`, () => { + expect(usesReference({foo: '{bar}'})).toBe(true); + }); + + it(`returns false if an object doesn't have a reference`, () => { + expect(usesReference({foo: 'bar'})).toBe(false); + }); + + it(`returns true if a nested object has a reference`, () => { + expect(usesReference({foo: {bar: '{bar}'}})).toBe(true); + }); + + it(`returns true if an array uses a reference`, () => { + expect(usesReference(["foo", "{bar}"])).toBe(true); + }); + + it(`returns false if an array doesn't use a reference`, () => { + expect(usesReference(["foo", "bar"])).toBe(false); + }); + + describe(`with custom options`, () => { + test(`returns true if value is reference`, () => { + const customOpts = { + opening_character: '(', + closing_character: ')', + separator: '|' + }; + + expect(usesReference('(foo|bar)', customOpts)).toBe(true); + }); + }); +}); diff --git a/__tests__/utils/resolveObject.test.js b/__tests__/utils/resolveObject.test.js index 701c40767..76cc15871 100644 --- a/__tests__/utils/resolveObject.test.js +++ b/__tests__/utils/resolveObject.test.js @@ -181,6 +181,19 @@ describe('utils', () => { })); }); + describe('ignorePaths', () => { + it('should not resolve values containing variables in ignored paths', () => { + const test = resolveObject({ + foo: { value: 'bar' }, + bar: { + value: '{foo.value}' + } + }, {ignorePaths: ['foo.value']}); + + expect(test).toHaveProperty ('bar.value', '{foo.value}'); + }); + }); + describe('ignoreKeys', () => { it('should handle default value of original', () => { var test = resolveObject({ diff --git a/docs/README.md b/docs/README.md index 8ec130d96..eaa8467b6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,9 +2,8 @@ [![npm version](https://img.shields.io/npm/v/style-dictionary.svg?style=flat-square)](https://badge.fury.io/js/style-dictionary) ![license](https://img.shields.io/npm/l/style-dictionary.svg?style=flat-square) -[![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/amzn/style-dictionary/blob/master/CONTRIBUTING.md#submitting-pull-requests) -
-[![Build Status](https://img.shields.io/travis/amzn/style-dictionary.svg?style=flat-square)](https://travis-ci.org/amzn/style-dictionary) +[![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/amzn/style-dictionary/blob/main/CONTRIBUTING.md#submitting-pull-requests) +[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/amzn/style-dictionary/Test?style=flat-square)](https://github.com/amzn/style-dictionary/actions/workflows/test.yml) [![downloads](https://img.shields.io/npm/dm/style-dictionary.svg?style=flat-square)](https://www.npmjs.com/package/style-dictionary) # Style Dictionary @@ -12,7 +11,7 @@ A Style Dictionary is a system that allows you to define styles once, in a way for any platform or language to consume. A single place to create and edit your styles, and a single command exports these rules to all the places you need them - iOS, Android, CSS, JS, HTML, sketch files, style documentation, etc. It is available as a [CLI](using_the_cli.md) through npm, but can also be used like any normal [npm module](using_the_npm_module.md) if you want to [extend](extending.md) its functionality. -When you are managing user experiences, it can be quite challenging to keep styles consistent and synchronized across multiple development platforms and devices. At the same time, designers, developers, PMs and others must be able to have consistent and up-to-date style documentation to enable effective work and communication. Even then, mistakes inevitably happen and the design may not be implemented accurately. StyleDictionary solves this by automatically generating style definitions across all platforms from a single source - removing roadblocks, errors, and inefficiencies across your workflow. +When you are managing user experiences, it can be quite challenging to keep styles consistent and synchronized across multiple development platforms and devices. At the same time, designers, developers, PMs and others must be able to have consistent and up-to-date style documentation to enable effective work and communication. Even then, mistakes inevitably happen and the design may not be implemented accurately. Style Dictionary solves this by automatically generating style definitions across all platforms from a single source - removing roadblocks, errors, and inefficiencies across your workflow. ## Watch the Demo on Youtube [![Watch the video](assets/fake_player.png)](http://youtu.be/1HREvonfqhY) @@ -22,12 +21,12 @@ When you are managing user experiences, it can be quite challenging to keep styl ## The Basics __A style dictionary consists of:__ -1. [Style properties](properties.md), organized in JSON files +1. [Design tokens](tokens.md), organized in JSON, JSON5, or JS files 1. Static assets (e.g. fonts, icons, images, sounds, etc.), organized into folders -1. [Configuration](config.md), defining the transformation of the properties and assets for each output platform +1. [Configuration](config.md), defining the [transformation](transforms.md) and [formatting](formats.md) of the tokens and assets for each output platform __What a style dictionary does:__ -1. Transforms style properties and assets into platform specific deliverables +1. Transforms design tokens and assets into platform specific deliverables 1. Creates human readable artifacts (e.g. documentation, design libraries, etc) __Things you can build with a style dictionary:__ @@ -39,15 +38,14 @@ __Things you can build with a style dictionary:__ **The value of using Style Dictionary to build all of these is that they are all consistent and up to date.** -The Style Dictionary framework is fully extensible and modular. You can create any type of file from a style dictionary. -If there is a new language, platform, or file type you need, you can easily [extend](extending.md) the style dictionary framework to create the necessary files. +The Style Dictionary framework is fully extensible and modular. You can create any type of file from a style dictionary. If there is a new language, platform, or file type you need, you can easily [extend](extending.md) the style dictionary framework to create the necessary files. ## Contributing -Please help make this framework better. For more information take a look at [CONTRIBUTING.md](https://github.com/amzn/style-dictionary/blob/master/CONTRIBUTING.md) +Please help make this framework better. For more information take a look at [CONTRIBUTING.md](https://github.com/amzn/style-dictionary/blob/main/CONTRIBUTING.md) ## License -[Apache 2.0](https://github.com/amzn/style-dictionary/blob/master/LICENSE) +[Apache 2.0](https://github.com/amzn/style-dictionary/blob/main/LICENSE) diff --git a/docs/_coverpage.md b/docs/_coverpage.md index c226e7218..00aae4947 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -9,6 +9,6 @@ [GitHub](https://github.com/amzn/style-dictionary) [Get Started](README.md) -[Get ready for the next version of Style Dictionary!](version_3.md) +[See what's new in 3.0!](version_3.md) ![color](#D9F8F5) diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 0cac1f3b6..2da7a968a 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -3,16 +3,16 @@ - [Quick Start](quick_start.md) - [Examples](examples.md) - [Config](config.md) - - [Properties](properties.md) + - [Tokens](tokens.md) - [Package structure](package_structure.md) - [Extending](extending.md) - Reference - [Architecture](architecture.md) - - [Build Process](build_process.md) - [Using the CLI](using_the_cli.md) - [Using the NPM Module](using_the_npm_module.md) - [API](api.md) + - [Parsers](parsers.md) - [Transforms](transforms.md) - [Transform groups](transform_groups.md) - [Formats](formats.md) diff --git a/docs/actions.md b/docs/actions.md index 8234cce60..62b279d37 100644 --- a/docs/actions.md +++ b/docs/actions.md @@ -6,13 +6,13 @@ EDIT scripts/handlebars/templates/api.hbs OR JSDOC COMMENT INSTEAD! Actions provide a way to run custom build code such as generating binary assets like images. -Here are all the actions that come with the Style Dictionary build system. We try to include what most people might need. If you think we are missing some things, take a look at our [contributing docs](https://github.com/amzn/style-dictionary/blob/master/CONTRIBUTING.md) and send us a pull request! If you have a specific need for your project, you can always create your own custom action with [`registerAction`](api.md?id=registeraction). +Here are all the actions that come with the Style Dictionary build system. We try to include what most people might need. If you think we are missing some things, take a look at our [contributing docs](https://github.com/amzn/style-dictionary/blob/main/CONTRIBUTING.md) and send us a pull request! If you have a specific need for your project, you can always create your own custom action with [`registerAction`](api.md?id=registeraction). You use actions in your config file under platforms > [platform] > actions ```json { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "android": { "transformGroup": "android", @@ -28,7 +28,7 @@ You use actions in your config file under platforms > [platform] > actions ## Pre-defined Actions -[lib/common/actions.js](https://github.com/amzn/style-dictionary/blob/master/lib/common/actions.js) +[lib/common/actions.js](https://github.com/amzn/style-dictionary/blob/main/lib/common/actions.js) ### android/copyImages diff --git a/docs/api.md b/docs/api.md index 61c1800a2..709032849 100644 --- a/docs/api.md +++ b/docs/api.md @@ -28,7 +28,7 @@ StyleDictionary.buildAllPlatforms(); Takes a platform and performs all transforms to -the properties object (non-mutative) then +the tokens object (non-mutative) then builds all the files and performs any actions. This is useful if you only want to build the artifacts of one platform to speed up the build process. @@ -70,8 +70,8 @@ defined in the platform and calls the undo method on any actions. Takes a platform and performs all transforms to -the properties object (non-mutative) then -cleans all the files and perfoms the undo method of any [actions](actions.md). +the tokens object (non-mutative) then +cleans all the files and performs the undo method of any [actions](actions.md). | Param | Type | @@ -87,7 +87,7 @@ cleans all the files and perfoms the undo method of any [actions](actions.md). -Exports a properties object with applied +Exports a tokens object with applied platform transforms. This is useful if you want to use a style @@ -119,7 +119,7 @@ Create a Style Dictionary const StyleDictionary = require('style-dictionary').extend('config.json'); const StyleDictionary = require('style-dictionary').extend({ - source: ['properties/*.json'], + source: ['tokens/*.json'], platforms: { scss: { transformGroup: 'scss', @@ -142,7 +142,7 @@ const StyleDictionary = require('style-dictionary').extend({ -Adds a custom action to the style property builder. Custom +Adds a custom action to Style Dictionary. Custom actions can do whatever you need, such as: copying files, base64'ing files, running other build scripts, etc. After you register a custom action, you then use that @@ -179,6 +179,37 @@ StyleDictionary.registerAction({ * * * +### registerFileHeader +> StyleDictionary.registerFileHeader(options) ⇒ [style-dictionary](#module_style-dictionary) + + + + +Add a custom file header to the style dictionary. File headers are used in +formats to display some information about how the file was built in a comment. + + +| Param | Type | Description | +| --- | --- | --- | +| options | Object | | +| options.name | String | Name of the format to be referenced in your config.json | +| options.fileHeader | function | Function that returns an array of strings, which will be mapped to comment lines. It takes a single argument which is the default message array. See [file headers](formats.md#file-headers) for more information. | + +**Example** +```js +StyleDictionary.registerFileHeader({ + name: 'myCustomHeader', + fileHeader: function(defaultMessage) { + return [ + ...defaultMessage, + `hello, world!` + ]; + } +}) +``` + +* * * + ### registerFilter > StyleDictionary.registerFilter(filter) ⇒ [style-dictionary](#module_style-dictionary) @@ -192,14 +223,14 @@ Add a custom filter to the style dictionary | --- | --- | --- | | filter | Object | | | filter.name | String | Name of the filter to be referenced in your config.json | -| filter.matcher | function | Matcher function, return boolean if the property should be included. | +| filter.matcher | function | Matcher function, return boolean if the token should be included. | **Example** ```js StyleDictionary.registerFilter({ name: 'isColor', - matcher: function(prop) { - return prop.attributes.category === 'color'; + matcher: function(token) { + return token.attributes.category === 'color'; } }) ``` @@ -219,14 +250,40 @@ Add a custom format to the style dictionary | --- | --- | --- | | format | Object | | | format.name | String | Name of the format to be referenced in your config.json | -| format.formatter | function | Function to perform the format. Takes 2 arguments, `dictionary` and `config` Must return a string. Function is bound to its file object in the `platform.files` array. | +| format.formatter | function | Function to perform the format. Takes a single argument. See [creating custom formats](formats.md#creating-formats) Must return a string, which is then written to a file. | **Example** ```js StyleDictionary.registerFormat({ name: 'json', - formatter: function(dictionary, config) { - return JSON.stringify(dictionary.properties, null, 2); + formatter: function({dictionary, platform, options, file}) { + return JSON.stringify(dictionary.tokens, null, 2); + } +}) +``` + +* * * + +### registerParser +> StyleDictionary.registerParser(pattern, parse) ⇒ [style-dictionary](#module_style-dictionary) + + + + +Adds a custom parser to parse style dictionary files + + +| Param | Type | Description | +| --- | --- | --- | +| pattern | Regex | A file path regular expression to match which files this parser should be be used on. This is similar to how webpack loaders work. `/\.json$/` will match any file ending in '.json', for example. | +| parse | function | Function to parse the file contents. Takes 1 argument, which is an object with 2 attributes: contents wich is the string of the file contents and filePath. The function should return a plain Javascript object. | + +**Example** +```js +StyleDictionary.registerParser({ + pattern: /\.json$/, + parse: ({contents, filePath}) => { + return JSON.parse(contents); } }) ``` @@ -267,7 +324,7 @@ StyleDictionary.registerTemplate({ Add a custom transform to the Style Dictionary -Transforms can manipulate a property's name, value, or attributes +Transforms can manipulate a token's name, value, or attributes | Param | Type | Description | @@ -275,22 +332,23 @@ Transforms can manipulate a property's name, value, or attributes | transform | Object | Transform object | | transform.type | String | Type of transform, can be: name, attribute, or value | | transform.name | String | Name of the transformer (used by transformGroup to call a list of transforms). | -| [transform.matcher] | function | Matcher function, return boolean if transform should be applied. If you omit the matcher function, it will match all properties. | -| transform.transformer | function | Performs a transform on a property object, should return a string or object depending on the type. Will only update certain properties by which you can't mess up property objects on accident. | +| transform.transitive | Boolean | If the value transform should be applied transitively, i.e. should be applied to referenced values as well as absolute values. | +| [transform.matcher] | function | Matcher function, return boolean if transform should be applied. If you omit the matcher function, it will match all tokens. | +| transform.transformer | function | Modifies a design token object. The transformer function will receive the token and the platform configuration as its arguments. The transformer function should return a string for name transforms, an object for attribute transforms, and same type of value for a value transform. | **Example** ```js StyleDictionary.registerTransform({ name: 'time/seconds', type: 'value', - matcher: function(prop) { - return prop.attributes.category === 'time'; + matcher: function(token) { + return token.attributes.category === 'time'; }, - transformer: function(prop) { + transformer: function(token) { // Note the use of prop.original.value, // before any transforms are performed, the build system - // clones the original property to the 'original' attribute. - return (parseInt(prop.original.value) / 1000).toString() + 's'; + // clones the original token to the 'original' attribute. + return (parseInt(token.original.value) / 1000).toString() + 's'; } }); ``` diff --git a/docs/architecture.md b/docs/architecture.md index fbd6e94c8..28bad20e6 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,4 +1,4 @@ -# Architecture Overview +# Architecture This is how Style Dictionary works under the hood. @@ -8,11 +8,13 @@ Let's take a closer look into each of these steps. ## 1. Parse the config -Style Dictionary is a configuration based framework, you tell it what to do in a configuration file. Style Dictionary first parses this configuration to know what to do. +Style Dictionary is a configuration based framework, you tell it what to do in a configuration file. Style Dictionary first parses this [configuration](config.md) to know what to do. ## 2. Find all token files -In your [config](config.md) file you define a `source`, which is an array of file paths. This tells Style Dictionary where to find your token files. You can have them anywhere and in any folder structure as long as you tell Style Dictionary where to find them. +In your [config](config.md) file can define `include` and `source`, which are arrays of file path globs. These tell Style Dictionary where to find your token files. You can have them anywhere and in any folder structure as long as you tell Style Dictionary where to find them. + +If there are [custom parsers](parsers.md) defined, Style Dictionary will run those on files the parsers match. ## 3. Deep merge token files @@ -20,18 +22,24 @@ Style Dictionary takes all the files it found and performs a deep merge. This al ## 4. Iterate over the platforms -For each platform defined in your [config](config.md), Style Dictionary will do a few steps to get it ready to be consumed on that platform. You don't need to worry about one platform affecting another because everything that happens in a platform is non-destructive +For each platform defined in your [config](config.md), Style Dictionary will do a few steps to get it ready to be consumed on that platform. You don't need to worry about one platform affecting another because everything that happens in a platform is non-destructive. ## 4a. Transform the tokens Style Dictionary now traverses over the whole token object and looks for design tokens. It does this by looking for anything with a `value` key. When it comes across a design token, it then performs all the [transforms](transforms.md) defined in your [config](config.md) in order. +Value transforms, transforms that modify a token's value, are skipped if the token references another token. Starting in 3.0, you can define a [transitive transform](transforms.md#transitive-transforms) that will transform a value that references another token after that reference has been resolved. + ## 4b. Resolve aliases / references to other values -After all the tokens have been transformed, it then does another pass over the token object looking for aliases, which look like `"{size.font.base.value}"`. When it finds these, it then replaces the reference with the transformed value. As we have a single complete token object, aliases can be in any token file and still work. +After all the tokens have been transformed, it then does another pass over the token object looking for aliases, which look like `"{size.font.base.value}"`. When it finds these, it then replaces the reference with the transformed value. Because Style Dictionary merges all token files into a single object, aliases can be in any token file and still work. ## 4c. Format the tokens into files Now all the design tokens are ready to be written to a file. Style Dictionary takes the whole transformed and resolved token object and for each file defined in the platform it [formats](formats.md) the token object and write the output to a file. Internally, Style Dictionary creates a flat array of all the design tokens it finds in addition to the token object. This is how you can output a flat SCSS variables file. -After Style Dictionary does steps 4-6 for each platform, now you have all your output files that are ready to consume in each platform and codebase. +## 4d. Run actions + +[Actions](actions.md) are custom code that run in a platform after the files are generated. They are useful for things like copying assets to specific build directories or generating images. + +After Style Dictionary does steps 4a-4d for each platform, you will have all your output files that are ready to consume in each platform and codebase. diff --git a/docs/assets/styles.css b/docs/assets/styles.css index 35a24813c..fa97f2d2c 100644 --- a/docs/assets/styles.css +++ b/docs/assets/styles.css @@ -284,7 +284,8 @@ section.cover .cover-main { } .markdown-section hr { - border-bottom: 5px solid transparent; + width: 25%; + border-bottom: 5px solid #F1F1F2; } .token.punctuation { @@ -363,6 +364,11 @@ section.cover .cover-main { color: var(--theme-color-dark); } +.alert { + padding: 2rem; + border: 0.1rem solid var(--theme-color-secondary-light); +} + /* Badges */ .markdown-section > p:first-child > a { diff --git a/docs/build_process.md b/docs/build_process.md deleted file mode 100644 index 95936a01d..000000000 --- a/docs/build_process.md +++ /dev/null @@ -1,16 +0,0 @@ -# Build Process - -Here is what the build system is doing under the hood. - -![build structure](assets/build-diagram.png) - -1. The build system reads in a configuration -1. If there is an `includes` attribute in the config, it will take those files and deep merge them into the `properties` object -1. It takes all the JSON files in the `source` attribute in the config and performs a deep merge onto the `properties` object -1. Then it iterates over the platforms in the config and: - 1. Performs all transforms, in order, defined in the transforms attribute or transformGroup - 1. Builds all files defined in the files array - 1. Performs any actions defined in the actions attribute - -# How to Build -You can build a style dictionary [using the cli](using_the_cli.md) or [using the npm module](using_the_npm_module.md). diff --git a/docs/config.md b/docs/config.md index 7523a8443..ab185e647 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,17 +1,15 @@ # Configuration -Style dictionaries are configuration driven. Your config file defines what executes and what to output when the style dictionary builds. +Style dictionaries are configuration driven. Your configuration lets Style Dictionary know: -By default, Style Dictionary looks for a `config.json` file in the root of your package. If not found, it looks for a `config.js` file in the root of your package. You can also specify a custom location when you use the [CLI](using_the_cli.md). If you want a custom build system using the [npm module](using_the_npm_module.md), you can specify a custom location for a configuration file or use a plain Javascript object. +1. Where to find your [design tokens](tokens.md) +1. How to transform and format them to generate output files -## config.js -You can find out more about creating configurations in JS in our documentation about using the [npm module](using_the_npm_module.md). +Here is an example configuration: -## config.json - Here is a quick example: ```json { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "scss": { "transformGroup": "scss", @@ -35,20 +33,145 @@ You can find out more about creating configurations in JS in our documentation a } ``` +## Configuration file formats + +Style Dictionary supports configuration files in these file formats: + +* JSON +* JSON5 +* Javascript (CommonJS) + +Here is an example using a CommonJS module for configuration: + +```javascript +// config.js +module.exports = { + source: [`tokens/**/*.json`], + // If you don't want to call the registerTransform method a bunch of times + // you can override the whole transform object directly. This works because + // the .extend method copies everything in the config + // to itself, allowing you to override things. It's also doing a deep merge + // to protect from accidentally overriding nested attributes. + transform: { + // Now we can use the transform 'myTransform' below + myTransform: { + type: 'name', + transformer: (token) => token.path.join('_').toUpperCase() + } + }, + // Same with formats, you can now write them directly to this config + // object. The name of the format is the key. + format: { + myFormat: ({dictionary, platform}) => { + return dictionary.allTokens.map(token => `${token.name}: ${token.value}`).join('\n'); + } + }, + platforms: { + // ... + } +} +``` + +Some interesting things you can do in a CommonJS file that you cannot do in a JSON file: + +* Add custom transforms, formats, filters, actions, and parsers +* Programmatically generate your configuration + + +---- + + +## Using configuration files + +By default, the Style Dictionary [CLI](using_the_cli.md) looks for a `config.json` or `config.js` file in the root of your package. + +```json5 +// package.json +"scripts": { + "build": "style-dictionary build" +} +``` + +You can also specify a custom location when you use the [CLI](using_the_cli.md) with the `--config` parameter. + +```json5 +// package.json +"scripts": { + "build": "style-dictionary build --config ./sd.config.js" +} +``` + +## Using in Node + +You can also use Style Dictionary as an [npm module](using_the_npm_module.md) and further customize how Style Dictionary is run, for example running Style Dictionary multiple times with different configurations. To do this you would create a Javascript file that imports the Style Dictionary npm module and calls the [`.extend`](api.md#extend) and [`.buildAllPlatforms`](api.md#buildallplatforms) functions. + +```javascript +// build.js +const StyleDictionary = require('style-dictionary'); + +const myStyleDictionary = StyleDictionary.extend({ + // configuration +}); + +myStyleDictionary.buildAllPlatforms(); + +// You can also extend Style Dictionary multiple times: +const myOtherStyleDictionary = myStyleDictionary.extend({ + // new configuration +}); + +myOtherStyleDictionary.buildAllPlatforms(); +``` + +You would then change your npm script or CLI command to run that file with Node: + +```json5 +// package.json +"scripts": { + "build": "node build.js" +} +``` + +---- + + +## Attributes + | Attribute | Type | Description | | :--- | :--- | :--- | -| include | Array[String] (optional) | An array of path [globs](https://github.com/isaacs/node-glob) to Style Dictionary property files that contain default styles. The Style Dictionary uses this as a base collection of properties. The properties found using the "source" attribute will overwrite properties found using include. | -| source | Array[String] | An array of path [globs](https://github.com/isaacs/node-glob) to JSON files that contain style properties. The Style Dictionary will do a deep merge of all of the JSON files, allowing you to separate your properties into multiple files. | -| platforms | Object | An object containing platform config objects that describe how the Style Dictionary should build for that platform. You can add any arbitrary attributes on this object that will get passed to formats and actions (more on these in a bit). This is useful for things like build paths, name prefixes, variable names, etc. | -| platform.transforms | Array[String] (optional) | An array of [transforms](transforms.md) to be performed on the style properties object. These will transform the properties in a non-destructive way, allowing each platform to transform the properties. Transforms to apply sequentially to all properties. Can be a built-in one or you can create your own. | -| platform.transformGroup | String (optional) | A string that maps to an array of transforms. This makes it easier to reference transforms by grouping them together. You must either define this or [transforms](transforms.md). | -| platform.buildPath | String (optional) | Base path to build the files, must end with a trailing slash. | -| platform.files | Array (optional) | Files to be generated for this platform. | -| platform.file.destination | String (optional) | Location to build the file, will be appended to the buildPath. | -| platform.file.format | String (optional) | [Format](formats.md) used to generate the file. Can be a built-in one or you can create your own via [registerFormat](api.md#registerformat). | -| platform.file.filter | String/Function/Object (optional) | A function, string or object used to filter the properties that will be included in the file. If a function is provided, each property will be passed to the function and the result (true or false) will determine whether the property is included. If an object is provided, each property will be matched against the object using a partial deep comparison. If a match is found, the property is included. If a string is passed, is considered a custom filter registered via [registerFilter](api.md#registerfilter) | -| platform.file.options | Object (optional) | A set of extra options associated with the file. Only includes 'showFileHeader' at this time. | -| platform.file.options.showFileHeader | Boolean | If the generated file should have a "Do not edit + Timestamp" header (where the format supports it). By default is "true". | -| platform.actions | Array[String] (optional) | [Actions](actions.md) to be performed after the files are built for that platform. Actions can be any arbitrary code you want to run like copying files, generating assets, etc. You can use pre-defined actions or create custom actions. | +| transform | Object (optional) | Custom [transforms](transforms.md) you can include inline rather than using `.registerTransform`. The keys in this object will be the transform's name, the value should be an object with `type` +| format | Object (optional) | Custom [formats](formats.md) you can include inline in the configuration rather than using `.registerFormat`. The keys in this object will be for format's name and value should be the formatter function. +| action | Object (optional) | Custom inline [actions](actions.md). The keys in this object will be the action's name and the value should be an object containing `do` and `undo` methods. +| parsers | Array[Parser] (optional) | Custom [file parsers](parsers.md) to run on input files | +| include | Array[String] (optional) | An array of file path [globs](https://github.com/isaacs/node-glob) to design token files that contain default styles. Style Dictionary uses this as a base collection of design tokens. The tokens found using the "source" attribute will overwrite tokens found using include. | +| source | Array[String] | An array of file path [globs](https://github.com/isaacs/node-glob) to design token files. Style Dictionary will do a deep merge of all of the token files, allowing you to organize your files files however you want. | +| tokens | Object | The tokens object is a way to include inline design tokens as opposed to using the `source` and `include` arrays. +| properties | Object | **DEPRECATED** The properties object has been renamed to `tokens`. Using the `properties` object will still work for backwards compatibility. +| platforms | Object[Platform] | An object containing [platform](#platform) config objects that describe how the Style Dictionary should build for that platform. You can add any arbitrary attributes on this object that will get passed to formats and actions (more on these in a bit). This is useful for things like build paths, name prefixes, variable names, etc. ----- +### Platform + +A platform is a build target that tells Style Dictionary how to properly transform and format your design tokens for output to a specific platform. You can have as many platforms as you need and you can name them anything, there are no restrictions. + +| Attribute | Type | Description | +| :--- | :--- | :--- | +| transforms | Array[String] (optional) | An array of [transforms](transforms.md) to be performed on the design tokens. These will transform the tokens in a non-destructive way, allowing each platform to transform the tokens. Transforms to apply sequentially to all tokens. Can be a built-in one or you can create your own. +| transformGroup | String (optional) | A string that maps to an array of transforms. This makes it easier to reference transforms by grouping them together. You must either define this or [transforms](transforms.md). +| buildPath | String (optional) | Base path to build the files, must end with a trailing slash. +| options | Object (optional) | Options that apply to all files in the platform, for example `outputReferences` and `showFileHeader` +| files | Array[File] (optional) | [Files](#file) to be generated for this platform. +| actions | Array[String] (optional) | [Actions](actions.md) to be performed after the files are built for that platform. Actions can be any arbitrary code you want to run like copying files, generating assets, etc. You can use pre-defined actions or create custom actions. + +### File + +A File configuration object represents a single output file. The `options` object on the file configuration will take precedence over the `options` object defined at the platform level. + +| Attribute | Type | Description | +| :--- | :--- | :--- | +| destination | String (optional) | Location to build the file, will be appended to the buildPath. | +| format | String (optional) | [Format](formats.md) used to generate the file. Can be a built-in one or you can create your own via [registerFormat](api.md#registerformat). | +| filter | String/Function/Object (optional) | A function, string or object used to filter the tokens that will be included in the file. If a function is provided, each design token will be passed to the function and the result (true or false) will determine whether the design token is included. If an object is provided, each design token will be matched against the object using a partial deep comparison. If a match is found, the design token is included. If a string is passed, is considered a custom filter registered via [registerFilter](api.md#registerfilter) | +| options | Object (optional) | A set of extra options associated with the file. Includes `showFileHeader` and `outputReferences`. | +| options.showFileHeader | Boolean | If the generated file should have a comment at the top about being generated. The default fileHeader comment has "Do not edit + Timestamp". By default is "true". | +| options.fileHeader | String/Function (optional) | A custom fileHeader that can be either a name of a registered file header (string) or an inline [fileHeader](formats.md#customfileheader) function. +| options.outputReferences | Boolean | If the file should keep token [references](formats.md#references-in-output-files). By default this is "false". diff --git a/docs/examples.md b/docs/examples.md index 5245e9523..f37209cc5 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -24,18 +24,29 @@ This is a more complete package and should have everything you need to get start ## Advanced [View the folder](https://github.com/amzn/style-dictionary/tree/main/examples/advanced) -If you want to look at more advanced examples of possible applications and customizations of Style Dictionary, the `examples/advanced` folder on GitHub contains these extra folders: +If you want to look at more advanced examples of possible applications and customizations of Style Dictionary, the [`examples/advanced`](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/) folder on GitHub contains these extra folders: * [**assets-base64-embed**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/assets-base64-embed) shows how it's possible to embed and distribute assets – like images, icons and fonts – directly as design tokens. -* [**auto-rebuild-watcher**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/auto-rebuild-watcher) shows how to setup a "watcher" that auto-rebuilds the tokens every time there is a change in the properties. +* [**auto-rebuild-watcher**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/auto-rebuild-watcher) shows how to setup a "watcher" that auto-rebuilds the tokens every time there is a change in the tokens. +* [**component-cti**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/component-cti) shows how to write component tokens and still use the CTI structure. +* [**create-react-app**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/create-react-app) shows how to integrate Style Dictionary into a React application. +* [**create-react-native-app**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/create-react-native-app) shows how to integrate Style Dictionary into a React Native application. +* [**custom-file-header**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-file-header) shows how to define custom file headers and use them in output files. * [**custom-formats-with-templates**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-formats-with-templates) shows how to generate custom output formats using templates, useful when you need to distribute your design tokens into your own pipelines or scripts. -* [**custom-transforms**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-transforms) shows how to use custom transforms (and transformGroups) to apply custom "transformations" to the properties when converted to design tokens. -* [**multi-brand-multi-platform**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/multi-brand-multi-platform) shows how to set up Style Dictionary to support a multi-brand (for brand theming) and multi-platform (web, iOS, Android) solution, with property values depending on brand and platforms. +* [**custom-parser**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-parser) shows how to use custom parsers for token files. +* [**custom-transforms**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-transforms) shows how to use custom transforms (and transformGroups) to apply custom "transformations" to the design tokens. +* [**flutter**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/flutter) shows how to integrate with Flutter applications. +* [**matching-build-files**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/matching-build-files) shows how to output files 1-to-1 with source files. +* [**multi-brand-multi-platform**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/multi-brand-multi-platform) shows how to set up Style Dictionary to support a multi-brand (for brand theming) and multi-platform (web, iOS, Android) solution, with token values depending on brand and platforms. +* [**node-modules-as-config-and-properties**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/node-modules-as-config-and-properties) shows how to use Javascript rather than JSON for configuration and token files. * [**npm-module**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/npm-module) shows how to set up a style dictionary as an npm module, either to publish to a local npm service or to publish externally. +* [**referencing_aliasing**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/referencing_aliasing) shows how to use referencing (or "aliasing") to reference a value -or an attribute– of a token and assign it to the value –or attribute– of another token. * [**s3**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/s3) shows how to set up a style dictionary to build files for different platforms (web, iOS, Android) and upload those build artifacts, together with a group of assets, to an S3 bucket. -* [**referencing_aliasing**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/referencing_aliasing) shows how to use referencing (or "aliasing") to reference a value -or an attribute– of a property and assign it to the value –or attribute– of another property. * [**tokens-deprecation**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/tokens-deprecation) shows one way to deprecate tokens by adding metadata to tokens and using custom formats to output comments in the generated files. -* [**component-cti**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/component-cti) shows how to write component tokens and still use the CTI structure. +* [**transitive-transforms**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/transitive-transforms) shows how to use transitive transforms to transform references +* [**variables-in-outputs**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/variables-in-outputs) shows you how to use the `outputReferences` option to generate files variable references in them. +* [**yaml-tokens**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/yaml-tokens) shows how to use a custom parser to define your source files in YAML rather than JSON. + --- diff --git a/docs/extending.md b/docs/extending.md index 83a8c76a5..3222e47f8 100644 --- a/docs/extending.md +++ b/docs/extending.md @@ -9,6 +9,7 @@ There is a straightforward way to extend Style Dictionary to meet your needs - s * [registerFormat](api.md#registerformat) * [registerTemplate](api.md#registertemplate) (deprecated) * [registerAction](api.md#registeraction) +* [registerParser](api.md#registerparser) ## Extension Examples Importing a configuration, defining a new `time/seconds` transform, and building the style dictionary. diff --git a/docs/formats.md b/docs/formats.md index 0fa1aba81..7e49f936b 100644 --- a/docs/formats.md +++ b/docs/formats.md @@ -8,13 +8,13 @@ Formats define the output of your created files. For example, to use your styles you use the `css/variables` format. This will create a CSS file containing the variables from your style dictionary. -### Using formats +## Using formats You use formats in your config file under platforms > [platform] > files > [file] > format ```json { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "css": { "transformGroup": "css", @@ -31,13 +31,13 @@ You use formats in your config file under platforms > [platform] > files > [file There is an extensive (but not exhaustive) list of [included formats](#pre-defined-formats) available in Style Dictionary. -### Format configuration +## Format configuration Formats can take configuration to make them more flexible. This allows you to re-use the same format multiple times with different configurations or to allow the format to use data not defined in the tokens themselves. To configure a format, add extra attributes on the file object in your configuration like the following: ```json { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "scss": { "transformGroup": "scss", @@ -53,13 +53,13 @@ Formats can take configuration to make them more flexible. This allows you to re In this example we are adding the `mapName` configuration to the `scss/map-deep` format. This will change the name of the SCSS map in the output. Not all formats have the configuration options; format configuration is defined by the format itself. To see the configurtion options of a format, take a look at the documentation of the [specific format](#pre-defined-formats) -### Filtering tokens +## Filtering tokens A special file configuration is `filter`, which will filter the tokens before they get to the format. This allows you to re-use the same format to generate multiple files with different sets of tokens. Filtering tokens works by adding a `filter` attribute on the file object, where `filter` is: * An object which gets passed to [Lodash's filter method](https://lodash.com/docs/4.17.14#filter). * A string that references the name of a registered filter, using the [`registerFilter`](api.md#registerfilter) method -* A function if you are defining your configuration in Javascript rather than JSON. The filter function takes a token as the property and should return a boolean if the token should be included (true) or excluded (false). +* A function that takes a token and returns a boolean if the token should be included (true) or excluded (false). **This is only available if you are defining your configuration in Javascript.** ```javascript { @@ -71,24 +71,554 @@ A special file configuration is `filter`, which will filter the tokens before th } ``` -### Creating formats +The design token that is passed to the filter function has already been [transformed](transforms.md) and has [default metadata](tokens.md?id=default-design-token-metadata) added by Style Dictionary. -You can create custom formats using the [`registerFormat`](api.md#registerformat) function. If you want to add configuration to your custom format, `this` is bound to the file object. Using this, you can access attributes on the file object with `this.myCustomAttribute` if the file object looks like: +## References in output files + +Starting with version 3.0, some formats can keep the references in the output. This is a bit hard to explain, so let's look at an example. Say you have this very basic set of design tokens: + +```json5 +// tokens.json +{ + "color": { + "red": { "value": "#ff0000" }, + "danger": { "value": "{color.red.value}" }, + "error": { "value": "{color.danger.value}" } + } +} +``` + +With this configuration: + +```json5 +// config.json +{ + "source": ["tokens.json"] + "platforms": { + "css": { + "transformGroup": "css", + "files": [{ + "destination": "variables.css", + "format": "css/variables", + "options": { + // Look here 👇 + "outputReferences": true + } + }] + } + } +} +``` + +This would be the output: + +```css +:root { + --color-red: #ff0000; + --color-danger: var(--color-red); + --color-error: var(--color-danger); +} +``` + +The css variables file now keeps the references you have in your Style Dictionary! This is useful for outputting themeable and dynamic code. + +Without `outputReferences: true` Style Dictionary would resolve all references and the output would be: + +```css +:root { + --color-red: #ff0000; + --color-danger: #ff0000; + --color-error: #ff0000; +} +``` + +Not all formats use the `outputReferences` option because that file format might not support it (like JSON for example). The current list of formats that handle `outputReferences`: + +* [css/variables](#cssvariables) +* [scss/variables](#scssvariables) +* [less/variables](#lessvariables) +* [android/resources](#androidresources) +* [compose/object](#composeobject) +* [ios-swift/class.swift](#ios-swiftclassswift) +* [flutter/class.dart](#flutterclassdart) + +You can create custom formats that output references as well. See the [Custom format with output references](#custom-format-with-output-references) section. + +## File headers + +By default Style Dictionary adds a file header comment in the top of files built using built-in formats like this: + +```js +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT +``` + +You can remove these comments with the option: `showFileHeader: false` if you do not want them in your generated files. You can also create your own file header or extend the default one. This could be useful if you want to put a version number or hash of the source files rather than a timestamp. + +Custom file headers can be added the same way you would add a custom format, either by using the [`registerFileHeader`](api.md#registerfileheader) function or adding the fileHeader object directly in the Style Dictionary [configuration](config.md). Your custom file header can be used in built-in formats as well as custom formats. To use a custom file header in a custom format see the [`fileHeader`](formats.md#fileheader) format helper method. + +```js +const StyleDictionary = require('style-dictionary'); +StyleDictionary.registerFileHeader({ + name: 'myCustomHeader', + fileHeader: (defaultMessage) => { + // defaultMessage are the 2 lines above that appear in the default file header + // you can use this to add a message before or after the default message 👇 + + // the fileHeader function should return an array of strings + // which will be formatted in the proper comment style for a given format + return [ + ...defaultMessage, + `hello?`, + `is it me you're looking for?`, + ] + } +}); +``` + +Then you can use your custom file header in a file similar to a custom format: + +```json5 +{ + source: ['tokens/**/*.json'], + platforms: { + css: { + transformGroup: 'css', + files: [{ + destination: 'variables.css', + format: 'css/variables', + options: { + fileHeader: 'myCustomHeader' + } + }] + } + } +} +``` + +Which should output a file that will start like this: + +```css +/** + * Do not edit directly + * Generated on Thu, 18 Mar 2021 21:30:47 GMT + * hello? + * is it me you're looking for? + */ +``` + +For an in-depth example see the [custom-file-header](https://github.com/amzn/style-dictionary/examples/advanced/custom-file-header) example. + +## Custom formats + +You can create custom formats using the [`registerFormat`](api.md#registerformat) function or by directly including them in your [configuration](config.md). A format has a name and a formatter function, which takes an object as the argument and should return a string which is then written to a file. + +### formatter +> format.formatter(args) ⇒ String + +The formatter function that is called when Style Dictionary builds files. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParamTypeDescription
argsObject

A single argument to support named parameters and destructuring.

+
args.dictionaryObject

The transformed and resolved dictionary object

+
args.dictionary.tokensObject

Object structure of the tokens that has been transformed and references resolved.

+
args.dictionary.allTokensArray

Flattened array of all the tokens. This makes it easy to output a list, like a list of SCSS variables.

+
args.dictionary.usesReferencefunction

Use this function to see if a token's value uses a reference. This is the same function style dictionary uses internally to detect a reference.

+
args.dictionary.getReferencesfunction

Use this function to get the tokens that it references. You can use this to output a reference in your custom format. For example: dictionary.getReferences(token.original.value) // returns an array of the referenced token objects

+
args.platformObject

The platform configuration this format is being called in.

+
args.fileObject

The file configuration this format is being called in.

+
args.optionsObject

Merged options object that combines platform level configuration and file level configuration. File options take precedence.

+
+ +**Example** +```js +StyleDictionary.registerFormat({ + name: 'myCustomFormat', + formatter: function({dictionary, platform, options, file}) { + return JSON.stringify(dictionary.tokens, null, 2); + } +}) +``` + +* * * + + +To use your custom format, you call it by name in the file configuration object: ```json { - "destination": "destination", - "format": "myCustomFormat", - "myCustomAttribute": "Hello world" + "source": ["tokens/**/*.json"], + "platforms": { + "css": { + "options": { + "showFileHeader": true + }, + "transformGroup": "css", + "files": [{ + "destination": "destination", + "format": "myCustomFormat", + "options": { + "showFileHeader": false + } + }] + } + } } ``` +It is recommended for any configuration needed for your custom format to use the `options` object. Style Dictionary will merge platform and file options so that in your Style Dictionary configuration you can specify options at a platform or file level. In the configuration above, the `options` object passed to the formatter would have `showFileHeader: false`. + +
+Note: to support legacy ways of defining custom formats, this in the formatter function is bound to the file object and when Style Dictionary calls the formatter function it passes 3 arguments: dictionary, platform, and file. Starting in 3.0 all data the formatter needs is in the first argument as shown above to make it easier to grab the arguments by name rather than by position. We recommend not using this or the positional arguments in your custom format. +
+ +## Custom format with output references + +To take advantage of outputting references in your custom formats there are 2 helper methods in the `dictionary` argument passed to your formatter function: `usesReference(value)` and `getReferences(value)`. Here is an example using those: + +```javascript +StyleDictionary.registerFormat({ + name: `es6WithReferences`, + formatter: function({dictionary}) { + return dictionary.allTokens.map(token => { + let value = JSON.stringify(token.value); + // the `dictionary` object now has `usesReference()` and + // `getReferences()` methods. `usesReference()` will return true if + // the value has a reference in it. `getReferences()` will return + // an array of references to the whole tokens so that you can access its + // name or any other attributes. + if (dictionary.usesReference(token.original.value)) { + // Note: make sure to use `token.original.value` because + // `token.value` is already resolved at this point. + const reference = dictionary.getReferences(token.original.value); + value = reference.name; + } + return `export const ${token.name} = ${value};` + }).join(`\n`) + } +}); +``` + +## Custom format helpers + +We provide some helper methods we use internally in some of the built-in formats to make building custom formats a bit easier. They are accessible at `StyleDictionary.formatHelpers`. + +```javascript +const StyleDictionary = require('style-dictionary'); + +const { fileHeader, formattedVariables } = StyleDictionary.formatHelpers; + +StyleDictionary.registerFormat({ + name: 'myCustomFormat', + formatter: function({dictionary, file, options}) { + const { outputReferences } = options; + return fileHeader({file}) + + ':root {\n' + + formattedVariables({format: 'css', dictionary, outputReferences}) + + '\n}\n'; + } +}); +``` + +Here are the available format helper methods: + +### createPropertyFormatter +> formatHelpers.createPropertyFormatter(options) ⇒ function + +Creates a function that can be used to format a property. This can be useful +to use as the function on `dictionary.allTokens.map`. The formatting +is configurable either by supplying a `format` option or a `formatting` object +which uses: prefix, indentation, separator, suffix, and commentStyle. + + + + + + + + + + + + + + + + + + + +
ParamTypeDescription
optionsObject
options.outputReferencesBoolean

Whether or not to output references. You will want to pass this from the options object sent to the formatter function.

+
options.dictionaryDictionary

The dictionary object sent to the formatter function

+
options.formatString

Available formats are: 'css', 'sass', 'less', and 'stylus'. If you want to customize the format and can't use one of those predefined formats, use the formatting option

+
options.formattingObject

Custom formatting properties that define parts of a declaration line in code. The configurable strings are: prefix, indentation, separator, suffix, and commentStyle. Those are used to generate a line like this: ${indentation}${prefix}${prop.name}${separator} ${prop.value}${suffix}

+
+ +**Example** +```javascript +StyleDictionary.registerFormat({ + name: 'myCustomFormat', + formatter: function({ dictionary, options }) { + const { outputReferences } = options; + const formatProperty = createPropertyFormatter({ + outputReferences, + dictionary, + format: 'css' + }); + return dictionary.allTokens.map(formatProperty).join('\n'); + } +}); +``` + +* * * + +### fileHeader +> formatHelpers.fileHeader(options) ⇒ String + +This is for creating the comment at the top of generated files with the generated at date. +It will use the custom file header if defined on the configuration, or use the +default file header. + + + + + + + + + + + + + + + + + +
ParamTypeDescription
optionsObject
options.fileFile

The file object that is passed to the formatter.

+
options.commentStyleString

The only options are 'short' and 'xml', which will use the // or <!-- --> style comments respectively. Anything else will use /* style comments.

+
options.formattingObject

Custom formatting properties that define parts of a comment in code. The configurable strings are: prefix, lineSeparator, header, and footer.

+
+ +**Example** +```js +StyleDictionary.registerFormat({ + name: 'myCustomFormat', + formatter: function({ dictionary, file }) { + return fileHeader({file, 'short') + + dictionary.allTokens.map(token => `${token.name} = ${token.value}`) + .join('\n'); + } +}); +``` + +* * * + +### formattedVariables +> formatHelpers.formattedVariables(options) ⇒ String + +This is used to create lists of variables like Sass variables or CSS custom properties + + + + + + + + + + + + + + + + + + + +
ParamTypeDescription
optionsObject
options.formatString

What type of variables to output. Options are: css, sass, less, and stylus

+
options.dictionaryObject

The dictionary object that gets passed to the formatter method.

+
options.outputReferencesBoolean

Whether or not to output references

+
options.formattingObject

Custom formatting properties that define parts of a declaration line in code. This will get passed to formatHelpers.createPropertyFormatter and used for the lineSeparator between lines of code.

+
+ +**Example** +```js +StyleDictionary.registerFormat({ + name: 'myCustomFormat', + formatter: function({ dictionary, options }) { + return formattedVariables('less', dictionary, options.outputReferences); + } +}); +``` + +* * * + +### iconsWithPrefix +> formatHelpers.iconsWithPrefix(prefix, allTokens, options) ⇒ String + +This is used to create CSS (and CSS pre-processor) lists of icons. It assumes you are +using an icon font and creates helper classes with the :before pseudo-selector to add +a unicode character. +__You probably don't need this.__ + + + + + + + + + + + + + + + +
ParamTypeDescription
prefixString

Character to prefix variable names, like '$' for Sass

+
allTokensArray.<Token>

allTokens array on the dictionary object passed to the formatter function.

+
optionsObject

options object passed to the formatter function.

+
+ +**Example** +```js +StyleDictionary.registerFormat({ + name: 'myCustomFormat', + formatter: function({ dictionary, options }) { + return iconsWithPrefix('$', dictionary.allTokens, options); + } +}); +``` + +* * * + +### minifyDictionary +> formatHelpers.minifyDictionary(obj) ⇒ Object + +Outputs an object stripping out everything except values + + + + + + + + + + + +
ParamTypeDescription
objObject

The object to minify. You will most likely pass dictionary.tokens to it.

+
+ +**Example** +```js +StyleDictionary.registerFormat({ + name: 'myCustomFormat', + formatter: function({ dictionary }) { + return JSON.stringify(minifyDictionary(dictionary.tokens)); + } +}); +``` + +* * * + +### sortByName +> formatHelpers.sortByName(a, b) ⇒ Integer + +A sorting function to be used when iterating over `dictionary.allTokens` in +a format. + +**Returns**: Integer - -1 or 1 depending on which element should come first based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort + + + + + + + + + + + + +
ParamTypeDescription
a*

first element for comparison

+
b*

second element for comparison

+
+ +**Example** +```javascript +StyleDictionary.registerFormat({ + name: 'myCustomFormat', + formatter: function({ dictionary, options }) { + return dictionary.allTokens.sort(sortByName) + .map(token => `${token.name} = ${token.value}`) + .join('\n'); + } +}); +``` + +* * * + +### sortByReference +> formatHelpers.sortByReference(dictionary) ⇒ function + +A function that returns a sorting function to be used with Array.sort that +will sort the allTokens array based on references. This is to make sure +if you use output references that you never use a reference before it is +defined. + + + + + + + + + + + +
ParamType
dictionaryDictionary
+ +**Example** +```javascript +dictionary.allTokens.sort(sortByReference(dictionary)) +``` + +* * * + -### Using a template / templating engine to create a format +## Using a template / templating engine to create a format Formatters are functions and created easily with most templating engines. Formats can be built using templates if there is a lot of boilerplate code to insert (e.g. ObjectiveC files). If the output consists of only the values (e.g. a flat SCSS variables file), writing a formatter function directly may be easier. -Any templating language can work as there is a node module for it. All you need to do is register a format that calls your template and returns a string. +Any templating language can work as long as there is a node module for it. All you need to do is register a format that calls your template and returns a string. Here is a quick example for Lodash. @@ -116,9 +646,9 @@ const template = Handlebars.compile( fs.readFileSync('templates/MyTemplate.hbs') styleDictionary.registerFormat({ name: 'my/format', - formatter: function(dictionary, platform) { + formatter: function({dictionary, platform}) { return template({ - properties: dictionary.properties, + tokens: dictionary.tokens, options: platform }); } @@ -131,7 +661,7 @@ styleDictionary.registerFormat({ ## Pre-defined Formats -These are the formats included in Style Dictionary by default, pulled from [lib/common/formats.js](https://github.com/amzn/style-dictionary/blob/master/lib/common/formats.js) +These are the formats included in Style Dictionary by default, pulled from [lib/common/formats.js](https://github.com/amzn/style-dictionary/blob/main/lib/common/formats.js) Want a format? [You can request it here](https://github.com/amzn/style-dictionary/issues). @@ -143,6 +673,24 @@ You created a format and think it should be included? [Send us a PR](https://git Creates a CSS file with variable definitions based on the style dictionary + + + + + + + + + + + + + + +
ParamTypeDefaultDescription
optionsObject
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

+
+ **Example** ```css :root { @@ -197,12 +745,32 @@ $tokens: { ### scss/variables -Creates a SCSS file with variable definitions based on the style dictionary +Creates a SCSS file with variable definitions based on the style dictionary. + +Add `!default` to any variable by setting a `themeable: true` attribute in the token's definition. + + + + + + + + + + + + + + + +
ParamTypeDefaultDescription
optionsObject
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

+
**Example** ```scss $color-background-base: #f0f0f0; -$color-background-alt: #eeeeee; +$color-background-alt: #eeeeee !default; ``` * * * @@ -225,6 +793,24 @@ $content-icon-email: '\E001'; Creates a LESS file with variable definitions based on the style dictionary + + + + + + + + + + + + + + +
ParamTypeDefaultDescription
optionsObject
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

+
+ **Example** ```less @color-background-base: #f0f0f0; @@ -246,6 +832,19 @@ Creates a LESS file with variable definitions and helper classes for icons * * * +### stylus/variables + + +Creates a Stylus file with variable definitions based on the style dictionary + +**Example** +```stylus +$color-background-base= #f0f0f0; +$color-background-alt= #eeeeee; +``` + +* * * + ### javascript/module @@ -257,7 +856,7 @@ module.exports = { color: { base: { red: { - value: '#ff000' + value: '#ff0000' } } } @@ -266,6 +865,20 @@ module.exports = { * * * +### javascript/module-flat + + +Creates a CommonJS module with the whole style dictionary flattened to a single level. + +**Example** +```js +module.exports = { + "ColorBaseRed": "#ff0000" +} +``` + +* * * + ### javascript/object @@ -278,7 +891,7 @@ var StyleDictionary = { color: { base: { red: { - value: '#ff000' + value: '#ff0000' } } } @@ -353,11 +966,152 @@ export const ColorBackgroundAlt = '#fcfcfcfc'; * * * +### typescript/es6-declarations + + +Creates TypeScript declarations for ES6 modules + +```json +{ + "platforms": { + "ts": { + "transformGroup": "js", + "files": [ + { + "format": "javascript/es6", + "destination": "colors.js" + }, + { + "format": "typescript/es6-declarations", + "destination": "colors.d.ts" + } + ] + } + } +} +``` + +**Example** +```typescript +export const ColorBackgroundBase : string; +export const ColorBackgroundAlt : string; +``` + +* * * + +### typescript/module-declarations + + +Creates TypeScript declarations for CommonJS module + +```json +{ + "platforms": { + "ts": { + "transformGroup": "js", + "files": [ + { + "format": "javascript/module", + "destination": "colors.js" + }, + { + "format": "typescript/module-declarations", + "destination": "colors.d.ts" + } + ] + } + } +} +``` + +**Example** +```typescript +export default tokens; +declare interface DesignToken { value: string; name?: string; path?: string[]; comment?: string; attributes?: any; original?: any; } +declare const tokens: { + "color": { + "red": DesignToken + } +} +``` + +As you can see above example output this does not generate 100% accurate d.ts. +This is a compromise between of what style-dictionary can do to help and not bloating the library with rarely used dependencies. + +Thankfully you can extend style-dictionary very easily: + +```js +const JsonToTS = require('json-to-ts'); +StyleDictionaryPackage.registerFormat({ + name: 'typescript/accurate-module-declarations', + formatter: function(dictionary) { + return 'declare const root: RootObject\n' + + 'export default root\n' + + JsonToTS(dictionary.properties).join('\n'); + }, +}); +``` + +* * * + +### android/resources + + +Creates a [resource](https://developer.android.com/guide/topics/resources/providing-resources) xml file. It is recommended to use a filter with this format +as it is generally best practice in Android development to have resource files +organized by type (color, dimension, string, etc.). However, a resource file +with mixed resources will still work. + +This format will try to use the proper resource type for each token based on +the category (color => color, size => dimen, etc.). However if you want to +force a particular resource type you can provide a 'resourceType' attribute +on the file configuration. You can also provide a 'resourceMap' if you +don't use Style Dictionary's built-in CTI structure. + + + + + + + + + + + + + + + +
ParamTypeDefaultDescription
optionsObject
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

+
+ +**Example** +```xml + + + #fffaf3f2 + #fff0cccc + 14sp +``` + +* * * + ### android/colors Creates a color resource xml file with all the colors in your style dictionary. +It is recommended to use the 'android/resources' format with a custom filter +instead of this format: + +```javascript +format: 'android/resources', +filter: { + attributes: { category: 'color' } +} +``` + **Example** ```xml @@ -374,6 +1128,16 @@ Creates a color resource xml file with all the colors in your style dictionary. Creates a dimen resource xml file with all the sizes in your style dictionary. +It is recommended to use the 'android/resources' format with a custom filter +instead of this format: + +```javascript +format: 'android/resources', +filter: { + attributes: { category: 'size' } +} +``` + **Example** ```xml @@ -390,6 +1154,16 @@ Creates a dimen resource xml file with all the sizes in your style dictionary. Creates a dimen resource xml file with all the font sizes in your style dictionary. +It is recommended to use the 'android/resources' format with a custom filter +instead of this format: + +```javascript +format: 'android/resources', +filter: { + attributes: { category: 'size' } +} +``` + **Example** ```xml @@ -405,7 +1179,17 @@ Creates a dimen resource xml file with all the font sizes in your style dictiona Creates a resource xml file with all the integers in your style dictionary. It filters your -style properties by `prop.attributes.category === 'time'` +design tokens by `token.attributes.category === 'time'` + +It is recommended to use the 'android/resources' format with a custom filter +instead of this format: + +```javascript +format: 'android/resources', +filter: { + attributes: { category: 'time' } +} +``` **Todo** @@ -426,7 +1210,17 @@ style properties by `prop.attributes.category === 'time'` Creates a resource xml file with all the strings in your style dictionary. Filters your -style properties by `prop.attributes.category === 'content'` +design tokens by `token.attributes.category === 'content'` + +It is recommended to use the 'android/resources' format with a custom filter +instead of this format: + +```javascript +format: 'android/resources', +filter: { + attributes: { category: 'content' } +} +``` **Example** ```xml @@ -439,10 +1233,52 @@ style properties by `prop.attributes.category === 'content'` * * * +### compose/object + + +Creates a Kotlin file for Compose containing an object with a `val` for each property. + + + + + + + + + + + + + + + + + + + +
ParamTypeDefaultDescription
classNameString

The name of the generated Kotlin object

+
packageNameString

The package for the generated Kotlin object

+
optionsObject
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

+
+ +**Example** +```kotlin +package com.example.tokens; + +import androidx.compose.ui.graphics.Color + +object StyleDictionary { + val colorBaseRed5 = Color(0xFFFAF3F2) +} +``` + +* * * + ### ios/macros -Creates an Objective-C header file with macros for style properties +Creates an Objective-C header file with macros for design tokens **Example** ```objectivec @@ -568,10 +1404,30 @@ Creates an Objective-C implementation file of strings Creates a Swift implementation file of a class with values -**Todo** - -- Add example and usage + + + + + + + + + + + + + + +
ParamTypeDefaultDescription
optionsObject
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

+
+**Example** +```swift +public class StyleDictionary { + public static let colorBackgroundDanger = UIColor(red: 1.000, green: 0.918, blue: 0.914, alpha:1) +} +``` * * * @@ -610,7 +1466,7 @@ Creates a JSON file of the style dictionary. "color": { "base": { "red": { - "value": "#ff000" + "value": "#ff0000" } } } @@ -649,7 +1505,7 @@ Creates a JSON nested file of the style dictionary. { "color": { "base": { - "red": "#ff000" + "red": "#ff0000" } } } @@ -665,7 +1521,7 @@ Creates a JSON flat file of the style dictionary. **Example** ```json { - "color-base-red": "#ff000" + "color-base-red": "#ff0000" } ``` @@ -718,6 +1574,24 @@ the sketchpalette plugin. To use this you should use the Creates a Dart implementation file of a class with values + + + + + + + + + + + + + + +
ParamTypeDefaultDescription
optionsObject
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

+
+ **Example** ```dart import 'package:flutter/material.dart'; diff --git a/docs/index.html b/docs/index.html index c78a4a0eb..b8b4e17c1 100644 --- a/docs/index.html +++ b/docs/index.html @@ -38,6 +38,7 @@ + diff --git a/docs/package_structure.md b/docs/package_structure.md index e84f69c91..44e55990d 100644 --- a/docs/package_structure.md +++ b/docs/package_structure.md @@ -1,12 +1,12 @@ # Package Structure -Style dictionaries are configuration driven. A style dictionary package must contain a configuration and reference a path to property files. You can optionally include assets in your package. +Style dictionaries are configuration driven. A style dictionary package must contain a configuration and reference a path to design token files. You can optionally include assets in your package. Here is a basic example of what a style dictionary package looks like. ``` ├── config.json -├── properties/ +├── tokens/ │ ├── size/ │ ├── font.json │ ├── color/ @@ -21,7 +21,7 @@ Here is a basic example of what a style dictionary package looks like. | Name | Description | | :--- | :--- | | config.json | This is where the [configuration](config.md) for the style dictionary lives, where you define what happens when Style Dictionary runs | -| property files | [Properties](properties.md) are saved as a collection of JSON or JS module files. We usually keep them in a `properties` directory, but you can put them wherever you like - the path to them should be in the `source` attribute on your `config.json` file. | +| design token files | [Design tokens](tokens.md) are saved as a collection of JSON or JS module files. You can put them wherever you like - the path to them should be in the `source` attribute on your `config.json` file. | | assets (optional) | Assets can be included in your style dictionary package, allowing you to keep them in your style dictionary as a single source of truth. | diff --git a/docs/parsers.md b/docs/parsers.md new file mode 100644 index 000000000..465b822d9 --- /dev/null +++ b/docs/parsers.md @@ -0,0 +1,71 @@ +# Parsers + +Starting in version 3.0, you can define custom parsers to parse design token files. This allows you to define your design token files in *any* language you like as long as you can write a parser for it. + +A custom parser matches design token files based on a file path regular expression. It will get the contents of a file as a string and should return an object of the data. + +Custom parsers can be used to keep design token files in other languages like YAML, but they can also be used to add extra metadata or modify the design tokens themselves before they get to Style Dictionary. For example, you could modify the token object based on its file path or programmatically generate tokens based on the data in certain files. + + +---- + + +## Parser structure + +A parser has 2 parts: a pattern which is a regular expression to match against a file path, and a parse function which takes the file path and contents of the file and is expected to return a function. + +```javascript +const myParser = { + pattern: /\.json$/, + parse: ({ filePath, contents }) => { + return JSON.parse(contents); + } +} +``` + + +---- + + +## Using parsers + +First you will need to tell Style Dictionary about your parser. You can do this in two ways: + +1. Using the `.registerParser` method +1. Inline in the [configuration](config.md) + +### .registerParser + +```javascript +const StyleDictionary = require('style-dictionary'); + +StyleDictionary.registerParser({ + pattern: /\.json$/, + parse: ({ filePath, contents }) => { + return JSON.parse(contents); + } +}); +``` + +### Inline + +```javascript +module.exports = { + parsers: [{ + pattern: /\.json$/, + parse: ({ filePath, contents }) => { + return JSON.parse(contents); + } + }], + // ... the rest of the configuration +} +``` + + +---- + + +## Parser examples + +* [More in-depth custom parser example](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-parser) +* [Using custom parsers to support YAML design token files](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/yaml-tokens) diff --git a/docs/properties.md b/docs/properties.md deleted file mode 100644 index 81f99b28b..000000000 --- a/docs/properties.md +++ /dev/null @@ -1,112 +0,0 @@ -# Properties - -> Synonyms: design tokens, design variables, design constants, atoms - -Style properties are stored in a collection of JSON or JS module files. We usually keep them in a `properties` directory, but you can put them wherever you like, they need to be referenced in the `source` attribute on your `config.json` file. - -A property is a collection of attributes that describe any fundamental/atomic visual style. Each attribute is a `key:value` pair. A property name and its value are considered a design token (or design variable/constant/atom). - -![Terminology for different parts of a JSON property](assets/property-definitions.png) - -A property is transformed for use in different platforms, languages, and contexts. A simple example is color. A color can be represented in many ways, all of these are the same color: `#ffffff`, `rgb(255,255,255)`, `hsl(0,0,1)`. - -A property file organizes properties in a structured way for quick access. Property files are organized as a deep object with the leaf nodes being the style key:value pairs. - -## Examples - -```json -{ - "color": { - "font": { - "base": { "value": "#111111" }, - "secondary": { "value": "#333333" }, - "tertiary": { "value": "#666666" }, - "inverse": { - "base": { "value": "#ffffff" } - } - } - } -} -``` - -Any object in the JSON that has a `value` attribute on it is a property; in this example there are 4 style properties: `color.font.base`, `color.font.secondary`, `color.font.tertiary`, and `color.font.inverse.base`. - -For any properties you wish to output, the "value" attribute is required. This provides the data that will be used throughout the build process (and ultimately used for styling in your deliverables). You can optionally include any custom attributes you would like (e.g. "comment" with a string or "metadata" as an object with its own attributes). - -### Example Property -Here you can see a property of "size.font.small" with two attributes: -1. the required "value" attribute, set to "10" -1. the optional "comment" attribute (The "comment" attribute is treated in a special way - the comment will appear in output files when the output format supports comments.) -```json -{ - "size": { - "font": { - "small" : { - "value": "10", - "comment": "the smallest font allowed for readability" - }, - } - } -} -``` - -### Multiple Properties -Multiple properties in a single file are simple to read and understand using the recommended [`Category / Type / Item (CTI)`](#category-type-item) method -```json -{ - "size": { - "font": { - "small" : { "value": "10" }, - "medium": { "value": "16" }, - "large" : { "value": "24" }, - } - } -} -``` - -### Attribute reference / alias -You can reference (alias) existing values by using the dot-notation object path (the fully articulated property name) in brackets. Note that this only applies to values; referencing a non-value property will cause unexpected results in your output. -```json -{ - "size": { - "font": { - "small" : { "value": "10" }, - "medium": { "value": "16" }, - "large" : { "value": "24" }, - "base" : { "value": "{size.font.medium.value}" } - } - } -} -``` -See more in the advanced [referencing-aliasing example](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/referencing_aliasing). - -## Category / Type / Item - -This CTI structure is not required. However, we feel this classification structure makes the most sense semantically. - -Style properties are organized into a hierarchical tree structure with 'category' defining the primitive nature of the property. For example, we have the color category and every property underneath is always a color. As you proceed down the tree, you get more specific about what that color is. Is it a background color, a text color, or a border color? What kind of text color is it? You get the point. It's like the animal kingdom classification: - -![](assets/cti.png) - -Now you can structure your property JSON files like simple objects: - -```json -{ - "size": { - "font": { - "base": { "value": "16" }, - "large": { "value": "20" } - } - } -} -``` - -The CTI is implicit in the structure, the category is 'size' and the type is 'font', and there are 2 properties 'base' and 'large'. - -Structuring style properties in this manner gives us consistent naming and accessing of these properties. You don't need to remember if it is `button_color_error` or `error_button_color`, it is `color_background_button_error`! - -You can organize and name your style properties however you want, **there are no restrictions**. But there are a good amount of helpers if you do use this structure, like the 'attribute/cti' transform which adds attributes to the property of its CTI based on the path in the object. There are a lot of names transforms as well for when you want a flat structure like for Sass variables. - -Also, the CTI structure provides a good mechanism to target transforms for specific kinds of properties. All of the transforms provided by the framework use the CTI structure to know if it should be applied. For instance, the 'color/hex' transform only applies to properties of the category 'color'. - ----- diff --git a/docs/quick_start.md b/docs/quick_start.md index 527637512..04df150b3 100644 --- a/docs/quick_start.md +++ b/docs/quick_start.md @@ -1,28 +1,33 @@ # Quick Start ## Installation + *Note that you must have [node (and npm) installed](https://www.npmjs.com/get-npm) before you can follow this guide.* If you want to use the CLI, you can install it globally via npm: + ```bash $ npm install -g style-dictionary ``` Or you can install it like a normal npm dependency. Style Dictionary is a build tool, and you are most likely to use it as a dev dependency: + ```bash $ npm install -D style-dictionary ``` - ## Creating a New Project + The CLI comes with some starter code to get a new project started easily. + ```bash $ mkdir MyStyleD $ cd MyStyleD $ style-dictionary init basic ``` -This command will copy over the example files found in the [basic example](https://github.com/amzn/style-dictionary/tree/master/examples/basic) in this repo and then run the `style-dictionary build` command to generate the build artifacts. You should see something like this output: +This command will copy over the example files found in the [basic example](https://github.com/amzn/style-dictionary/tree/main/examples/basic) in this repo and then run the `style-dictionary build` command to generate the build artifacts. You should see something like this output: + ``` Copying starter files... @@ -38,6 +43,10 @@ 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 @@ -56,7 +65,7 @@ Pat yourself on the back, you built your first style dictionary! Take a look at ``` ├── README.md ├── config.json -├── properties/ +├── tokens/ │ ├── color/ │ ├── base.json │ ├── font.json @@ -66,6 +75,9 @@ Pat yourself on the back, you built your first style dictionary! Take a look at │ ├── android/ │ ├── font_dimens.xml │ ├── colors.xml +│ ├── compose/ +│ ├── StyleDictionaryColor.kt +│ ├── StyleDictionarySize.kt │ ├── scss/ │ ├── _variables.scss │ ├── ios/ @@ -104,6 +116,31 @@ If you open `config.json` you will see there are 3 platforms defined: scss, andr
``` +**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 $color-base-gray-light: #cccccc; @@ -154,15 +191,15 @@ $size-font-base: 1rem; ``` Pretty nifty! This shows a few things happening: -1. The build system does a deep merge of all the property JSON files defined in the `source` attribute of `config.json`. This allows you to split up the property 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 style property values. `{size.font.medium.value}` is resolved properly. -1. The build system handles references to property values in other files as well (as you can see in `properties/color/font.json`). +1. The build system does a deep merge of all the design token files defined in the `source` attribute of `config.json`. This allows you to split up the design token 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}` is resolved properly. +1. The build system handles references to design token values in other files as well (as you can see in `tokens/color/font.json`). 1. Values are transformed specifically for each platform. ## Making a change -Now let's make a change and see how that affects things. Open up `properties/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. Now: +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. Now: **Android** ```xml @@ -178,6 +215,18 @@ Now let's make a change and see how that affects things. Open up `properties/col #ffcccccc ``` +```kotlin +object StyleDictionaryColor { + val colorBaseGrayDark = Color(0xff000000) + 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) +} +``` ```scss $color-base-gray-light: #cccccc; $color-base-gray-medium: #999999; @@ -212,7 +261,9 @@ Call this in the root directory of your project, which must include a [configura More detailed information about [using the Style Dictionary CLI is available here](using_the_cli.md). ### Node + You can also use the style dictionary build system in node if you want to [extend](extending.md) the functionality or use it in another build system like Grunt or Gulp. + ```javascript const StyleDictionary = require('style-dictionary').extend('config.json'); @@ -220,9 +271,10 @@ StyleDictionary.buildAllPlatforms(); ``` The `.extend()` method is an overloaded method that can also take a [configuration](config.md) object. + ```javascript const StyleDictionary = require('style-dictionary').extend({ - source: ['properties/**/*.json'], + source: ['tokens/**/*.json'], platforms: { scss: { transformGroup: 'scss', diff --git a/docs/tokens.md b/docs/tokens.md new file mode 100644 index 000000000..7c2c64c5b --- /dev/null +++ b/docs/tokens.md @@ -0,0 +1,398 @@ +# Design Tokens + +> Synonyms: style properties, design variables, design constants, atoms + +Design tokens are the platform-agnostic way to define the input for Style Dictionary. A design token is a collection of attributes that describe any fundamental/atomic visual style. Each attribute is a key-value pair. + +![Terminology for different parts of a JSON property](assets/property-definitions.png) + +A design token is transformed for use in different platforms, languages, and contexts. A simple example is color. A color can be represented in many ways, all of these are the same color: `#ffffff`, `rgb(255,255,255)`, `hsl(0,0,1)`. + +A collection of design tokens which are organized in a nested object make the Style Dictionary. Here is an example of design tokens written for Style Dictionary: + +```json +{ + "color": { + "font": { + "base": { "value": "#111111" }, + "secondary": { "value": "#333333" }, + "tertiary": { "value": "#666666" }, + "inverse": { + "base": { "value": "#ffffff" } + } + } + } +} +``` + +Any node in the object that has a `value` attribute on it is a design token. In this example there are 4 style design tokens: `color.font.base`, `color.font.secondary`, `color.font.tertiary`, and `color.font.inverse.base`. + +## Design token attributes + +For any design tokens you wish to output, the "value" attribute is required. This provides the data that will be used throughout the build process (and ultimately used for styling in your deliverables). You can optionally include any custom attributes you would like (e.g. "comment" with a string or "metadata" as an object with its own attributes). + +| Attribute | Type | Description | +| :--- | :--- | :--- | +| value | Any | The value of the design token. This can be any type of data, a hex string, an integer, a file path to a file, even an object or array. +| comment | String (optional) | The comment attribute will show up in a code comment in output files if the format supports it. +| themeable | Boolean (optional) | This is used in formats that support override-able or themable values like the `!default` flag in Sass. +| name | String (optional) | Usually the name for a design token is generated with a [name transform](transforms.md#transform-types), but you can write your own if you choose. By default Style Dictionary will add a default name which is the key of the design token object. +| attributes | Object (optional) | Extra information about the design token you want to include. [Attribute transforms](transforms.md#transform-types) will modify this object so be careful + +You can add any attributes or data you want in a design token and Style Dictionary will pass it along to transforms and formats. For example, you could add a `deprecated` flag like in [this example](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/tokens-deprecation). Other things you can do is add documentation information about each design token or information about color contrast. + +### Default design token metadata + +Style Dictionary adds some default metadata on each design token that helps with transforms and formats. Here is what Style Dictionary adds onto each design token: + +| Attribute | Type | Description | +| :--- | :--- | :--- | +| name | String | A default name of the design token that is set to the key of the design token. This is only added if you do not provide one. +| path | Array[String] | The object path of the design token. `color: { background: { primary: { value: "#fff" } } }` will have a path of `['color','background', 'primary']`. +| original | Object | A pristine copy of the original design token object. This is to make sure transforms and formats always have the unmodified version of the original design token. +| filePath | String | The file path of the file the token is defined in. This file path is derived from the `source` or `include` file path arrays defined in the [configuration](config.md). +| isSource | Boolean | If the token is from a file defined in the `source` array as opposed to `include` in the [configuration](config.md). + +Given this configuration: + +```json5 +{ + "source": ["tokens/**/*.json"] + //... +} +``` + +This design token: + +```json5 +// tokens/color/background.json +{ + "color": { + "background": { + "primary": { "value": "#fff" } + } + } +} +``` + +becomes: + +```json5 +{ + "color": { + "background": { + "primary": { + "name": "primary", + "value": "#fff", + "path": ["color","background","primary"], + "original": { + "value": "#fff" + }, + "filePath": "tokens/color/background.json", + "isSource": true + } + } + } +} +``` + + +---- + + +## Referencing / Aliasing + +You can reference (alias) existing values by using the dot-notation object path (the fully articulated design token name) in curly brackets. Note that this only applies to values; referencing a non-value design token will cause unexpected results in your output. + +```json +{ + "size": { + "font": { + "small" : { "value": "10" }, + "medium": { "value": "16" }, + "large" : { "value": "24" }, + "base" : { "value": "{size.font.medium.value}" } + } + } +} +``` + +See more in the advanced [referencing-aliasing example](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/referencing_aliasing). + + +---- + + +## Defining design tokens + +Design token files can included inline in the configuration, or be written in separate files. Style Dictionary supports these languages for design token files: + +* JSON +* [JSON5](https://json5.org) +* CommonJS modules +* Potentially any language with [custom parsers](#customfileparsers) + +Tokens can be defined *inline* in the Style Dictionary configuration, or in files. You can add a `tokens` object to your Style Dictionary configuration like this: + +```javascript +// config.js +module.exports = { + tokens: { + color: { + background: { + primary: { value: "#fff" } + } + } + }, + platforms: { + //... + } +} +``` + +Generally you will have too many design tokens to include them all inline, so you can separate them out into their own files. You can tell Style Dictionary where to find your design token files with the `source` and `include` attributes in the configuration like this: + +```javascript +module.exports = { + include: [ + // you can list singular files: + `node_modules/my-other-style-dictionary/tokens.json` + ], + source: [ + // or use file path [globs](https://www.npmjs.com/package/glob) + // this says grab all files in the tokens directory with a .json extension + `tokens/**/*.json` + ] + // ... +} +``` + +**You can organize your design token files in any way as long as you can tell Style Dictionary where to find them.** The directory and file structure of design token files does not have any effect on the object structure of the tokens because Style Dictionary does a deep merge on all design token files. Separating tokens into files and folders is to make the authoring experience cleaner and more flexible. + +### Collision warnings + +Style Dictionary takes all the files it finds in the include and source arrays and performs a deep merge on them. It will first add files in the include array, in order, and then the source array in order. Later files will take precedence. For example if you defined 2 source files like this: + +```javascript +module.exports = { + source: [ + `tokens.json`, + `tokens2.json` + ] +} +``` + +```json5 +// tokens.json +{ + "color": { + "background": { + "primary": { "value": "#fff" }, + "secondary": { "value": "#ccc" } + } + } +} +``` + +```json5 +// tokens2.json +{ + "color": { + "background": { + "primary": { "value": "#eee" }, + "tertiary": { "value": "#999" } + } + } +} +``` + +The resulting merged dictionary would be: + +```json5 +{ + "color": { + "background": { + "primary": { "value": "#eee" }, + "secondary": { "value": "#ccc" }, + "tertiary": { "value": "#999" } + } + } +} +``` + +This example would show a warning in the console that you have a collision at `color.background.primary` because 2 source files defined the same design token. A file in source overriding a file in include will not show a warning because the intent is that you include files you want to potentially override. For example, if you had multiple brands and you wanted to share a default theme, you could include the default theme and then override certain parts. + +### CommonJS modules + +One way to write your design token files is to write them in Javascript rather than JSON. The only requirement for writing your source files in Javascript is to use a CommonJS module to export a plain object. For example: + +```javascript +module.exports = { + color: { + base: { + red: { value: '#ff0000' } + } + } +} +``` + +is equivalent to this JSON file: + +```json +{ + "color": { + "base": { + "red": { "value": "#ff0000" } + } + } +} +``` + +You might prefer authoring your design token files in Javascript because it can be a bit more friendly to read and write (don't have to quote keys, can leave dangling commas, etc.). Writing your design token files as Javascript gives you more freedom to do complex things like generating many tokens based on code: + +```javascript +const Color = require('tinycolor2'); + +const baseColors = { + red: {h: 4, s: 62, v: 90}, + purple: {h: 262, s: 47, v: 65}, + blue: {h: 206, s: 70, v: 85}, + teal: {h: 178, s: 75, v: 80}, + green: {h: 119, s: 47, v: 73}, + yellow: {h: 45, s: 70, v: 95}, + orange: {h: 28, s: 76, v: 98}, + grey: {h: 240, s: 14, v: 35}, +} + +// Use a reduce function to take the array of keys in baseColor +// and map them to an object with the same keys. +module.exports = Object.keys(baseColors).reduce((ret, color) => { + return Object.assign({}, ret, { + [color]: { + // generate the shades/tints for each color + "20": { value: Color(baseColors[color]).lighten(30).toString()}, + "40": { value: Color(baseColors[color]).lighten(25).toString()}, + "60": { value: Color(baseColors[color]).lighten(20).toString()}, + "80": { value: Color(baseColors[color]).lighten(10).toString()}, + "100": { value: baseColors[color]}, + "120": { value: Color(baseColors[color]).darken(10).toString()}, + "140": { value: Color(baseColors[color]).darken(20).toString()} + } + }) +}, {}); +``` + +Take a look at the [this example](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/node-modules-as-config-and-properties) if you want to see a more in-depth example of using Javascript files as input. + +### Custom file parsers + +Starting in 3.0, you can define custom parsers to parse your source files. This allows you to author your design token files in other languages like [YAML](https://yaml.org/). Custom parsers run on certain input files based on a file path pattern regular expression (similar to how Webpack loaders work). The parser function gets the contents of the file and is expected to return an object of the data of that file for Style Dictionary to merge with the other input file data. + +```javascript +const StyleDictionary = require('style-dictionary'); + +StyleDictionary.registerParser({ + pattern: /.json$/, + parse: ({contents, filePath}) => { + return JSON.parse(contents); + } +}); +``` + +[Here is a complete custom file parser example](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-parser) + +[yaml-tokens example](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/yaml-tokens) + + +---- + + +## Design token structure + +You can structure your tokens any way you want. You could have a flat object rather than a nested one: + +```json +{ + "colorBackgroundPrimary": { "value": "#fff" }, + "sizePaddingLarge": { "value": 4 } +} +``` + +### Category / Type / Item + +**This structure is not required.** This is just one example of how to structure your design tokens. + +Design tokens are organized into a hierarchical tree structure with 'category' defining the primitive nature of the design token. For example, we have the color category and every design token underneath is always a color. As you proceed down the tree, you get more specific about what that color is. Is it a background color, a text color, or a border color? What kind of text color is it? You get the point. It's like the animal kingdom classification: + +![](assets/cti.png) + +Now you can structure your tokens in a nested object like this: + +```json +{ + "size": { + "font": { + "base": { "value": "16" }, + "large": { "value": "20" } + } + } +} +``` + +The CTI is implicit in the structure, the category is 'size' and the type is 'font', and there are 2 tokens 'base' and 'large'. + +Structuring design tokens in this manner gives us consistent naming and accessing of these tokens. You don't need to remember if it is `button_color_error` or `error_button_color`, it is `color_background_button_error`! + +You can organize and name your design tokens however you want, **there are no restrictions**. But there are a good amount of helpers if you do use this structure, like the 'attribute/cti' transform which adds attributes to the design token of its CTI based on the path in the object. There are a lot of names transforms as well for when you want a flat structure like for Sass variables. + +Also, the CTI structure provides a good mechanism to target transforms for specific kinds of tokens. All of the transforms provided by the framework use the CTI structure to know if it should be applied. For instance, the 'color/hex' transform only applies to tokens of the category 'color'. + +Here are the categories and types the built-in transforms and formats use: + +#### Category: color +Everything under this category is a color. You can further organize by background, font, border, etc. if you want. The built-ins only look for a category of `color` +* [`color/rgb`](transforms.md#colorrgb) +* [`color/hsl`](transforms.md#colorhsl) +* [`color/hsl-4`](transforms.md#colorhsl-4) +* [`color/hex`](transforms.md#colorhex) +* [`color/hex8`](transforms.md#colorhex8) +* [`color/hex8android`](transforms.md#colorhex8android) +* [`color/UIColor`](transforms.md#coloruicolor) +* [`color/UIColorSwift`](transforms.md#coloruicolorswift) +* [`color/css`](transforms.md#colorcss) +* [`color/sketch`](transforms.md#colorsketch) +* [`color/hex8flutter`](transforms.md#colorhex8flutter) + +#### Category: size +Most platforms any type of size is treated the same. On Android it is common to use SP for font sizes and DP for paddings and dimensions. +* [`size/sp`](transforms.md#sizesp) +* [`size/dp`](transforms.md#sizedp) +* [`size/object`](transforms.md#sizeobject) +* [`size/remToSp`](transforms.md#sizeremtosp) +* [`size/remToDp`](transforms.md#sizeremtodp) +* [`size/px`](transforms.md#sizepx) +* [`size/rem`](transforms.md#sizerem) +* [`size/remToPt`](transforms.md#sizeremtopt) +* [`size/swift/remToCGFloat`](transforms.md#sizeswiftremtocgfloat) +* [`size/remToPx`](transforms.md#sizeremtopx) +* [`size/pxToRem`](transforms.md#sizepxtorem) +* [`size/flutter/remToDouble`](transforms.md#sizeflutterremtodouble) + +#### Category: time +* [`time/seconds`](transforms.md#timeseconds) + +#### Category: asset +These should be file paths used for images and font files +* [`asset/base64`](transforms.md#assetbase64) +* [`asset/path`](transforms.md#assetpath) +* [`asset/objC/literal`](transforms.md#assetobjcliteral) +* [`asset/swift/literal`](transforms.md#assetswiftliteral) +* [`asset/flutter/literal`](transforms.md#assetflutterliteral) + +#### Category: content +These should be strings +* [`content/icon`](transforms.md#contenticon) +* [`content/quote`](transforms.md#contentquote) +* [`content/objC/literal`](transforms.md#contentobjcliteral) +* [`content/swift/literal`](transforms.md#contentswiftliteral) +* [`content/flutter/literal`](transforms.md#contentflutterliteral) diff --git a/docs/transform_groups.md b/docs/transform_groups.md index 9ad47b8e5..2b13eda73 100644 --- a/docs/transform_groups.md +++ b/docs/transform_groups.md @@ -10,7 +10,7 @@ You use transformGroups in your config file under platforms > [platform] > trans ```json { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "android": { "transformGroup": "android" @@ -23,7 +23,7 @@ You use transformGroups in your config file under platforms > [platform] > trans ## Pre-defined Transform groups -[lib/common/transformGroups.js](https://github.com/amzn/style-dictionary/blob/master/lib/common/transformGroups.js) +[lib/common/transformGroups.js](https://github.com/amzn/style-dictionary/blob/main/lib/common/transformGroups.js) ### web @@ -120,6 +120,21 @@ Transforms: [size/remToDp](transforms.md#sizeremtodp) +* * * + +### compose + + +Transforms: + +[attribute/cti](transforms.md#attributecti) +[name/cti/camel](transforms.md#namecticamel) +[color/composeColor](transforms.md#colorcomposecolor) +[size/compose/em](transforms.md#sizecomposeem) +[size/compose/remToSp](transforms.md#sizecomposeremtosp) +[size/compose/remToDp](transforms.md#sizecomposeremtodp) + + * * * ### ios @@ -167,7 +182,7 @@ Transforms: [size/swift/remToCGFloat](transforms.md#sizeswiftremtocgfloat) [font/swift/literal](transforms.md#fontswiftliteral) -This is to be used if you want to have separate files per category and you don't want the category (e.g., color) as the lead value in the name of the property (e.g., StyleDictionaryColor.baseText instead of StyleDictionary.colorBaseText). +This is to be used if you want to have separate files per category and you don't want the category (e.g., color) as the lead value in the name of the token (e.g., StyleDictionaryColor.baseText instead of StyleDictionary.colorBaseText). * * * @@ -211,7 +226,19 @@ Transforms: [asset/flutter/literal](transforms.md#assetflutterliteral) [font/flutter/literal](transforms.md#fontflutterliteral) -This is to be used if you want to have separate files per category and you don't want the category (e.g., color) as the lead value in the name of the property (e.g., StyleDictionaryColor.baseText instead of StyleDictionary.colorBaseText). +This is to be used if you want to have separate files per category and you don't want the category (e.g., color) as the lead value in the name of the token (e.g., StyleDictionaryColor.baseText instead of StyleDictionary.colorBaseText). + + +* * * + +### react-native + + +Transforms: + +[name/cti/camel](transforms.md#namecticamel) +[size/object](transforms.md#sizeobject) +[color/css](transforms.md#colorcss) * * * diff --git a/docs/transforms.md b/docs/transforms.md index 8337435d4..58b232dd3 100644 --- a/docs/transforms.md +++ b/docs/transforms.md @@ -4,14 +4,14 @@ EDIT scripts/handlebars/templates/api.hbs OR JSDOC COMMENT INSTEAD! --> # Transforms -Transforms are functions that transform a property - this enables each platform to consume the property in different ways. A simple example is changing pixel values to point values for iOS and dp or sp for Android. Transforms are applied in a non-destructive way thus each platform can transform the properties. Transforms are performed sequentially, therfore the order you use transforms matters. Transforms are used in your [configuration](config.md), and can be either [pre-defined transforms](transforms.md?id=defining-custom-transforms) supplied by Style Dictionary or [custom transforms](transforms.md?id=defining-custom-transforms). +Transforms are functions that modify a [token](tokens.md) so that it can be understood by a specific platform. It can modify the name, value, or attributes of a token - enabling each platform to use the design token in different ways. A simple example is changing pixel values to point values for iOS and dp or sp for Android. Transforms are isolated per platform; each platform begins with the same design token and makes the modifications it needs without affecting other platforms. The order you use transforms matters because transforms are performed sequentially. Transforms are used in your [configuration](config.md), and can be either [pre-defined transforms](transforms.md?id=defining-custom-transforms) supplied by Style Dictionary or [custom transforms](transforms.md?id=defining-custom-transforms). ## Using Transforms You use transforms in your config file under platforms > [platform] > transforms ```json { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "android": { "transforms": ["attribute/cti", "name/cti/kebab", "color/hex", "size/rem"] @@ -20,25 +20,73 @@ You use transforms in your config file under platforms > [platform] > transforms } ``` -A transform consists of 4 parts: type, name, matcher, and transformer. Transforms are run on all properties where the matcher returns true. *NOTE: if you don't provide a matcher function, it will match all properties.* +A transform consists of 4 parts: type, name, matcher, and transformer. Transforms are run on all design tokens where the matcher returns true. *NOTE: if you don't provide a matcher function, it will match all tokens.* ## Transform Types There are 3 types of transforms: attribute, name, and value. -**Attribute:** An attribute transform adds to the attributes object on a property. This is for including any meta-data about a property such as it's CTI or other information. +**Attribute:** An attribute transform adds to the attributes object on a design token. This is for including any meta-data about a design token such as it's CTI or other information. -**Name:** A name transform transform the name of a property. You should really only be apply one name transformer because they will override each other if you use more than one. +**Name:** A name transform transform the name of a design token. You should really only be apply one name transformer because they will override each other if you use more than one. -**Value:** The value transform is the most important as this is the one that changes the representation of the value. Colors can be turned into hex values, rgb, hsl, hsv, etc. Value transforms have a matcher function that filter which properties that transform runs on. This allows us to only run a color transform on only the colors and not every property. +**Value:** The value transform is the most important as this is the one that changes the representation of the value. Colors can be turned into hex values, rgb, hsl, hsv, etc. Value transforms have a matcher function that filter which tokens that transform runs on. This allows us to only run a color transform on only the colors and not every design token. ## Defining Custom Transforms -You can define custom transforms with the [`registerTransform`](api.md#registertransform). +You can define custom transforms with the [`registerTransform`](api.md#registertransform). Style Dictionary adds some [default metadata](tokens.md?id=default-design-token-metadata) to each design token to provide context that may be useful for some transforms. + +## Transitive Transforms +Starting in version 3.0, you can define transitive transforms which allow you to transform a referenced value. Normally, value transforms only transform non-referenced values and because transforms happen before references are resolved, the transformed value is then used to resolve references. + +```javascript +const StyleDictionary = require('style-dictionary'); + +StyleDictionary.registerTransform({ + type: `value`, + transitive: true, + name: `myTransitiveTransform`, + matcher: (token) => {}, + transformer: (token) => { + // token.value will be resolved and transformed at this point + } +}) +``` + +There is one thing to be mindful of with transitive transforms. The token's value will be resolved and *transformed* already at the time the transitive transform. What happens is Style Dictionary will transform and resolve values iteratively. First it will transform any non-referenced values, then it will resolve any references to non-referenced values, then it will try to transform any non-referenced values, and so on. Let's take a look at an example: + +```json +{ + "color": { + "red": { "value": "#f00" }, + "danger": { "value": "{color.red}" }, + "error": { "value": "{color.danger}" } + } +} +``` + +Style dictionary will first transform the value of `color.red`, then resolve `color.danger` to the transformed `color.red` value. Then it will transform `color.danger` and resolve `color.error` to the transformed `color.danger`. Finally, it will transform `color.error` and see that there is nothing left to transform or resolve. + +This allows you to modify a reference that modifies another reference. For example: + +```json +{ + "color": { + "red": { "value": "#f00" }, + "danger": { "value": "{color.red}", "darken": 0.75 }, + "error": { "value": "{color.danger}", "darken": 0.5 } + } +} +``` + +Using a custom transitive transform you could have `color.danger` darken `color.red` and `color.error` darken `color.danger`. The pre-defined transforms are *not transitive* to be backwards compatible with Style Dictionary v2 - an upgrade should not cause breaking changes. + +If you want to learn more about transitive transforms, take a look at the [transitive transforms example](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/transitive-transforms). + ## Pre-defined Transforms -[lib/common/transforms.js](https://github.com/amzn/style-dictionary/blob/master/lib/common/transforms.js) +[lib/common/transforms.js](https://github.com/amzn/style-dictionary/blob/main/lib/common/transforms.js) -> All the pre-defined transforms included use the [CTI structure](properties.md?id=category-type-item) for the match properties. If you structure your style properties differently you will need to write [custom transforms](transforms.md?id=defining-custom-transforms) or make sure the property CTIs are on the attributes of your properties. +> All the pre-defined transforms included use the [CTI structure](tokens.md?id=category-type-item) for matching tokens. If you structure your design tokens differently you will need to write [custom transforms](transforms.md?id=defining-custom-transforms) or make sure the proper CTIs are on the attributes of your design tokens. ### attribute/cti @@ -66,7 +114,7 @@ Adds: category, type, item, subitem, and state on the attributes object based on Adds: hex, hsl, hsv, rgb, red, blue, green. ```js -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns { "hex": "009688", @@ -158,7 +206,7 @@ Creates a snake case name. If you define a prefix on the platform in your config ### name/cti/constant -Creates a constant-style name based on the full CTI of the property. If you define a prefix on the platform in your config, it will prepend with your prefix +Creates a constant-style name based on the full CTI of the token. If you define a prefix on the platform in your config, it will prepend with your prefix ```js // Matches: all @@ -173,7 +221,7 @@ Creates a constant-style name based on the full CTI of the property. If you defi ### name/ti/constant -Creates a constant-style name on the type and item of the property. This is useful if you want to create different static classes/files for categories like `Color.BACKGROUND_BASE`. If you define a prefix on the platform in your config, it will prepend with your prefix. +Creates a constant-style name on the type and item of the token. This is useful if you want to create different static classes/files for categories like `Color.BACKGROUND_BASE`. If you define a prefix on the platform in your config, it will prepend with your prefix. ```js // Matches: all @@ -206,7 +254,7 @@ Creates a Pascal case name. If you define a prefix on the platform in your confi Transforms the value into an RGB string ```js -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: "rgb(0, 150, 136)" ``` @@ -220,7 +268,7 @@ Transforms the value into an RGB string Transforms the value into an HSL string or HSLA if alpha is present. Better browser support than color/hsl-4 ```js -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: "hsl(174, 100%, 29%)" "hsl(174, 100%, 29%, .5)" @@ -235,7 +283,7 @@ Transforms the value into an HSL string or HSLA if alpha is present. Better brow Transforms the value into an HSL string, using fourth argument if alpha is present. ```js -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: "hsl(174 100% 29%)" "hsl(174 100% 29% / .5)" @@ -250,7 +298,7 @@ Transforms the value into an HSL string, using fourth argument if alpha is prese Transforms the value into an 6-digit hex string ```js -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: "#009688" ``` @@ -264,7 +312,7 @@ Transforms the value into an 6-digit hex string Transforms the value into an 8-digit hex string ```js -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: "#009688ff" ``` @@ -278,12 +326,26 @@ Transforms the value into an 8-digit hex string Transforms the value into an 8-digit hex string for Android because they put the alpha channel first ```js -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: "#ff009688" ``` +* * * + +### color/composeColor + + +Transforms the value into a Color class for Compose + +```kotlin +// Matches: prop.attributes.category === 'color' +// Returns: +Color(0xFF009688) +``` + + * * * ### color/UIColor @@ -292,7 +354,7 @@ Transforms the value into an 8-digit hex string for Android because they put the Transforms the value into an UIColor class for iOS ```objectivec -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: [UIColor colorWithRed:0.114f green:0.114f blue:0.114f alpha:1.000f] ``` @@ -306,7 +368,7 @@ Transforms the value into an UIColor class for iOS Transforms the value into an UIColor swift class for iOS ```swift -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: UIColor(red: 0.667, green: 0.667, blue: 0.667, alpha:0.6) ``` @@ -320,7 +382,7 @@ UIColor(red: 0.667, green: 0.667, blue: 0.667, alpha:0.6) Transforms the value into a hex or rgb string depending on if it has transparency ```css -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: #000000 rgba(0,0,0,0.5) @@ -337,7 +399,7 @@ attributes that are floats from 0 - 1. This object is how Sketch stores colors. ```js -// Matches: prop.attributes.category === 'color' +// Matches: token.attributes.category === 'color' // Returns: { red: 0.5, @@ -356,7 +418,7 @@ colors. Transforms the value into a scale-independent pixel (sp) value for font sizes on Android. It will not scale the number. ```js -// Matches: prop.attributes.category === 'size' && prop.attributes.type === 'font' +// Matches: token.attributes.category === 'size' && token.attributes.type === 'font' // Returns: "10.0sp" ``` @@ -370,12 +432,31 @@ Transforms the value into a scale-independent pixel (sp) value for font sizes on Transforms the value into a density-independent pixel (dp) value for non-font sizes on Android. It will not scale the number. ```js -// Matches: prop.attributes.category === 'size' && prop.attributes.type !== 'font' +// Matches: token.attributes.category === 'size' && token.attributes.type !== 'font' // Returns: "10.0dp" ``` +* * * + +### size/object + + +Transforms the value into a usefull object ( for React Native support ) + +```js +// Matches: token.attributes.category === 'size' +// Returns: +{ + original: "10px", + number: 10, + decimal: 0.1, // 10 divided by 100 + scale: 160, // 10 times 16 +} +``` + + * * * ### size/remToSp @@ -384,7 +465,7 @@ Transforms the value into a density-independent pixel (dp) value for non-font si Transforms the value from a REM size on web into a scale-independent pixel (sp) value for font sizes on Android. It WILL scale the number by a factor of 16 (common base font size on web). ```js -// Matches: prop.attributes.category === 'size' && prop.attributes.type === 'font' +// Matches: token.attributes.category === 'size' && token.attributes.type === 'font' // Returns: "16.0sp" ``` @@ -395,10 +476,10 @@ Transforms the value from a REM size on web into a scale-independent pixel (sp) ### size/remToDp -Transforms the value from a REM size on web into a density-independent pixel (dp) value for font sizes on Android. It WILL scale the number by a factor of 16 (common base font size on web). +Transforms the value from a REM size on web into a density-independent pixel (dp) value for font sizes on Android. It WILL scale the number by a factor of 16 (or the value of 'basePxFontSize' on the platform in your config). ```js -// Matches: prop.attributes.category === 'size' && prop.attributes.type !== 'font' +// Matches: token.attributes.category === 'size' && token.attributes.type !== 'font' // Returns: "16.0dp" ``` @@ -412,7 +493,7 @@ Transforms the value from a REM size on web into a density-independent pixel (dp Adds 'px' to the end of the number. Does not scale the number ```js -// Matches: prop.attributes.category === 'size' +// Matches: token.attributes.category === 'size' // Returns: "10px" ``` @@ -426,7 +507,7 @@ Adds 'px' to the end of the number. Does not scale the number Adds 'rem' to the end of the number. Does not scale the number ```js -// Matches: prop.attributes.category === 'size' +// Matches: token.attributes.category === 'size' // Returns: "10rem" ``` @@ -437,24 +518,66 @@ Adds 'rem' to the end of the number. Does not scale the number ### size/remToPt -Scales the number by 16 (default web font size) and adds 'pt' to the end. +Scales the number by 16 (or the value of 'basePxFontSize' on the platform in your config) and adds 'pt' to the end. ```js -// Matches: prop.attributes.category === 'size' +// Matches: token.attributes.category === 'size' // Returns: "16pt" ``` +* * * + +### size/compose/remToSp + + +Transforms the value from a REM size on web into a scale-independent pixel (sp) value for font sizes in Compose. It WILL scale the number by a factor of 16 (common base font size on web). + +```kotlin +// Matches: prop.attributes.category === 'size' && prop.attributes.type === 'font' +// Returns: +"16.0.sp" +``` + + +* * * + +### size/compose/remToDp + + +Transforms the value from a REM size on web into a density-independent pixel (dp) value for font sizes in Compose. It WILL scale the number by a factor of 16 (or the value of 'basePxFontSize' on the platform in your config). + +```kotlin +// Matches: prop.attributes.category === 'size' && prop.attributes.type !== 'font' +// Returns: +"16.0.dp" +``` + + +* * * + +### size/compose/em + + +Adds the .em Compose extension to the end of a number. Does not scale the value + +```kotlin +// Matches: prop.attributes.category === 'size' && prop.attributes.type === 'font' +// Returns: +"16.0em" +``` + + * * * ### size/swift/remToCGFloat -Scales the number by 16 to get to points for Swift and initializes a CGFloat +Scales the number by 16 (or the value of 'basePxFontSize' on the platform in your config) to get to points for Swift and initializes a CGFloat ```js -// Matches: prop.attributes.category === 'size' +// Matches: token.attributes.category === 'size' // Returns: "CGFloat(16.00)"" ``` @@ -464,10 +587,10 @@ Scales the number by 16 to get to points for Swift and initializes a CGFloat ### size/remToPx -Scales the number by 16 (default web font size) and adds 'px' to the end. +Scales the number by 16 (or the value of 'basePxFontSize' on the platform in your config) and adds 'px' to the end. ```js -// Matches: prop.attributes.category === 'size' +// Matches: token.attributes.category === 'size' // Returns: "16px" ``` @@ -481,7 +604,7 @@ Scales the number by 16 (default web font size) and adds 'px' to the end. Takes a unicode point and transforms it into a form CSS can use. ```js -// Matches: prop.attributes.category === 'content' && prop.attributes.type === 'icon' +// Matches: token.attributes.category === 'content' && token.attributes.type === 'icon' // Returns: "'\\E001'" ``` @@ -495,7 +618,7 @@ Takes a unicode point and transforms it into a form CSS can use. Wraps the value in a single quoted string ```js -// Matches: prop.attributes.category === 'content' +// Matches: token.attributes.category === 'content' // Returns: "'string'" ``` @@ -509,7 +632,7 @@ Wraps the value in a single quoted string Wraps the value in a double-quoted string and prepends an '@' to make a string literal. ```objectivec -// Matches: prop.attributes.category === 'content' +// Matches: token.attributes.category === 'content' // Returns: **"string"**: ``` @@ -522,7 +645,7 @@ Wraps the value in a double-quoted string and prepends an '@' to make a string l Wraps the value in a double-quoted string to make a string literal. ```swift -// Matches: prop.attributes.category === 'content' +// Matches: token.attributes.category === 'content' // Returns: "string" ``` @@ -536,7 +659,7 @@ Wraps the value in a double-quoted string to make a string literal. Wraps the value in a double-quoted string and prepends an '@' to make a string literal. ```objectivec -// Matches: prop.attributes.category === 'font' +// Matches: token.attributes.category === 'font' // Returns: @"string" ``` @@ -549,7 +672,7 @@ Wraps the value in a double-quoted string and prepends an '@' to make a string l Wraps the value in a double-quoted string to make a string literal. ```swift -// Matches: prop.attributes.category === 'font' +// Matches: token.attributes.category === 'font' // Returns: "string" ``` @@ -562,7 +685,7 @@ Wraps the value in a double-quoted string to make a string literal. Assumes a time in miliseconds and transforms it into a decimal ```js -// Matches: prop.attributes.category === 'time' +// Matches: token.attributes.category === 'time' // Returns: "0.5s" ``` @@ -576,7 +699,7 @@ Assumes a time in miliseconds and transforms it into a decimal Wraps the value in a double-quoted string and prepends an '@' to make a string literal. ```js -// Matches: prop.attributes.category === 'asset' +// Matches: token.attributes.category === 'asset' // Returns: 'IyBlZGl0b3Jjb25maWcub3JnCnJvb3QgPSB0cnVlCgpbKl0KaW5kZW50X3N0eWxlID0gc3BhY2UKaW5kZW50X3NpemUgPSAyCmVuZF9vZl9saW5lID0gbGYKY2hhcnNldCA9IHV0Zi04CnRyaW1fdHJhaWxpbmdfd2hpdGVzcGFjZSA9IHRydWUKaW5zZXJ0X2ZpbmFsX25ld2xpbmUgPSB0cnVlCgpbKi5tZF0KdHJpbV90cmFpbGluZ193aGl0ZXNwYWNlID0gZmFsc2U=' ``` @@ -590,7 +713,7 @@ Wraps the value in a double-quoted string and prepends an '@' to make a string l Prepends the local file path ```js -// Matches: prop.attributes.category === 'asset' +// Matches: token.attributes.category === 'asset' // Returns: "path/to/file/asset.png" ``` @@ -604,7 +727,7 @@ Prepends the local file path Wraps the value in a double-quoted string and prepends an '@' to make a string literal. ```objectivec -// Matches: prop.attributes.category === 'asset' +// Matches: token.attributes.category === 'asset' // Returns: @"string" ``` @@ -617,7 +740,7 @@ Wraps the value in a double-quoted string and prepends an '@' to make a string l Wraps the value in a double-quoted string to make a string literal. ```swift -// Matches: prop.attributes.category === 'asset' +// Matches: token.attributes.category === 'asset' // Returns: "string" ``` @@ -629,7 +752,7 @@ Wraps the value in a double-quoted string to make a string literal. Transforms the value into a Flutter Color object using 8-digit hex with the alpha chanel on start ```js - // Matches: prop.attributes.category === 'color' + // Matches: token.attributes.category === 'color' // Returns: Color(0xFF00FF5F) ``` @@ -643,7 +766,7 @@ Transforms the value into a Flutter Color object using 8-digit hex with the alph Wraps the value in a double-quoted string to make a string literal. ```dart -// Matches: prop.attributes.category === 'content' +// Matches: token.attributes.category === 'content' // Returns: "string" ``` @@ -656,7 +779,7 @@ Wraps the value in a double-quoted string to make a string literal. Wraps the value in a double-quoted string to make a string literal. ```dart -// Matches: prop.attributes.category === 'asset' +// Matches: token.attributes.category === 'asset' // Returns: "string" ``` @@ -669,7 +792,7 @@ Wraps the value in a double-quoted string to make a string literal. Wraps the value in a double-quoted string to make a string literal. ```dart -// Matches: prop.attributes.category === 'font' +// Matches: token.attributes.category === 'font' // Returns: "string" ``` @@ -679,10 +802,10 @@ Wraps the value in a double-quoted string to make a string literal. ### size/flutter/remToDouble -Scales the number by 16 to get to points for Flutter +Scales the number by 16 (or the value of 'basePxFontSize' on the platform in your config) to get to points for Flutter ```dart -// Matches: prop.attributes.category === 'size' +// Matches: token.attributes.category === 'size' // Returns: 16.00 ``` diff --git a/docs/using_the_cli.md b/docs/using_the_cli.md index 37ba9e143..692ec7b51 100644 --- a/docs/using_the_cli.md +++ b/docs/using_the_cli.md @@ -4,74 +4,104 @@ The Style Dictionary command line interface (CLI) provides an executable system # Installation + To use the CLI, you can install it globally via npm: + ```bash $ npm install -g style-dictionary ``` +Most of the time you will want to install Style Dictionary as a dev dependency in your NPM package. The reason to have it as a dev dependency rather than a regular dependency is that Style Dictionary is a build tool rather than a runtime tool because it is used to *generate* files rather than used directly in an application. + +```bash +$ npm install --save-dev style-dictionary +``` + +In your `package.json` file you can add an NPM script that runs Style Dictionary: + +```json + "scripts": { + "build": "style-dictionary build" + } +``` + # CLI Quick Start -This will create a new folder called 'quick-start' and populate it with a Style Dictionary configuration and properties. + +This will create a new folder called 'quick-start' and populate it with a Style Dictionary configuration and tokens. + ```bash $ mkdir quick-start && cd quick-start $ style-dictionary init basic ``` -You can then modify the properties in the properties directory and run the build command below. See the changes in the output generated in the build folder. + +You can then modify the design tokens in the tokens directory and run the build command below. See the changes in the output generated in the build folder. + ```bash $ style-dictionary build ``` - # Commands + The CLI provides three basic commands: -* [build](using_the_cli.md?id=build) Builds a style dictionary package from the current directory. -* [clean](using_the_cli.md?id=clean) Removes files specified in the config of the style dictionary package of the current directory. -* [init](using_the_cli.md?id=init) Generates a starter style dictionary + +* [build](using_the_cli.md?id=build) Builds a style dictionary package from the current directory. +* [clean](using_the_cli.md?id=clean) Removes files specified in the config of the style dictionary package of the current directory. +* [init](using_the_cli.md?id=init) Generates a starter style dictionary These commands can be run using: + ```bash $ style-dictionary [command] [options] ``` +## build -# build Builds a style dictionary package from the current directory. Usage: + ```bash $ style-dictionary build [options] ``` + Options: + | Name | Usage | Description | | :--- | :--- | :--- | | Configuration Path | -c , --config | Set the path to the configuration file. Defaults to './config.json'. | | Platform | -p , --platform | Only build a specific platform. If not supplied, builds all platform found in the configuration file. | +## clean -# clean Removes files and folders generated by a previously run 'build' command. Usage: + ```bash $ style-dictionary clean [options] ``` + Options: + | Name | Usage | Description | | :--- | :--- | :--- | | Configuration Path | -c , --config | Set the path to the configuration file. Defaults to './config.json'. | | Platform | -p , --platform | Only clean a specific platform. If not supplied, cleans all platform found in the configuration file. | +## init -# init Generates a starter style dictionary, based on the supplied example type. Usage: + ```bash $ style-dictionary init ``` + Where example-type is one of: * `basic` * `complete` - +## version -# Version To see what version of Style Dictionary you have, run this command: + ```bash $ style-dictionary --version ``` diff --git a/docs/using_the_npm_module.md b/docs/using_the_npm_module.md index 2b138af17..de69fec8a 100644 --- a/docs/using_the_npm_module.md +++ b/docs/using_the_npm_module.md @@ -2,28 +2,52 @@ The Style Dictionary npm module exposes an [API](api.md) to interact with style dictionaries. +## Installation -# Installation To use the npm module, install it like a normal npm dependency. You are most likely going to want to save it as a dev dependency (The -D option) because it's a build tool: + ```bash $ npm install -D style-dictionary ``` +## NPM Module Quick Start -# NPM Module Quick Start To use the style dictionary build system in node, there are generally three steps: + 1. Require/import the StyleDictionary module 1. Extend the module with a configuration, creating the fully defined dictionary (importing all properties and intended outputs) 1. Call one or more build calls for various platforms +To use the NPM module you will need to update your NPM script that runs Style Dictionary from using the CLI command to running Node on the file you are using. + +```json5 +// package.json + "scripts": { + "build": "style-dictionary build" + } +``` + +becomes + +```json5 +// package.json + "scripts": { + "build": "node build.js" + } +``` + +Update "build.js" to the name of the file you created. + Using a JSON [configuration](config.md) file, that looks like this: + ```javascript const StyleDictionary = require('style-dictionary').extend('config.json'); StyleDictionary.buildAllPlatforms(); ``` -Alternatively, you can pass in a [configuration](config.md) object to the extend call. The buildAllPlatforms call is the same. +Alternatively, you can pass in a [configuration](config.md) object to the extend call. The `buildAllPlatforms` call is the same. + ```javascript const StyleDictionary = require('style-dictionary').extend({ source: ['properties/**/*.json'], @@ -43,6 +67,43 @@ const StyleDictionary = require('style-dictionary').extend({ StyleDictionary.buildAllPlatforms(); ``` +You can `extend` Style Dictionary multiple times and call `buildAllPlatforms` as many times as you need. This can be useful if you are creating nested (parent-child) themes with Style Dictionary. + +```javascript +const StyleDictionary = require('style-dictionary'); + +const styleDictionary = StyleDictionary.extend({ + // add custom formats/transforms +}); + +styleDictionary.extend({ + // ... +}).buildAllPlatforms(); + +styleDictionary.extend({ + // ... +}).buildAllPlatforms(); +``` + +Another way to do this is to loop over an array and apply different configurations to Style Dictionary: + +```javascript +const StyleDictionary = require('style-dictionary'); + +const brands = [`brand-1`, `brand-2`, `brand-3`]; +brands.forEach(brand => { + StyleDictionary.extend({ + include: [`tokens/default/**/*.json`], + source: [`tokens/${brand}/**/*.json`], + // ... + }).buildAllPlatforms(); +}); +``` + +The [multi-brand-multi-platform example](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/multi-brand-multi-platform) uses this method. + +---- + +## NPM Module API -# NPM Module API The [complete npm module API is documented here](api.md). diff --git a/docs/version_3.md b/docs/version_3.md index e4d7156d1..c21edbc65 100644 --- a/docs/version_3.md +++ b/docs/version_3.md @@ -47,7 +47,7 @@ Use cases this change opens up: * Combining values like using HSL for colors * Modifying aliases like making a color lighter or darker -Example (WIP): https://github.com/amzn/style-dictionary/pull/487 +Example: https://github.com/amzn/style-dictionary/tree/3.0/examples/advanced/transitive-transforms Thanks [@mfal](https://github.com/mfal)! @@ -117,8 +117,10 @@ Not all formats use the `outputReferences` option because that file format might * css/variables * scss/variables * less/variables +* compose/object * android/resources * ios-swift/class.swift +* ios-swift/enum.swift * flutter/class.dart If you have custom formats you can make use of this feature too! The `dictionary` object that is passed as an argument to the formatter function has 2 new methods on it: `usesReference()` and `getReference()` which you can use to get the reference name. Here is an example of that: @@ -143,6 +145,9 @@ StyleDictionary.registerFormat({ } }) ``` + +Example: https://github.com/amzn/style-dictionary/tree/3.0/examples/advanced/variables-in-outputs + ### Custom parser support https://github.com/amzn/style-dictionary/pull/429 @@ -152,8 +157,6 @@ We are pretty excited about this. Until now you could only define your design to * Example: https://github.com/amzn/style-dictionary/tree/3.0/examples/advanced/custom-parser * YAML example: https://github.com/amzn/style-dictionary/tree/3.0/examples/advanced/yaml-tokens -TODO: Fix README in example - ### Adding filePath and isSource entries on tokens @@ -193,7 +196,36 @@ We are adding 2 new pieces of metadata to each token: Thanks [@7studio](https://github.com/7studio)! -TODO: use filePath in error messages to help with debugging. +### Format helpers + +Style Dictionary comes with built-in formats to generate basic files like CSS, Sass, and Less variables. We know that we can't build formats to fit everyone's exact needs, so you can write your own formats to output exactly what you want. However, one common ask was to use 90% of a built-in format, but tweak small parts of it. Before 3.0, the only way to do that would be to copy and paste the format source code from Style Dictionary into your own custom format and then make your tweaks. + +In 3.0, we have added format helpers. Format helpers are functions that the built-in formats use for things like formatting each token definition line, sorting the tokens, and displaying a file header comment. These functions are now part of the public API, which you can access with StyleDictionary.formatHelpers. Format helpers should make it simple to build custom formats. + +```javascript +const StyleDictionary = require('style-dictionary'); + +const { formattedVariables } = StyleDictionary.formatHelpers; + +module.exports = { + format: { + myFormat: ({ dictionary, options, file }) => { + const { outputReferences } = options; + return formattedVariables({ + dictionary, + outputReferences, + formatting: { + prefix: '$', + separator: ':', + suffix: ';' + } + }); + } + } +} +``` + +Example: https://github.com/amzn/style-dictionary/tree/3.0/examples/advanced/format-helpers ### Updated format method arguments @@ -258,24 +290,75 @@ You might also notice a new part of the information sent to the formatter method Previously, there wasn't much convention around adding extra configuration at the platform and file-level for transforms, formats, and actions. We want to start correcting that a bit by using an `options` object at the file and platform level. +### Custom file headers + +When we started Style Dictionary, our intention was that the code it generates would not be checked into version control. To make that very apparent we added a code comment at the top of every built-in format that says it is a generated file with a timestamp of when it was generated. Over the years we have seen many different use-cases and patterns emerge from using Style Dictionary. One of those is actually checking in generated files to version control and using a pull request to review and verify the results. Having a time-stamped comment in generated files now becomes a bit of an obstacle. In the principle of extensibility and customization, you can now define your own file header comments for output files! This allows you to remove the timestamp if you want, write a custom message, use the version number of the package, or even use a hash of the source so that it only changes when the source changes. + +You can use the custom file headers on any built-in format, or even use them in a custom format with the formatHelper.fileHeader function. + +```javascript +module.exports = { + //... + fileHeader: { + myFileHeader: (defaultMessage) => { + return [ + ...defaultMessage, + 'hello, world!' + ] + } + }, + + platforms: { + css: { + transformGroup: `css`, + files: [{ + destination: `variables.css`, + format: `css/variables`, + fileHeader: `myFileHeader` + }] + } + } +} +``` + +Example: https://github.com/amzn/style-dictionary/tree/3.0/examples/advanced/custom-file-header + ### Typescript typings https://github.com/amzn/style-dictionary/pull/410 -Added typings for Style Dictionary so you can use it in a TypeScript environment now! +Style Dictionary has Typescript types now! We have added support both for generating typescript files with the typescript/es6-declarations and typescript/module-declarations formats, as well as type definitions for using the Style Dictionary module in a Typescript environment. The source code of Style Dictionary remains in plain Javascript for now, but many people have been wanting to use Style Dictionary in Typescript so as an interim solution we added just the type definitions. As an added bonus, the type definitions also help Javascript Intellisense in VSCode even if you aren't using Typescript in your project! Thanks [@AndrewLeedham](https://github.com/AndrewLeedham)! -### Formats +### More built-ins + +We added support for: Jetpack Compose, React Native, and Stylus with built-in transforms, transform groups, and formats. Style Dictionary is built to be customized and extended, so any language or platform can be supported with customization. We do want to offer a core set of generic transforms and formats to get you started so that you don't have to write custom code for everything. If you think we are missing something, please let us know! Here are the formats, transforms, and transformGroups we added in 3.0: -* [Added 'javascript/module-flat' format](https://github.com/amzn/style-dictionary/pull/457), thanks [@noslouch](https://github.com/noslouch)! -* [Added 'android/resources' format](https://github.com/amzn/style-dictionary/pull/509) +#### Formats -### Transforms +* [`javascript/module-flat`](https://github.com/amzn/style-dictionary/pull/457), thanks [@noslouch](https://github.com/noslouch)! +* [`android/resources`](https://github.com/amzn/style-dictionary/pull/509) +* [`stylus/variables`](https://github.com/amzn/style-dictionary/pull/527), thanks [@klausbayrhammer](https://github.com/klausbayrhammer) +* [`compose/object`](https://github.com/amzn/style-dictionary/pull/599), thanks [@bherbst](https://github.com/bherbst) +* [`typescript/es6-declarations`](https://github.com/amzn/style-dictionary/pull/557), thanks [@Tiamanti](https://github.com/Tiamanti) +* [`typescript/module-declarations`](https://github.com/amzn/style-dictionary/pull/557), thanks [@Tiamanti](https://github.com/Tiamanti) -* [Added 'size/pxToRem' transform](https://github.com/amzn/style-dictionary/pull/491), thanks [@jbarreiros](https://github.com/jbarreiros)! +#### Transforms + +* [`size/pxToRem`](https://github.com/amzn/style-dictionary/pull/491), thanks [@jbarreiros](https://github.com/jbarreiros)! +* [`size/object`](https://github.com/amzn/style-dictionary/pull/512), thanks [@levi-pires](https://github.com/levi-pires) +* [`size/compose/remToSP`](https://github.com/amzn/style-dictionary/pull/599), thanks [@bherbst](https://github.com/bherbst) +* [`size/compose/remToDP`](https://github.com/amzn/style-dictionary/pull/599), thanks [@bherbst](https://github.com/bherbst) +* [`size/compose/em`](https://github.com/amzn/style-dictionary/pull/599), thanks [@bherbst](https://github.com/bherbst) +* [`color/composeColor`](https://github.com/amzn/style-dictionary/pull/599), thanks [@bherbst](https://github.com/bherbst) * [Made base pixel size configurable](https://github.com/amzn/style-dictionary/pull/505), thanks [@jbarreiros](https://github.com/jbarreiros)! +#### Transform Groups + +* [`react-native`](https://github.com/amzn/style-dictionary/pull/512), thanks [@levi-pires](https://github.com/levi-pires) +* [`compose`](https://github.com/amzn/style-dictionary/pull/599), thanks [@bherbst](https://github.com/bherbst) + ### Bug fixes * [Trailing slash check on windows](https://github.com/amzn/style-dictionary/pull/419), thanks [@JDansercoer](https://github.com/JDansercoer)! @@ -291,19 +374,20 @@ Thanks [@AndrewLeedham](https://github.com/AndrewLeedham)! To have higher confidence in the end-to-end experience of Style Dictionary we have added integration tests that run Style Dictionary as real users would. Integration tests are in **__integration__** and use snapshot testing to ensure the output of Style Dictionary from input, transforms, and formats remains the same and valid output. -We have also added more unit tests as well for some features we have added and bugs we have found. So far we have added: -* 11 test suites -* 84 tests -* 27 snapshots +We have also added more unit tests as well for some features we have added and bugs we have found. We added: + +* 28 test suites +* 174 tests +* 69 snapshots + ### Dropping support for older versions of node https://github.com/amzn/style-dictionary/pull/441 To be honest, we should have done this way sooner. Those versions of Node are no longer even in long-term support or maintenance. Hopefully this change should not affect anyone as you should all be on more recent versions of Node anyways. +Style Properties → Design Tokens -### To do +One last change is Style Dictionary is moving to the term "design tokens", both in documentation and in code. This has become the industry standard term for a while and it is time we respect that. Until now, Style Dictionary had called these "style properties" or just "properties", with some parts of the documentation also mentioning "design tokens". We want to be consistent with the direction of the community as well as in our documentation and code. We use the terms `properties` and `allProperties` in different APIs in Style Dictionary. To be consistent in documentation as well as code, we will be moving to using `tokens` and `allTokens`. -* Use ES6 where possible -* Better log levels -* Update documentation +Don't worry! This change is backwards-compatible; you will still be able to use `properties` and `allProperties` wherever you currently do in your code. If you want, you can update those to tokens and allTokens and everything will work as expected. Moving forward, all examples and documentation will use the term "design tokens" and "tokens" rather than "style properties" and "properties". We do recommend using `tokens` and `allTokens` in new code from here on out! diff --git a/examples/README.md b/examples/README.md index ef992a711..79eeee952 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,14 +1,8 @@ -Style Dictionary logo +Style Dictionary logo # Examples -Here you can find some sample projects to get started, or to find inspiration on how to customise and extend the Style Dictionary framework to create the files you need. - -## Setup - -To use one of these examples, clone (or [download](https://github.com/amzn/style-dictionary/archive/master.zip)) from GitHub the project and copy the folder of the example that you want to use. Inside the folder you will find a `README.md` file with the instructions on how to do the initial setup and run the `build` process. - -You can alternatively start a new project from one of the `basic` or `complete` examples using the CLI: +To get you started, there are some example packages included that you can use. You can [take a look at the code on Github](https://github.com/amzn/style-dictionary/tree/main/examples/) or you can use the CLI included to generate a new package using some of these examples. Here is how you can do that: ```bash $ mkdir MyFolder @@ -18,32 +12,42 @@ $ style-dictionary init [example] Where `[example]` is one of: `basic`, `complete`. -This will create a copy of the example in `MyFolder` and start the build process, running `style-dictionary build` for the first time to generate the artifacts. - ## Basic -[View the example](https://github.com/amzn/style-dictionary/tree/master/examples/basic) +[View on Github](https://github.com/amzn/style-dictionary/tree/main/examples/basic) This example code is bare-bones to show you what this framework can do. Use this if you want to play around with what the Style Dictionary can do. ## Complete -[View the example](https://github.com/amzn/style-dictionary/tree/master/examples/complete) +[View on Github](https://github.com/amzn/style-dictionary/tree/main/examples/complete) This is a more complete package and should have everything you need to get started. This package can be consumed as a Cocoapod on iOS, as a node module for web, and as a local library for Android. ## Advanced -[View the folder](https://github.com/amzn/style-dictionary/tree/master/examples/advanced) - -If you want to look at more advanced examples of possible applications and customisations of Style Dictionary, the `examples/advanced` folder on GitHub contains these extra folders: - -* [**assets-base64-embed**](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/assets-base64-embed) shows how it's possible to embed and distribute assets – like images, icons and fonts – directly as design tokens. -* [**auto-rebuild-watcher**](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/auto-rebuild-watcher) shows how to setup a "watcher" that auto-rebuilds the tokens every time there is a change in the properties. -* [**custom-templates**](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/custom-templates/custom-templates) shows how to use "custom" templates to generate design tokens files with custom formats, useful when you need to distribute your design tokens and integrate them with custom pipelines or scripts. -* [**custom-transforms**](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/custom-templates/custom-transforms) shows how to use custom tranforms (and transformGroups) to apply custom "tranformations" to the properties when converted to design tokens. -* [**multi-brand-multi-platform**](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/multi-brand-multi-platform) shows how to set up Style Dictionary to support a multi-brand (for brand theming) and multi-platform (web, iOS, Android) solution, with property values depending on brand and plaforms. -* [**npm-module**](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/npm-module) shows how to set up a style dictionary as an npm module, either to publish to a local npm service or to publish externally. -* [**s3**](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/s3) shows how to set up a style dictionary to build files for different platforms (web, iOS, Android) and upload those build artifacts, together with a group of assets, to an S3 bucket. -* [**referencing_aliasing**](https://github.com/amzn/style-dictionary/tree/master/examples/advanced/referencing_aliasing) shows how to use referencing (or "aliasing") to reference a value -or an attribute– of a property and assign it to the value –or attribute– of another property. +[View the folder](https://github.com/amzn/style-dictionary/tree/main/examples/advanced) + +If you want to look at more advanced examples of possible applications and customizations of Style Dictionary, the [`examples/advanced`](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/) folder on GitHub contains these extra folders: + +* [**assets-base64-embed**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/assets-base64-embed) shows how it's possible to embed and distribute assets – like images, icons and fonts – directly as design tokens. +* [**auto-rebuild-watcher**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/auto-rebuild-watcher) shows how to setup a "watcher" that auto-rebuilds the tokens every time there is a change in the tokens. +* [**component-cti**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/component-cti) shows how to write component tokens and still use the CTI structure. +* [**create-react-app**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/create-react-app) shows how to integrate Style Dictionary into a React application. +* [**create-react-native-app**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/create-react-native-app) shows how to integrate Style Dictionary into a React Native application. +* [**custom-file-header**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-file-header) shows how to define custom file headers and use them in output files. +* [**custom-formats-with-templates**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-formats-with-templates) shows how to generate custom output formats using templates, useful when you need to distribute your design tokens into your own pipelines or scripts. +* [**custom-parser**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-parser) shows how to use custom parsers for token files. +* [**custom-transforms**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-transforms) shows how to use custom transforms (and transformGroups) to apply custom "transformations" to the design tokens. +* [**flutter**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/flutter) shows how to integrate with Flutter applications. +* [**matching-build-files**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/matching-build-files) shows how to output files 1-to-1 with source files. +* [**multi-brand-multi-platform**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/multi-brand-multi-platform) shows how to set up Style Dictionary to support a multi-brand (for brand theming) and multi-platform (web, iOS, Android) solution, with token values depending on brand and platforms. +* [**node-modules-as-config-and-properties**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/node-modules-as-config-and-properties) shows how to use Javascript rather than JSON for configuration and token files. +* [**npm-module**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/npm-module) shows how to set up a style dictionary as an npm module, either to publish to a local npm service or to publish externally. +* [**referencing_aliasing**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/referencing_aliasing) shows how to use referencing (or "aliasing") to reference a value -or an attribute– of a token and assign it to the value –or attribute– of another token. +* [**s3**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/s3) shows how to set up a style dictionary to build files for different platforms (web, iOS, Android) and upload those build artifacts, together with a group of assets, to an S3 bucket. +* [**tokens-deprecation**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/tokens-deprecation) shows one way to deprecate tokens by adding metadata to tokens and using custom formats to output comments in the generated files. +* [**transitive-transforms**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/transitive-transforms) shows how to use transitive transforms to transform references +* [**variables-in-outputs**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/variables-in-outputs) shows you how to use the `outputReferences` option to generate files variable references in them. +* [**yaml-tokens**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/yaml-tokens) shows how to use a custom parser to define your source files in YAML rather than JSON. --- diff --git a/examples/advanced/assets-base64-embed/README.md b/examples/advanced/assets-base64-embed/README.md index 60ba36783..ba6c63d07 100644 --- a/examples/advanced/assets-base64-embed/README.md +++ b/examples/advanced/assets-base64-embed/README.md @@ -2,7 +2,7 @@ This example shows how it's possible to embed and distribute assets – like **images, icons and fonts** – directly as design tokens. -This means that you can centralise all your "core" design values in one single place and one single format, and make their distribution (and consumption) much easier. +This means that you can centralize all your "core" design values in one single place and one single format, and make their distribution (and consumption) much easier. #### Running the example @@ -12,7 +12,7 @@ At this point, run `npm run build`. This command will generate the files in the #### How does it work -In Style Dictionary it is possible to associate to the `value` of a property the path of a file. During the build process, the property is processed and the asset converted to a **base64 string**. In this way the asset can be distributed **embedded** in an output file that has a pre-defined format of your choice (JSON, JS, Sass, XML, PLIST, etc), and this can be then later consumed directly in your application or website. +In Style Dictionary it is possible to associate to the `value` of a token the path of a file. During the build process, the token is processed and the asset converted to a **base64 string**. In this way the asset can be distributed **embedded** in an output file that has a pre-defined format of your choice (JSON, JS, Sass, XML, PLIST, etc), and this can be then later consumed directly in your application or website. For example, in **JavaScript** this code: @@ -54,7 +54,7 @@ Open the `config.json` file and see how all the "assets/embed/*" platform blocks ... ``` -Here there are **three specific transforms**: *attribute/cti* to assign the Category/Type/Item attributes to the tokens, *name/cti/kebab* to assign them the correct name, and finally *asset/base64* to take the path declared in the "value" of the properties, convert the file at that path in base64 format, and assign the output of the base64 conversion to the "value" of the property. +Here there are **three specific transforms**: *attribute/cti* to assign the Category/Type/Item attributes to the tokens, *name/cti/kebab* to assign them the correct name, and finally *asset/base64* to take the path declared in the "value" of the tokens, convert the file at that path in base64 format, and assign the output of the base64 conversion to the "value" of the token. If you take for example the file `assets/icons.json` you will see this declaration: @@ -64,7 +64,7 @@ If you take for example the file `assets/icons.json` you will see this declarati "alert-circle": { "value": "assets/icons/alert-circle.svg" } ``` -where the value of the `alert-circle` property is a path that points to the `alert-circle.svg` file in the `assets/icons/` folder. +where the value of the `alert-circle` token is a path that points to the `alert-circle.svg` file in the `assets/icons/` folder. Now, `build` the dictionary and open the generated file `build/scss/assets_icons.scss`, and you will see this result: diff --git a/examples/advanced/assets-base64-embed/config.json b/examples/advanced/assets-base64-embed/config.json index f93e9a52d..0bc364192 100644 --- a/examples/advanced/assets-base64-embed/config.json +++ b/examples/advanced/assets-base64-embed/config.json @@ -1,5 +1,5 @@ { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "scss": { "transformGroup": "scss", diff --git a/examples/advanced/assets-base64-embed/package.json b/examples/advanced/assets-base64-embed/package.json index c1fde4138..7a02317c4 100644 --- a/examples/advanced/assets-base64-embed/package.json +++ b/examples/advanced/assets-base64-embed/package.json @@ -11,6 +11,6 @@ "author": "", "license": "Apache-2.0", "devDependencies": { - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/assets-base64-embed/properties/assets/fonts.json b/examples/advanced/assets-base64-embed/tokens/assets/fonts.json similarity index 100% rename from examples/advanced/assets-base64-embed/properties/assets/fonts.json rename to examples/advanced/assets-base64-embed/tokens/assets/fonts.json diff --git a/examples/advanced/assets-base64-embed/properties/assets/icons.json b/examples/advanced/assets-base64-embed/tokens/assets/icons.json similarity index 100% rename from examples/advanced/assets-base64-embed/properties/assets/icons.json rename to examples/advanced/assets-base64-embed/tokens/assets/icons.json diff --git a/examples/advanced/assets-base64-embed/properties/assets/images.json b/examples/advanced/assets-base64-embed/tokens/assets/images.json similarity index 100% rename from examples/advanced/assets-base64-embed/properties/assets/images.json rename to examples/advanced/assets-base64-embed/tokens/assets/images.json diff --git a/examples/advanced/assets-base64-embed/properties/color/base.json b/examples/advanced/assets-base64-embed/tokens/color/base.json similarity index 100% rename from examples/advanced/assets-base64-embed/properties/color/base.json rename to examples/advanced/assets-base64-embed/tokens/color/base.json diff --git a/examples/advanced/assets-base64-embed/properties/color/font.json b/examples/advanced/assets-base64-embed/tokens/color/font.json similarity index 100% rename from examples/advanced/assets-base64-embed/properties/color/font.json rename to examples/advanced/assets-base64-embed/tokens/color/font.json diff --git a/examples/advanced/assets-base64-embed/properties/size/font.json b/examples/advanced/assets-base64-embed/tokens/size/font.json similarity index 100% rename from examples/advanced/assets-base64-embed/properties/size/font.json rename to examples/advanced/assets-base64-embed/tokens/size/font.json diff --git a/examples/advanced/auto-rebuild-watcher/README.md b/examples/advanced/auto-rebuild-watcher/README.md index 18f71d32a..215484ba6 100644 --- a/examples/advanced/auto-rebuild-watcher/README.md +++ b/examples/advanced/auto-rebuild-watcher/README.md @@ -1,6 +1,6 @@ ## How to use a watcher to auto-rebuild -This example shows how to use a "watcher" to rebuild automatically the files every time a property file is updated. +This example shows how to use a "watcher" to rebuild automatically the files every time a token file is updated. This is quite handy when there are continuous changes to the token values (e.g. during development) and we want to avoid to run the "build" command at every update. @@ -10,11 +10,11 @@ First of all, set up the required dependencies running the command `npm install` At this point, if you want to build once the tokens you can run `npm run build`. This command will generate the files in the `build` folder. -If instead you want to automatically build the tokens every time a property file is updated, run the command `npm run watch` in your CLI. +If instead you want to automatically build the tokens every time a token file is updated, run the command `npm run watch` in your CLI. -This will start to watch the files in the "properties" folder, and whenever a file is updated and saved, the files in `build` are re-generated with the new/updated values. +This will start to watch the files in the "tokens" folder, and whenever a file is updated and saved, the files in `build` are re-generated with the new/updated values. -If you want to see it in action, open one of the files generated in "build", open a property file and update one of the values: you will see immediately updated also the generated file. +If you want to see it in action, open one of the files generated in "build", open a token file and update one of the values: you will see immediately updated also the generated file. **Important**: when in "watch" mode, to interrupt and exit the process and get back to your command line, use the `ctrl-c` command in your terminal. @@ -22,7 +22,7 @@ If you want to see it in action, open one of the files generated in "build", ope The "watch" runner will start a process (using a special filesystem watcher called [Chokidar](https://github.com/paulmillr/chokidar)) that will listen to changes to a list of "watched" files. Whenever one of this file is changed/updated (more precisely, is saved to disk) the watch process will trigger a command specified by the user (as an argument passed to the watcher). -In this example, we have selected all the JSON files in the `props` folder (using the glob pattern `properties/**/*.json`) but you can specify your own path of watched files. +In this example, we have selected all the JSON files in the `tokens` folder (using the glob pattern `tokens/**/*.json`) but you can specify your own path of watched files. The command that we automatically run at every update is the `npm run build` command, passed as parameter to the watcher via `-c 'npm run build'`. diff --git a/examples/advanced/auto-rebuild-watcher/config.json b/examples/advanced/auto-rebuild-watcher/config.json index 942e328ac..6710fad62 100644 --- a/examples/advanced/auto-rebuild-watcher/config.json +++ b/examples/advanced/auto-rebuild-watcher/config.json @@ -1,5 +1,5 @@ { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "scss": { "transformGroup": "scss", diff --git a/examples/advanced/auto-rebuild-watcher/package.json b/examples/advanced/auto-rebuild-watcher/package.json index 35cad64ae..0b5ba4214 100644 --- a/examples/advanced/auto-rebuild-watcher/package.json +++ b/examples/advanced/auto-rebuild-watcher/package.json @@ -17,6 +17,6 @@ "license": "Apache-2.0", "devDependencies": { "chokidar-cli": "^1.2.0", - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/auto-rebuild-watcher/properties/color/base.json b/examples/advanced/auto-rebuild-watcher/tokens/color/base.json similarity index 100% rename from examples/advanced/auto-rebuild-watcher/properties/color/base.json rename to examples/advanced/auto-rebuild-watcher/tokens/color/base.json diff --git a/examples/advanced/auto-rebuild-watcher/properties/color/font.json b/examples/advanced/auto-rebuild-watcher/tokens/color/font.json similarity index 100% rename from examples/advanced/auto-rebuild-watcher/properties/color/font.json rename to examples/advanced/auto-rebuild-watcher/tokens/color/font.json diff --git a/examples/advanced/auto-rebuild-watcher/properties/size/font.json b/examples/advanced/auto-rebuild-watcher/tokens/size/font.json similarity index 100% rename from examples/advanced/auto-rebuild-watcher/properties/size/font.json rename to examples/advanced/auto-rebuild-watcher/tokens/size/font.json diff --git a/examples/advanced/component-cti/config.js b/examples/advanced/component-cti/config.js index fbc774c19..a8d1688a7 100644 --- a/examples/advanced/component-cti/config.js +++ b/examples/advanced/component-cti/config.js @@ -1,4 +1,5 @@ const StyleDictionary = require('style-dictionary'); +const transformer = StyleDictionary.transform['attribute/cti'].transformer; const propertiesToCTI = { 'width': {category: 'size', type: 'dimension'}, @@ -15,7 +16,7 @@ const propertiesToCTI = { 'text-color': { category: 'color', type: 'font' }, 'padding': {category: 'size', type: 'padding'}, 'padding-vertical': {category: 'size', type: 'padding'}, - 'padding-horziontal': {category: 'size', type: 'padding'}, + 'padding-horizontal': {category: 'size', type: 'padding'}, 'icon': {category: 'content', type: 'icon'}, 'font-size': {category: 'size', type: 'font'}, 'line-height': { category: 'size', type: 'line-height' }, @@ -23,6 +24,7 @@ const propertiesToCTI = { } const CTITransform = { + type: `attribute`, transformer: (prop) => { // Only do this custom functionality in the 'component' top-level namespace. if (prop.path[0] === 'component') { @@ -31,15 +33,24 @@ const CTITransform = { return propertiesToCTI[prop.path[prop.path.length - 1]]; } else { // Fallback to the original 'attribute/cti' transformer - return StyleDictionary.transform['attribute/cti'].transformer(prop); + return transformer(prop); } } } +// We can call .registerTransform here +// or apply the custom transform directly in the configuration below +// +// StyleDictionary.registerTransform({ +// name: 'attribute/cti', +// type: 'attribute', +// transformer: CTITransform.transformer +// }); + module.exports = { // Rather than calling .registerTransform() we can apply the new transform // directly in our configuration. Using .registerTransform() with the same - // transform name, 'attribute/cti', would work as well. + // transform name, 'attribute/cti', would work as well. transform: { // Override the attribute/cti transform 'attribute/cti': CTITransform @@ -57,4 +68,4 @@ module.exports = { }] } } -} \ No newline at end of file +} diff --git a/examples/advanced/component-cti/package-lock.json b/examples/advanced/component-cti/package-lock.json index 4861c531b..25fb417e5 100644 --- a/examples/advanced/component-cti/package-lock.json +++ b/examples/advanced/component-cti/package-lock.json @@ -1,5 +1,5 @@ { - "name": "style-dictionary-tokens-deprecation", + "name": "style-dictionary-component-cti", "version": "1.0.0", "lockfileVersion": 1, "requires": true, @@ -179,25 +179,10 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, "style-dictionary": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-2.10.3.tgz", - "integrity": "sha512-iSDb8T2tMSB5JcTQ7uquB+W3oO7kuJbb+QrSQMiQjBCOa7AGYtWzYo/O7rl3f9Hj956w41WVw9HpTpYfFWwU+g==", + "version": "3.0.0-rc.6", + "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-3.0.0-rc.6.tgz", + "integrity": "sha512-EI0B3n9NnL/dmMWSSg18/CEqCamG9/fxYetS0kvBDfuSkXxDuBEwLfta1+GvSKF8b+/01WweITrazaUS991VIQ==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -206,7 +191,6 @@ "glob": "^7.1.6", "json5": "^2.1.3", "lodash": "^4.17.15", - "resolve-cwd": "^3.0.0", "tinycolor2": "^1.4.1" } }, diff --git a/examples/advanced/component-cti/package.json b/examples/advanced/component-cti/package.json index db1f7c8aa..52f67ad3b 100644 --- a/examples/advanced/component-cti/package.json +++ b/examples/advanced/component-cti/package.json @@ -15,6 +15,6 @@ "author": "", "license": "Apache-2.0", "devDependencies": { - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/create-react-app/package.json b/examples/advanced/create-react-app/package.json index 759be271d..1a4308a35 100644 --- a/examples/advanced/create-react-app/package.json +++ b/examples/advanced/create-react-app/package.json @@ -10,7 +10,7 @@ "styled-components": "^5.2.1" }, "devDependencies": { - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" }, "resolutions": { "immer": "8.0.1", @@ -35,4 +35,4 @@ "not op_mini all" ], "license": "Apache-2.0" -} +} \ No newline at end of file diff --git a/examples/advanced/create-react-native-app/.buckconfig b/examples/advanced/create-react-native-app/.buckconfig new file mode 100644 index 000000000..934256cb2 --- /dev/null +++ b/examples/advanced/create-react-native-app/.buckconfig @@ -0,0 +1,6 @@ + +[android] + target = Google Inc.:Google APIs:23 + +[maven_repositories] + central = https://repo1.maven.org/maven2 diff --git a/examples/advanced/create-react-native-app/.gitattributes b/examples/advanced/create-react-native-app/.gitattributes new file mode 100644 index 000000000..d42ff1835 --- /dev/null +++ b/examples/advanced/create-react-native-app/.gitattributes @@ -0,0 +1 @@ +*.pbxproj -text diff --git a/examples/advanced/create-react-native-app/.gitignore b/examples/advanced/create-react-native-app/.gitignore new file mode 100644 index 000000000..5e244adbb --- /dev/null +++ b/examples/advanced/create-react-native-app/.gitignore @@ -0,0 +1,64 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# BUCK +buck-out/ +\.buckd/ +*.keystore +!debug.keystore + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/ + +*/fastlane/report.xml +*/fastlane/Preview.html +*/fastlane/screenshots + +# Bundle artifacts +*.jsbundle + +# CocoaPods +/ios/Pods/ + +# Expo +.expo/* +web-build/ diff --git a/examples/advanced/create-react-native-app/__tests__/App.js b/examples/advanced/create-react-native-app/__tests__/App.js new file mode 100644 index 000000000..e1f2e0594 --- /dev/null +++ b/examples/advanced/create-react-native-app/__tests__/App.js @@ -0,0 +1,10 @@ +import "react-native"; +import React from "react"; +import App from "../src/App"; + +// Note: test renderer must be required after react-native. +import renderer from "react-test-renderer"; + +it("renders correctly", () => { + renderer.create(); +}); diff --git a/examples/advanced/create-react-native-app/android/app/BUCK b/examples/advanced/create-react-native-app/android/app/BUCK new file mode 100644 index 000000000..f2a26657d --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/BUCK @@ -0,0 +1,55 @@ +# To learn about Buck see [Docs](https://buckbuild.com/). +# To run your application with Buck: +# - install Buck +# - `npm start` - to start the packager +# - `cd android` +# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` +# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck +# - `buck install -r android/app` - compile, install and run application +# + +load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") + +lib_deps = [] + +create_aar_targets(glob(["libs/*.aar"])) + +create_jar_targets(glob(["libs/*.jar"])) + +android_library( + name = "all-libs", + exported_deps = lib_deps, +) + +android_library( + name = "app-code", + srcs = glob([ + "src/main/java/**/*.java", + ]), + deps = [ + ":all-libs", + ":build_config", + ":res", + ], +) + +android_build_config( + name = "build_config", + package = "com.createreactnativeapp", +) + +android_resource( + name = "res", + package = "com.createreactnativeapp", + res = "src/main/res", +) + +android_binary( + name = "app", + keystore = "//android/keystores:debug", + manifest = "src/main/AndroidManifest.xml", + package_type = "debug", + deps = [ + ":app-code", + ], +) diff --git a/examples/advanced/create-react-native-app/android/app/build.gradle b/examples/advanced/create-react-native-app/android/app/build.gradle new file mode 100644 index 000000000..341fb46b1 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/build.gradle @@ -0,0 +1,219 @@ +apply plugin: "com.android.application" + +import com.android.build.OutputFile + +/** + * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets + * and bundleReleaseJsAndAssets). + * These basically call `react-native bundle` with the correct arguments during the Android build + * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the + * bundle directly from the development server. Below you can see all the possible configurations + * and their defaults. If you decide to add a configuration block, make sure to add it before the + * `apply from: "../../node_modules/react-native/react.gradle"` line. + * + * project.ext.react = [ + * // the name of the generated asset file containing your JS bundle + * bundleAssetName: "index.android.bundle", + * + * // the entry file for bundle generation. If none specified and + * // "index.android.js" exists, it will be used. Otherwise "index.js" is + * // default. Can be overridden with ENTRY_FILE environment variable. + * entryFile: "index.android.js", + * + * // https://reactnative.dev/docs/performance#enable-the-ram-format + * bundleCommand: "ram-bundle", + * + * // whether to bundle JS and assets in debug mode + * bundleInDebug: false, + * + * // whether to bundle JS and assets in release mode + * bundleInRelease: true, + * + * // whether to bundle JS and assets in another build variant (if configured). + * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants + * // The configuration property can be in the following formats + * // 'bundleIn${productFlavor}${buildType}' + * // 'bundleIn${buildType}' + * // bundleInFreeDebug: true, + * // bundleInPaidRelease: true, + * // bundleInBeta: true, + * + * // whether to disable dev mode in custom build variants (by default only disabled in release) + * // for example: to disable dev mode in the staging build type (if configured) + * devDisabledInStaging: true, + * // The configuration property can be in the following formats + * // 'devDisabledIn${productFlavor}${buildType}' + * // 'devDisabledIn${buildType}' + * + * // the root of your project, i.e. where "package.json" lives + * root: "../../", + * + * // where to put the JS bundle asset in debug mode + * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", + * + * // where to put the JS bundle asset in release mode + * jsBundleDirRelease: "$buildDir/intermediates/assets/release", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in debug mode + * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in release mode + * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", + * + * // by default the gradle tasks are skipped if none of the JS files or assets change; this means + * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to + * // date; if you have any other folders that you want to ignore for performance reasons (gradle + * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ + * // for example, you might want to remove it from here. + * inputExcludes: ["android/**", "ios/**"], + * + * // override which node gets called and with what additional arguments + * nodeExecutableAndArgs: ["node"], + * + * // supply additional arguments to the packager + * extraPackagerArgs: [] + * ] + */ + +project.ext.react = [ + enableHermes: false +] + +apply from: '../../node_modules/react-native-unimodules/gradle.groovy' +apply from: "../../node_modules/react-native/react.gradle" +apply from: "../../node_modules/expo-constants/scripts/get-app-config-android.gradle" +apply from: "../../node_modules/expo-updates/scripts/create-manifest-android.gradle" + +/** + * Set this to true to create two separate APKs instead of one: + * - An APK that only works on ARM devices + * - An APK that only works on x86 devices + * The advantage is the size of the APK is reduced by about 4MB. + * Upload all the APKs to the Play Store and people will download + * the correct one based on the CPU architecture of their device. + */ +def enableSeparateBuildPerCPUArchitecture = false + +/** + * Run Proguard to shrink the Java bytecode in release builds. + */ +def enableProguardInReleaseBuilds = false + +/** + * The preferred build flavor of JavaScriptCore. + * + * For example, to use the international variant, you can use: + * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` + * + * The international variant includes ICU i18n library and necessary data + * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that + * give correct results when using with locales other than en-US. Note that + * this variant is about 6MiB larger per architecture than default. + */ +def jscFlavor = 'org.webkit:android-jsc:+' + +/** + * Whether to enable the Hermes VM. + * + * This should be set on project.ext.react and mirrored here. If it is not set + * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode + * and the benefits of using Hermes will therefore be sharply reduced. + */ +def enableHermes = project.ext.react.get("enableHermes", false); + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + defaultConfig { + applicationId "com.createreactnativeapp" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 1 + versionName "1.0" + } + splits { + abi { + reset() + enable enableSeparateBuildPerCPUArchitecture + universalApk false // If true, also generate a universal APK + include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" + } + } + signingConfigs { + debug { + storeFile file('debug.keystore') + storePassword 'android' + keyAlias 'androiddebugkey' + keyPassword 'android' + } + } + buildTypes { + debug { + signingConfig signingConfigs.debug + } + release { + // Caution! In production, you need to generate your own keystore file. + // see https://reactnative.dev/docs/signed-apk-android. + signingConfig signingConfigs.debug + minifyEnabled enableProguardInReleaseBuilds + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + } + } + + // applicationVariants are e.g. debug, release + applicationVariants.all { variant -> + variant.outputs.each { output -> + // For each separate APK per architecture, set a unique version code as described here: + // https://developer.android.com/studio/build/configure-apk-splits.html + def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] + def abi = output.getFilter(OutputFile.ABI) + if (abi != null) { // null for the universal-debug, universal-release variants + output.versionCodeOverride = + versionCodes.get(abi) * 1048576 + defaultConfig.versionCode + } + + } + } +} + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + //noinspection GradleDynamicVersion + implementation "com.facebook.react:react-native:+" // From node_modules + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { + exclude group:'com.facebook.fbjni' + } + debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { + exclude group:'com.facebook.flipper' + exclude group:'com.squareup.okhttp3', module:'okhttp' + } + debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { + exclude group:'com.facebook.flipper' + } + addUnimodulesDependencies() + + if (enableHermes) { + def hermesPath = "../../node_modules/hermes-engine/android/"; + debugImplementation files(hermesPath + "hermes-debug.aar") + releaseImplementation files(hermesPath + "hermes-release.aar") + } else { + implementation jscFlavor + } +} + +// Run this once to be able to run the application with BUCK +// puts all compile dependencies into folder libs for BUCK to use +task copyDownloadableDepsToLibs(type: Copy) { + from configurations.compile + into 'libs' +} + +apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) diff --git a/examples/advanced/create-react-native-app/android/app/build_defs.bzl b/examples/advanced/create-react-native-app/android/app/build_defs.bzl new file mode 100644 index 000000000..fff270f8d --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/build_defs.bzl @@ -0,0 +1,19 @@ +"""Helper definitions to glob .aar and .jar targets""" + +def create_aar_targets(aarfiles): + for aarfile in aarfiles: + name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] + lib_deps.append(":" + name) + android_prebuilt_aar( + name = name, + aar = aarfile, + ) + +def create_jar_targets(jarfiles): + for jarfile in jarfiles: + name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] + lib_deps.append(":" + name) + prebuilt_jar( + name = name, + binary_jar = jarfile, + ) diff --git a/examples/advanced/create-react-native-app/android/app/debug.keystore b/examples/advanced/create-react-native-app/android/app/debug.keystore new file mode 100644 index 000000000..364e105ed Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/debug.keystore differ diff --git a/examples/advanced/create-react-native-app/android/app/proguard-rules.pro b/examples/advanced/create-react-native-app/android/app/proguard-rules.pro new file mode 100644 index 000000000..11b025724 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/proguard-rules.pro @@ -0,0 +1,10 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: diff --git a/examples/advanced/create-react-native-app/android/app/src/debug/AndroidManifest.xml b/examples/advanced/create-react-native-app/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000..99e38fc5f --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/examples/advanced/create-react-native-app/android/app/src/debug/java/com/createreactnativeapp/ReactNativeFlipper.java b/examples/advanced/create-react-native-app/android/app/src/debug/java/com/createreactnativeapp/ReactNativeFlipper.java new file mode 100644 index 000000000..ea6a06ba0 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/debug/java/com/createreactnativeapp/ReactNativeFlipper.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + *

This source code is licensed under the MIT license found in the LICENSE file in the root + * directory of this source tree. + */ +package com.createreactnativeapp; + +import android.content.Context; +import com.facebook.flipper.android.AndroidFlipperClient; +import com.facebook.flipper.android.utils.FlipperUtils; +import com.facebook.flipper.core.FlipperClient; +import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; +import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; +import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; +import com.facebook.flipper.plugins.inspector.DescriptorMapping; +import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; +import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; +import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; +import com.facebook.flipper.plugins.react.ReactFlipperPlugin; +import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.modules.network.NetworkingModule; +import okhttp3.OkHttpClient; + +public class ReactNativeFlipper { + public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { + if (FlipperUtils.shouldEnableFlipper(context)) { + final FlipperClient client = AndroidFlipperClient.getInstance(context); + client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); + client.addPlugin(new ReactFlipperPlugin()); + client.addPlugin(new DatabasesFlipperPlugin(context)); + client.addPlugin(new SharedPreferencesFlipperPlugin(context)); + client.addPlugin(CrashReporterPlugin.getInstance()); + NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); + NetworkingModule.setCustomClientBuilder( + new NetworkingModule.CustomClientBuilder() { + @Override + public void apply(OkHttpClient.Builder builder) { + builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); + } + }); + client.addPlugin(networkFlipperPlugin); + client.start(); + // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized + // Hence we run if after all native modules have been initialized + ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); + if (reactContext == null) { + reactInstanceManager.addReactInstanceEventListener( + new ReactInstanceManager.ReactInstanceEventListener() { + @Override + public void onReactContextInitialized(ReactContext reactContext) { + reactInstanceManager.removeReactInstanceEventListener(this); + reactContext.runOnNativeModulesQueueThread( + new Runnable() { + @Override + public void run() { + client.addPlugin(new FrescoFlipperPlugin()); + } + }); + } + }); + } else { + client.addPlugin(new FrescoFlipperPlugin()); + } + } + } +} \ No newline at end of file diff --git a/examples/advanced/create-react-native-app/android/app/src/main/AndroidManifest.xml b/examples/advanced/create-react-native-app/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..92e7f00e8 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/advanced/create-react-native-app/android/app/src/main/java/com/createreactnativeapp/MainActivity.java b/examples/advanced/create-react-native-app/android/app/src/main/java/com/createreactnativeapp/MainActivity.java new file mode 100644 index 000000000..3470cf80b --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/main/java/com/createreactnativeapp/MainActivity.java @@ -0,0 +1,41 @@ +package com.createreactnativeapp; + +import android.os.Bundle; + +import com.facebook.react.ReactActivity; +import com.facebook.react.ReactActivityDelegate; +import com.facebook.react.ReactRootView; +import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; + +import expo.modules.splashscreen.singletons.SplashScreen; +import expo.modules.splashscreen.SplashScreenImageResizeMode; + +public class MainActivity extends ReactActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // SplashScreen.show(...) has to be called after super.onCreate(...) + // Below line is handled by '@expo/configure-splash-screen' command and it's discouraged to modify it manually + SplashScreen.show(this, SplashScreenImageResizeMode.CONTAIN, ReactRootView.class, false); + } + + + /** + * Returns the name of the main component registered from JavaScript. + * This is used to schedule rendering of the component. + */ + @Override + protected String getMainComponentName() { + return "main"; + } + + @Override + protected ReactActivityDelegate createReactActivityDelegate() { + return new ReactActivityDelegate(this, getMainComponentName()) { + @Override + protected ReactRootView createRootView() { + return new RNGestureHandlerEnabledRootView(MainActivity.this); + } + }; + } +} diff --git a/examples/advanced/create-react-native-app/android/app/src/main/java/com/createreactnativeapp/MainApplication.java b/examples/advanced/create-react-native-app/android/app/src/main/java/com/createreactnativeapp/MainApplication.java new file mode 100644 index 000000000..6691c2e5e --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/main/java/com/createreactnativeapp/MainApplication.java @@ -0,0 +1,120 @@ +package com.createreactnativeapp; + +import android.app.Application; +import android.content.Context; +import android.net.Uri; + +import com.facebook.react.PackageList; +import com.facebook.react.ReactApplication; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.shell.MainReactPackage; +import com.facebook.soloader.SoLoader; +import com.createreactnativeapp.generated.BasePackageList; + +import org.unimodules.adapters.react.ReactAdapterPackage; +import org.unimodules.adapters.react.ModuleRegistryAdapter; +import org.unimodules.adapters.react.ReactModuleRegistryProvider; +import org.unimodules.core.interfaces.Package; +import org.unimodules.core.interfaces.SingletonModule; +import expo.modules.constants.ConstantsPackage; +import expo.modules.permissions.PermissionsPackage; +import expo.modules.filesystem.FileSystemPackage; +import expo.modules.updates.UpdatesController; + +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.List; +import javax.annotation.Nullable; + +public class MainApplication extends Application implements ReactApplication { + private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider( + new BasePackageList().getPackageList() + ); + + private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { + @Override + public boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; + } + + @Override + protected List getPackages() { + List packages = new PackageList(this).getPackages(); + packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider)); + return packages; + } + + @Override + protected String getJSMainModuleName() { + return "index"; + } + + @Override + protected @Nullable String getJSBundleFile() { + if (BuildConfig.DEBUG) { + return super.getJSBundleFile(); + } else { + return UpdatesController.getInstance().getLaunchAssetFile(); + } + } + + @Override + protected @Nullable String getBundleAssetName() { + if (BuildConfig.DEBUG) { + return super.getBundleAssetName(); + } else { + return UpdatesController.getInstance().getBundleAssetName(); + } + } + }; + + @Override + public ReactNativeHost getReactNativeHost() { + return mReactNativeHost; + } + + @Override + public void onCreate() { + super.onCreate(); + SoLoader.init(this, /* native exopackage */ false); + + if (!BuildConfig.DEBUG) { + UpdatesController.initialize(this); + } + + initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + } + + /** + * Loads Flipper in React Native templates. Call this in the onCreate method with something like + * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + * + * @param context + * @param reactInstanceManager + */ + private static void initializeFlipper( + Context context, ReactInstanceManager reactInstanceManager) { + if (BuildConfig.DEBUG) { + try { + /* + We use reflection here to pick up the class that initializes Flipper, + since Flipper library is not available in release mode + */ + Class aClass = Class.forName("com.createreactnativeapp.ReactNativeFlipper"); + aClass + .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) + .invoke(null, context, reactInstanceManager); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } +} diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/drawable/splashscreen.xml b/examples/advanced/create-react-native-app/android/app/src/main/res/drawable/splashscreen.xml new file mode 100644 index 000000000..9f19c56e5 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/main/res/drawable/splashscreen.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/drawable/splashscreen_image.png b/examples/advanced/create-react-native-app/android/app/src/main/res/drawable/splashscreen_image.png new file mode 100644 index 000000000..cc94f379d Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/drawable/splashscreen_image.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..a2f590828 Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 000000000..1b5239980 Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..ff10afd6e Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 000000000..115a4c768 Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..dcd3cd808 Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 000000000..459ca609d Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..8ca12fe02 Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..8e19b410a Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..b824ebdd4 Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..4c19a13c2 Binary files /dev/null and b/examples/advanced/create-react-native-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/values/colors.xml b/examples/advanced/create-react-native-app/android/app/src/main/res/values/colors.xml new file mode 100644 index 000000000..7e2bd59b1 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/main/res/values/colors.xml @@ -0,0 +1,5 @@ + + + + #FFFFFF + diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/values/strings.xml b/examples/advanced/create-react-native-app/android/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..cfb7c5efa --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + create-react-native-app + diff --git a/examples/advanced/create-react-native-app/android/app/src/main/res/values/styles.xml b/examples/advanced/create-react-native-app/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..91ef30b0f --- /dev/null +++ b/examples/advanced/create-react-native-app/android/app/src/main/res/values/styles.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/examples/advanced/create-react-native-app/android/build.gradle b/examples/advanced/create-react-native-app/android/build.gradle new file mode 100644 index 000000000..7a08fa86a --- /dev/null +++ b/examples/advanced/create-react-native-app/android/build.gradle @@ -0,0 +1,38 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + ext { + buildToolsVersion = "29.0.2" + minSdkVersion = 21 + compileSdkVersion = 29 + targetSdkVersion = 29 + } + repositories { + google() + jcenter() + } + dependencies { + classpath("com.android.tools.build:gradle:3.5.3") + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + mavenLocal() + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url("$rootDir/../node_modules/react-native/android") + } + maven { + // Android JSC is installed from npm + url("$rootDir/../node_modules/jsc-android/dist") + } + + google() + jcenter() + maven { url 'https://www.jitpack.io' } + } +} diff --git a/examples/advanced/create-react-native-app/android/gradle.properties b/examples/advanced/create-react-native-app/android/gradle.properties new file mode 100644 index 000000000..e75e6d338 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/gradle.properties @@ -0,0 +1,29 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true + +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true + +# Version of flipper SDK to use with React Native +FLIPPER_VERSION=0.54.0 \ No newline at end of file diff --git a/examples/advanced/create-react-native-app/android/gradle/wrapper/gradle-wrapper.jar b/examples/advanced/create-react-native-app/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..2c6137b87 Binary files /dev/null and b/examples/advanced/create-react-native-app/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/examples/advanced/create-react-native-app/android/gradle/wrapper/gradle-wrapper.properties b/examples/advanced/create-react-native-app/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..842267020 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/examples/advanced/create-react-native-app/android/gradlew b/examples/advanced/create-react-native-app/android/gradlew new file mode 100644 index 000000000..2fe81a7d9 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/examples/advanced/create-react-native-app/android/gradlew.bat b/examples/advanced/create-react-native-app/android/gradlew.bat new file mode 100644 index 000000000..62bd9b9cc --- /dev/null +++ b/examples/advanced/create-react-native-app/android/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/examples/advanced/create-react-native-app/android/settings.gradle b/examples/advanced/create-react-native-app/android/settings.gradle new file mode 100644 index 000000000..ef1ed7c11 --- /dev/null +++ b/examples/advanced/create-react-native-app/android/settings.gradle @@ -0,0 +1,9 @@ +rootProject.name = 'createreactnativeapp' + +apply from: '../node_modules/react-native-unimodules/gradle.groovy' +includeUnimodulesProjects() + +apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); +applyNativeModulesSettingsGradle(settings) + +include ':app' diff --git a/examples/advanced/create-react-native-app/app.json b/examples/advanced/create-react-native-app/app.json new file mode 100644 index 000000000..4ff4e697f --- /dev/null +++ b/examples/advanced/create-react-native-app/app.json @@ -0,0 +1,12 @@ +{ + "name": "create-react-native-app", + "displayName": "create-react-native-app", + "expo": { + "name": "create-react-native-app", + "slug": "create-react-native-app", + "version": "1.0.0", + "assetBundlePatterns": [ + "**/*" + ] + } +} diff --git a/examples/advanced/create-react-native-app/babel.config.js b/examples/advanced/create-react-native-app/babel.config.js new file mode 100644 index 000000000..2900afe9d --- /dev/null +++ b/examples/advanced/create-react-native-app/babel.config.js @@ -0,0 +1,6 @@ +module.exports = function(api) { + api.cache(true); + return { + presets: ['babel-preset-expo'], + }; +}; diff --git a/examples/advanced/create-react-native-app/config.json b/examples/advanced/create-react-native-app/config.json new file mode 100644 index 000000000..d7441a0ca --- /dev/null +++ b/examples/advanced/create-react-native-app/config.json @@ -0,0 +1,15 @@ +{ + "source": ["./style-dictionary/properties/**/*.json"], + "platforms": { + "rn": { + "transformGroup": "react-native", + "buildPath": "./src/style-dictionary-dist/", + "files": [ + { + "destination": "variables.js", + "format": "javascript/es6" + } + ] + } + } +} diff --git a/examples/advanced/create-react-native-app/index.js b/examples/advanced/create-react-native-app/index.js new file mode 100644 index 000000000..4e11800cc --- /dev/null +++ b/examples/advanced/create-react-native-app/index.js @@ -0,0 +1,8 @@ +import { registerRootComponent } from "expo"; + +import App from "./src/App"; + +// registerRootComponent calls AppRegistry.registerComponent('main', () => App); +// It also ensures that whether you load the app in the Expo client or in a native build, +// the environment is set up appropriately +registerRootComponent(App); diff --git a/examples/advanced/create-react-native-app/ios/Podfile b/examples/advanced/create-react-native-app/ios/Podfile new file mode 100644 index 000000000..377fd7c83 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/Podfile @@ -0,0 +1,24 @@ +require_relative '../node_modules/react-native/scripts/react_native_pods' +require_relative '../node_modules/react-native-unimodules/cocoapods.rb' +require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' + +platform :ios, '10.0' + +target 'createreactnativeapp' do + use_unimodules! + config = use_native_modules! + + use_react_native!(:path => config["reactNativePath"]) + + # Uncomment the code below to enable Flipper. + # + # You should not install Flipper in CI environments when creating release + # builds, this will lead to significantly slower build times. + # + # Note that if you have use_frameworks! enabled, Flipper will not work. + # + # use_flipper! + # post_install do |installer| + # flipper_post_install(installer) + # end +end diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp.xcodeproj/project.pbxproj b/examples/advanced/create-react-native-app/ios/createreactnativeapp.xcodeproj/project.pbxproj new file mode 100644 index 000000000..4e0106515 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp.xcodeproj/project.pbxproj @@ -0,0 +1,481 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; + 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; + 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; }; + 96905EF65AED1B983A6B3ABC /* libPods-createreactnativeapp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-createreactnativeapp.a */; }; + BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; + 13B07F961A680F5B00A75B9A /* createreactnativeapp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = createreactnativeapp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = createreactnativeapp/AppDelegate.h; sourceTree = ""; }; + 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = createreactnativeapp/AppDelegate.m; sourceTree = ""; }; + 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = createreactnativeapp/Images.xcassets; sourceTree = ""; }; + 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = createreactnativeapp/Info.plist; sourceTree = ""; }; + 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = createreactnativeapp/main.m; sourceTree = ""; }; + 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-createreactnativeapp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-createreactnativeapp.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6C2E3173556A471DD304B334 /* Pods-createreactnativeapp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-createreactnativeapp.debug.xcconfig"; path = "Target Support Files/Pods-createreactnativeapp/Pods-createreactnativeapp.debug.xcconfig"; sourceTree = ""; }; + 7A4D352CD337FB3A3BF06240 /* Pods-createreactnativeapp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-createreactnativeapp.release.xcconfig"; path = "Target Support Files/Pods-createreactnativeapp/Pods-createreactnativeapp.release.xcconfig"; sourceTree = ""; }; + AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = createreactnativeapp/SplashScreen.storyboard; sourceTree = ""; }; + BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = ""; }; + ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 96905EF65AED1B983A6B3ABC /* libPods-createreactnativeapp.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 13B07FAE1A68108700A75B9A /* createreactnativeapp */ = { + isa = PBXGroup; + children = ( + BB2F792B24A3F905000567C9 /* Supporting */, + 008F07F21AC5B25A0029DE68 /* main.jsbundle */, + 13B07FAF1A68108700A75B9A /* AppDelegate.h */, + 13B07FB01A68108700A75B9A /* AppDelegate.m */, + 13B07FB51A68108700A75B9A /* Images.xcassets */, + 13B07FB61A68108700A75B9A /* Info.plist */, + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, + 13B07FB71A68108700A75B9A /* main.m */, + AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */, + ); + name = createreactnativeapp; + sourceTree = ""; + }; + 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { + isa = PBXGroup; + children = ( + ED297162215061F000B7C4FE /* JavaScriptCore.framework */, + ED2971642150620600B7C4FE /* JavaScriptCore.framework */, + 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-createreactnativeapp.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 832341AE1AAA6A7D00B99B32 /* Libraries */ = { + isa = PBXGroup; + children = ( + ); + name = Libraries; + sourceTree = ""; + }; + 83CBB9F61A601CBA00E9B192 = { + isa = PBXGroup; + children = ( + 13B07FAE1A68108700A75B9A /* createreactnativeapp */, + 832341AE1AAA6A7D00B99B32 /* Libraries */, + 83CBBA001A601CBA00E9B192 /* Products */, + 2D16E6871FA4F8E400B85C8A /* Frameworks */, + D65327D7A22EEC0BE12398D9 /* Pods */, + ); + indentWidth = 2; + sourceTree = ""; + tabWidth = 2; + usesTabs = 0; + }; + 83CBBA001A601CBA00E9B192 /* Products */ = { + isa = PBXGroup; + children = ( + 13B07F961A680F5B00A75B9A /* createreactnativeapp.app */, + ); + name = Products; + sourceTree = ""; + }; + BB2F792B24A3F905000567C9 /* Supporting */ = { + isa = PBXGroup; + children = ( + BB2F792C24A3F905000567C9 /* Expo.plist */, + ); + name = Supporting; + path = createreactnativeapp/Supporting; + sourceTree = ""; + }; + D65327D7A22EEC0BE12398D9 /* Pods */ = { + isa = PBXGroup; + children = ( + 6C2E3173556A471DD304B334 /* Pods-createreactnativeapp.debug.xcconfig */, + 7A4D352CD337FB3A3BF06240 /* Pods-createreactnativeapp.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 13B07F861A680F5B00A75B9A /* createreactnativeapp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "createreactnativeapp" */; + buildPhases = ( + 08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */, + FD10A7F022414F080027D42C /* Start Packager */, + 13B07F871A680F5B00A75B9A /* Sources */, + 13B07F8C1A680F5B00A75B9A /* Frameworks */, + 13B07F8E1A680F5B00A75B9A /* Resources */, + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, + 800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = createreactnativeapp; + productName = createreactnativeapp; + productReference = 13B07F961A680F5B00A75B9A /* createreactnativeapp.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 83CBB9F71A601CBA00E9B192 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1130; + TargetAttributes = { + 13B07F861A680F5B00A75B9A = { + LastSwiftMigration = 1120; + }; + }; + }; + buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "createreactnativeapp" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 83CBB9F61A601CBA00E9B192; + productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 13B07F861A680F5B00A75B9A /* createreactnativeapp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 13B07F8E1A680F5B00A75B9A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BB2F792D24A3F905000567C9 /* Expo.plist in Resources */, + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, + 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, + 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Bundle React Native code and images"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n../node_modules/expo-constants/scripts/get-app-config-ios.sh\n../node_modules/expo-updates/scripts/create-manifest-ios.sh\n"; + }; + 08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-createreactnativeapp-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-createreactnativeapp/Pods-createreactnativeapp-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-createreactnativeapp/Pods-createreactnativeapp-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + FD10A7F022414F080027D42C /* Start Packager */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Start Packager"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 13B07F871A680F5B00A75B9A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, + 13B07FC11A68108700A75B9A /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 13B07FB21A68108700A75B9A /* Base */, + ); + name = LaunchScreen.xib; + path = createreactnativeapp; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 13B07F941A680F5B00A75B9A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6C2E3173556A471DD304B334 /* Pods-createreactnativeapp.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + ENABLE_BITCODE = NO; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "FB_SONARKIT_ENABLED=1", + ); + INFOPLIST_FILE = createreactnativeapp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.name.createreactnativeapp; + PRODUCT_NAME = createreactnativeapp; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 13B07F951A680F5B00A75B9A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7A4D352CD337FB3A3BF06240 /* Pods-createreactnativeapp.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; + INFOPLIST_FILE = createreactnativeapp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.name.createreactnativeapp; + PRODUCT_NAME = createreactnativeapp; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 83CBBA201A601CBA00E9B192 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)"; + LIBRARY_SEARCH_PATHS = ( + "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", + "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"", + "\"$(inherited)\"", + ); + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 83CBBA211A601CBA00E9B192 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)"; + LIBRARY_SEARCH_PATHS = ( + "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", + "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"", + "\"$(inherited)\"", + ); + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "createreactnativeapp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13B07F941A680F5B00A75B9A /* Debug */, + 13B07F951A680F5B00A75B9A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "createreactnativeapp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 83CBBA201A601CBA00E9B192 /* Debug */, + 83CBBA211A601CBA00E9B192 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; +} diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp.xcodeproj/xcshareddata/xcschemes/createreactnativeapp.xcscheme b/examples/advanced/create-react-native-app/ios/createreactnativeapp.xcodeproj/xcshareddata/xcschemes/createreactnativeapp.xcscheme new file mode 100644 index 000000000..75b3acfd8 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp.xcodeproj/xcshareddata/xcschemes/createreactnativeapp.xcscheme @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/AppDelegate.h b/examples/advanced/create-react-native-app/ios/createreactnativeapp/AppDelegate.h new file mode 100644 index 000000000..1a1a48f66 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/AppDelegate.h @@ -0,0 +1,10 @@ +#import +#import +#import +#import + +#import + +@interface AppDelegate : UMAppDelegateWrapper + +@end diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/AppDelegate.m b/examples/advanced/create-react-native-app/ios/createreactnativeapp/AppDelegate.m new file mode 100644 index 000000000..9cb91ea38 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/AppDelegate.m @@ -0,0 +1,111 @@ +#import "AppDelegate.h" + +#import +#import +#import +#import + +#import +#import +#import +#import +#import + +#if defined(FB_SONARKIT_ENABLED) && __has_include() +#import +#import +#import +#import +#import +#import + +static void InitializeFlipper(UIApplication *application) { + FlipperClient *client = [FlipperClient sharedClient]; + SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; + [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; + [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; + [client addPlugin:[FlipperKitReactPlugin new]]; + [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; + [client start]; +} +#endif + +@interface AppDelegate () + +@property (nonatomic, strong) UMModuleRegistryAdapter *moduleRegistryAdapter; +@property (nonatomic, strong) NSDictionary *launchOptions; + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ +#if defined(FB_SONARKIT_ENABLED) && __has_include() + InitializeFlipper(application); +#endif + + self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]]; + self.launchOptions = launchOptions; + self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + #ifdef DEBUG + [self initializeReactNativeApp]; + #else + EXUpdatesAppController *controller = [EXUpdatesAppController sharedInstance]; + controller.delegate = self; + [controller startAndShowLaunchScreen:self.window]; + #endif + + [super application:application didFinishLaunchingWithOptions:launchOptions]; + + return YES; +} + +- (RCTBridge *)initializeReactNativeApp +{ + RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:self.launchOptions]; + RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil]; + rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; + + UIViewController *rootViewController = [UIViewController new]; + rootViewController.view = rootView; + self.window.rootViewController = rootViewController; + [self.window makeKeyAndVisible]; + + return bridge; + } + +- (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge +{ + NSArray> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge]; + // If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here! + return extraModules; +} + +- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { + #ifdef DEBUG + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; + #else + return [[EXUpdatesAppController sharedInstance] launchAssetUrl]; + #endif +} + +- (void)appController:(EXUpdatesAppController *)appController didStartWithSuccess:(BOOL)success { + appController.bridge = [self initializeReactNativeApp]; + EXSplashScreenService *splashScreenService = (EXSplashScreenService *)[UMModuleRegistryProvider getSingletonModuleForClass:[EXSplashScreenService class]]; + [splashScreenService showSplashScreenFor:self.window.rootViewController]; +} + +// Linking API +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { + return [RCTLinkingManager application:application openURL:url options:options]; +} + +// Universal Links +- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { + return [RCTLinkingManager application:application + continueUserActivity:userActivity + restorationHandler:restorationHandler]; +} + +@end diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Base.lproj/LaunchScreen.xib b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Base.lproj/LaunchScreen.xib new file mode 100644 index 000000000..2a3c27a6f --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Base.lproj/LaunchScreen.xib @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..118c98f74 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/Contents.json b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/Contents.json new file mode 100644 index 000000000..2d92bd53f --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreen.imageset/Contents.json b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreen.imageset/Contents.json new file mode 100644 index 000000000..40eb421f8 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreen.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images": [ + { + "idiom": "universal", + "filename": "splashscreen.png", + "scale": "1x" + }, + { + "idiom": "universal", + "scale": "2x" + }, + { + "idiom": "universal", + "scale": "3x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreen.imageset/splashscreen.png b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreen.imageset/splashscreen.png new file mode 100644 index 000000000..cc94f379d Binary files /dev/null and b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreen.imageset/splashscreen.png differ diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreenBackground.imageset/Contents.json b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreenBackground.imageset/Contents.json new file mode 100644 index 000000000..c69ca4ab3 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreenBackground.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images": [ + { + "idiom": "universal", + "filename": "background.png", + "scale": "1x" + }, + { + "idiom": "universal", + "scale": "2x" + }, + { + "idiom": "universal", + "scale": "3x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreenBackground.imageset/background.png b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreenBackground.imageset/background.png new file mode 100644 index 000000000..ff3dd16fd Binary files /dev/null and b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Images.xcassets/SplashScreenBackground.imageset/background.png differ diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Info.plist b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Info.plist new file mode 100644 index 000000000..0c590799e --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Info.plist @@ -0,0 +1,59 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + create-react-native-app + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSExceptionDomains + + localhost + + NSExceptionAllowsInsecureHTTPLoads + + + + + NSLocationWhenInUseUsageDescription + + UILaunchStoryboardName + SplashScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + UIStatusBarStyle + UIStatusBarStyleDefault + + diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/SplashScreen.storyboard b/examples/advanced/create-react-native-app/ios/createreactnativeapp/SplashScreen.storyboard new file mode 100644 index 000000000..24eec3df5 --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/SplashScreen.storyboard @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/Supporting/Expo.plist b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Supporting/Expo.plist new file mode 100644 index 000000000..03410dc8b --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/Supporting/Expo.plist @@ -0,0 +1,10 @@ + + + + + EXUpdatesSDKVersion + YOUR-APP-SDK-VERSION-HERE + EXUpdatesURL + YOUR-APP-URL-HERE + + diff --git a/examples/advanced/create-react-native-app/ios/createreactnativeapp/main.m b/examples/advanced/create-react-native-app/ios/createreactnativeapp/main.m new file mode 100644 index 000000000..25181b6cc --- /dev/null +++ b/examples/advanced/create-react-native-app/ios/createreactnativeapp/main.m @@ -0,0 +1,10 @@ +#import + +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} + diff --git a/examples/advanced/create-react-native-app/metro.config.js b/examples/advanced/create-react-native-app/metro.config.js new file mode 100644 index 000000000..ba9728366 --- /dev/null +++ b/examples/advanced/create-react-native-app/metro.config.js @@ -0,0 +1,5 @@ +module.exports = { + transformer: { + assetPlugins: ['expo-asset/tools/hashAssetFiles'], + }, +}; diff --git a/examples/advanced/create-react-native-app/package.json b/examples/advanced/create-react-native-app/package.json new file mode 100644 index 000000000..240a459d9 --- /dev/null +++ b/examples/advanced/create-react-native-app/package.json @@ -0,0 +1,36 @@ +{ + "main": "index.js", + "scripts": { + "android": "react-native run-android", + "ios": "react-native run-ios", + "web": "expo start --web", + "start": "react-native start", + "test": "jest" + }, + "dependencies": { + "expo": "~40.0.0", + "expo-cli": "^4.0.13", + "expo-splash-screen": "~0.8.0", + "expo-status-bar": "~1.0.3", + "expo-updates": "~0.4.0", + "react": "16.13.1", + "react-dom": "16.13.1", + "react-native": "~0.63.4", + "react-native-gesture-handler": "~1.8.0", + "react-native-reanimated": "~1.13.0", + "react-native-screens": "~2.15.0", + "react-native-unimodules": "~0.12.0", + "react-native-web": "~0.13.12" + }, + "devDependencies": { + "@babel/core": "~7.9.0", + "babel-jest": "~25.2.6", + "jest": "~25.2.6", + "react-test-renderer": "~16.13.1", + "style-dictionary": "3.0.0-rc.10" + }, + "jest": { + "preset": "react-native" + }, + "private": true +} \ No newline at end of file diff --git a/examples/advanced/create-react-native-app/src/App.js b/examples/advanced/create-react-native-app/src/App.js new file mode 100644 index 000000000..05b4b3da7 --- /dev/null +++ b/examples/advanced/create-react-native-app/src/App.js @@ -0,0 +1,31 @@ +import { StatusBar } from "expo-status-bar"; +import React from "react"; +import { StyleSheet, Text, View, PixelRatio } from "react-native"; +import * as variables from "./style-dictionary-dist/variables"; + +export default function App() { + return ( + + Testing! Testing! + All done! + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: variables.colorBrand01, + alignItems: "center", + justifyContent: "center", + }, + title: { + fontSize: PixelRatio.getFontScale() * variables.sizeFontMd.scale, + color: variables.colorBrand02, + }, + p: { + fontSize: PixelRatio.getFontScale() * variables.sizeFontSm.number, + color: variables.colorBrand02, + }, +}); diff --git a/examples/advanced/create-react-native-app/src/style-dictionary-dist/variables.js b/examples/advanced/create-react-native-app/src/style-dictionary-dist/variables.js new file mode 100644 index 000000000..888a75bca --- /dev/null +++ b/examples/advanced/create-react-native-app/src/style-dictionary-dist/variables.js @@ -0,0 +1,9 @@ +/** + * Do not edit directly + * Generated on Fri, 18 Dec 2020 00:08:57 GMT + */ + +export const colorBrand01 = "#eeeeff"; +export const colorBrand02 = "#ddaa33"; +export const sizeFontSm = {"original":"16px","number":16,"decimal":0.16,"scale":256}; +export const sizeFontMd = {"original":"2rem","number":2,"decimal":0.02,"scale":32}; \ No newline at end of file diff --git a/examples/advanced/create-react-native-app/style-dictionary/properties/color/brand.json b/examples/advanced/create-react-native-app/style-dictionary/properties/color/brand.json new file mode 100644 index 000000000..aa9b7ef30 --- /dev/null +++ b/examples/advanced/create-react-native-app/style-dictionary/properties/color/brand.json @@ -0,0 +1,18 @@ +{ + "color": { + "brand": { + "01": { + "value": "#eef", + "attributes": { + "category": "color" + } + }, + "02": { + "value": "#da3", + "attributes": { + "category": "color" + } + } + } + } +} diff --git a/examples/advanced/create-react-native-app/style-dictionary/properties/size/size.json b/examples/advanced/create-react-native-app/style-dictionary/properties/size/size.json new file mode 100644 index 000000000..06b26333b --- /dev/null +++ b/examples/advanced/create-react-native-app/style-dictionary/properties/size/size.json @@ -0,0 +1,18 @@ +{ + "size": { + "font": { + "sm": { + "value": "16px", + "attributes": { + "category": "size" + } + }, + "md": { + "value": "2rem", + "attributes": { + "category": "size" + } + } + } + } +} diff --git a/examples/advanced/custom-file-header/README.md b/examples/advanced/custom-file-header/README.md new file mode 100644 index 000000000..7fb21736f --- /dev/null +++ b/examples/advanced/custom-file-header/README.md @@ -0,0 +1,44 @@ +## Custom File Header + +Style Dictionary 3.0 added the ability to define custom file headers for files generated from formats. A file header is a comment at the beginning of the generated file that has some information about how it was generated. This is fairly common in build tools that output source code. Before 3.0 you could only show or hide this header in the built-in formats. Now you can write your own custom file header messages that can be used in built-in formats as well as custom formats. + +Use cases include: + +- Using a version number or hash in the file header comment +- Using your own custom message + + +#### Running the example + +First of all, set up the required dependencies running the command `npm ci` 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 output files in the `build` folder. Just to show how file headers work, this example outputs a bunch of files with the same code, but different file header comments. + + +#### How does it work + +There are 3 ways to add a custom file header: + +1. Using the `registerFileHeader` method, and then referencing the name in the file configuration. +1. Adding a `fileHeader` object to the Style Dictionary configuration, and then referencing the key in the file configuration +1. Writing the `fileHeader` as a function in the platform or file configuration + +This example codebase has all 3 methods for you to see which works best for you. All 3 methods are in the [**build.js**](/build.js) file. + +A file header is a function that returns an array of strings. This array of strings will get mapped to lines in a comment at the beginning of a file generated by a formatter. The formatter will take care of how to format the lines in the proper comment style (`//`, `/* */`). + +You can reference the file header in a custom format as well by using the `fileHeader` function in `StyleDictionary.formatHelpers`, as shown below: + +```javascript +const {fileHeader} = StyleDictionary.formatHelpers; + +const myCustomFormat = ({ dictionary, file }) => { + return `${fileHeader({file, commentStyle: 'short'})}${dictionary.allTokens.map(token => { + return `--${token.name}: ${token.value};` + }).join(`\n`)}` +} +``` + +#### What to look at + +* **build.js** Has everything you need diff --git a/examples/advanced/custom-file-header/build.js b/examples/advanced/custom-file-header/build.js new file mode 100644 index 000000000..70c4f2518 --- /dev/null +++ b/examples/advanced/custom-file-header/build.js @@ -0,0 +1,120 @@ +const crypto = require('crypto'); +const StyleDictionary = require('style-dictionary'); +const version = require('./package.json').version; + +// You can use the `fileHeader` format helper function +// This function will use any custom file headers or the default +// file header +const {fileHeader} = StyleDictionary.formatHelpers; + +const myCustomFormat = ({ dictionary, file }) => { + return `${fileHeader({file, commentStyle: 'short'})}${dictionary.allTokens.map(token => { + return `--${token.name}: ${token.value};` + }).join(`\n`)}` +} + +const styleDictionary = StyleDictionary.extend({ + // You can add custom file headers directly on the configuration by + // adding a `fileHeader` object. The keys inside are the names of + // the file headers + fileHeader: { + // defaultMessage is the built-in file header message: + // Do not edit directly + // Generated on Sat, 01 Jan 2000 00:00:00 GMT + myFileHeader: (defaultMessage) => { + // A file header function is expected to return an array of strings. + // This array will be mapped to the proper comment style for a given format. + // For example, Android XML formats use XML comments: , + // whereas other languages have short and long style comments, // and /* */ + return [ + ...defaultMessage, + 'hello, world!' + ]; + } + }, + + format: { + myCustomFormat + }, + + source: [`tokens/**/*.json`], + + platforms: { + css: { + transformGroup: `css`, + buildPath: `build/`, + files: [{ + destination: `variables.css`, + format: `css/variables`, + options: { + // You can now reference a custom file header in a file's options. + fileHeader: `myFileHeader` + } + },{ + destination: `variables1.css`, + format: `myCustomFormat`, + options: { + fileHeader: `myFileHeader` + } + },{ + destination: `variables2.css`, + format: `css/variables`, + options: { + // You can also directly pass a function to the `fileHeader` option: + fileHeader: () => { + return [ + `build version ${version}` + ] + } + } + }] + }, + js: { + transformGroup: `js`, + buildPath: `build/`, + // You can also add a header at the platform level. + // Platform-level options cascade down to files. + options: { + fileHeader: `customFileHeader` + }, + files: [{ + destination: `colors.js`, + format: `javascript/es6` + },{ + destination: `colors2.js`, + format: `javascript/es6`, + // This file won't get the custom header because it defines the + // showFileHeader option to false + options: { + showFileHeader: false + } + },{ + destination: `colors3.js`, + format: `javascript/es6`, + // This file will use the custom header defined here because the file's + // options take precedence over the platform's options. + options: { + fileHeader: () => [`Header overridden`] + } + }] + } + } +}); + +// Create a hash of style dictionary tokens object to use in a file header +const hash = crypto.createHash('md5') + .update(JSON.stringify(styleDictionary.tokens)) + .digest('hex'); + +// Adding a custom file header with the `.registerFileHeader` +styleDictionary.registerFileHeader({ + name: `customFileHeader`, + fileHeader: () => { + return [ + `Do not edit directly`, + `build hash ${hash}` + ] + } +}); + +styleDictionary.buildAllPlatforms(); \ No newline at end of file diff --git a/examples/advanced/custom-file-header/package-lock.json b/examples/advanced/custom-file-header/package-lock.json new file mode 100644 index 000000000..242aca09f --- /dev/null +++ b/examples/advanced/custom-file-header/package-lock.json @@ -0,0 +1,225 @@ +{ + "name": "custom-file-header", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "style-dictionary": { + "version": "3.0.0-rc.6", + "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-3.0.0-rc.6.tgz", + "integrity": "sha512-EI0B3n9NnL/dmMWSSg18/CEqCamG9/fxYetS0kvBDfuSkXxDuBEwLfta1+GvSKF8b+/01WweITrazaUS991VIQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.6", + "json5": "^2.1.3", + "lodash": "^4.17.15", + "tinycolor2": "^1.4.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/examples/advanced/custom-file-header/package.json b/examples/advanced/custom-file-header/package.json new file mode 100644 index 000000000..1d08ffaaf --- /dev/null +++ b/examples/advanced/custom-file-header/package.json @@ -0,0 +1,15 @@ +{ + "name": "custom-file-header", + "version": "1.0.0", + "description": "", + "main": "sd.config.js", + "scripts": { + "build": "node build.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "style-dictionary": "3.0.0-rc.10" + } +} \ No newline at end of file diff --git a/examples/advanced/custom-file-header/tokens/color.json b/examples/advanced/custom-file-header/tokens/color.json new file mode 100644 index 000000000..02bedfcc6 --- /dev/null +++ b/examples/advanced/custom-file-header/tokens/color.json @@ -0,0 +1,9 @@ +{ + "color": { + "core": { + "red": { "value": "#ff0000" }, + "blue": { "value": "#00ff00" }, + "green": { "value": "#0000ff" } + } + } +} \ No newline at end of file diff --git a/examples/advanced/custom-formats-with-templates/build.js b/examples/advanced/custom-formats-with-templates/build.js index e7bc05e18..2a5d541e8 100644 --- a/examples/advanced/custom-formats-with-templates/build.js +++ b/examples/advanced/custom-formats-with-templates/build.js @@ -35,13 +35,13 @@ const templateCustomXml = handlebars.compile(fs.readFileSync(__dirname + '/templ StyleDictionary.registerFormat({ name: 'custom/format/android-xml-alt', - formatter: function(dictionary, platform) { + formatter: function({dictionary, platform}) { return templateCustomXml({ // this is to show that the formatter function only takes a "dictionary" and "platform" parameters - // (and dictionary has a "properties" and "allProperties" attributes) + // (and dictionary has "tokens" and "allTokens" attributes) // and returns a string. for more details about the "formatter" function refer to the documentation - allProperties: dictionary.allProperties, - properties: dictionary.properties, + allTokens: dictionary.allTokens, + tokens: dictionary.tokens, options: platform }); } @@ -53,9 +53,9 @@ const templateCustomPlist = pug.compileFile(__dirname + '/templates/ios-plist_al StyleDictionary.registerFormat({ name: 'custom/format/ios-plist-alt', - formatter: function(dictionary) { + formatter: function({dictionary}) { return templateCustomPlist({ - allProperties: dictionary.allProperties + allTokens: dictionary.allTokens }); } }); diff --git a/examples/advanced/custom-formats-with-templates/package.json b/examples/advanced/custom-formats-with-templates/package.json index 498d4daca..f532c3d89 100644 --- a/examples/advanced/custom-formats-with-templates/package.json +++ b/examples/advanced/custom-formats-with-templates/package.json @@ -18,6 +18,6 @@ "handlebars": "^4.7.7", "lodash": "^4.17.21", "pug": "^3.0.2", - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/custom-formats-with-templates/templates/android-xml.template b/examples/advanced/custom-formats-with-templates/templates/android-xml.template index 013273c61..f00a17f73 100644 --- a/examples/advanced/custom-formats-with-templates/templates/android-xml.template +++ b/examples/advanced/custom-formats-with-templates/templates/android-xml.template @@ -1,5 +1,5 @@ <% -var allProperties = _.each(allProperties, function(prop) { +var allTokens = _.each(allTokens, function(prop) { if(prop.attributes.category === 'color') { prop.tag = 'color'; } else if(prop.attributes.category === 'size') { @@ -13,7 +13,7 @@ var allProperties = _.each(allProperties, function(prop) { } }); %> -<% _.each(allProperties, function(prop) { +<% _.each(allTokens, function(prop) { // Notice: this is an alternative way to use Lodash templating syntax, // that uses string concatenation and the print() function to have // more control over the indentation, whitespace, newlines, etc. diff --git a/examples/advanced/custom-formats-with-templates/templates/android-xml_alt.hbs b/examples/advanced/custom-formats-with-templates/templates/android-xml_alt.hbs index 7b9a44063..c2ebf22b9 100644 --- a/examples/advanced/custom-formats-with-templates/templates/android-xml_alt.hbs +++ b/examples/advanced/custom-formats-with-templates/templates/android-xml_alt.hbs @@ -1,4 +1,4 @@ -{{#each allProperties}} +{{#each allTokens}} {{value}} {{/each}} diff --git a/examples/advanced/custom-formats-with-templates/templates/ios-plist.template b/examples/advanced/custom-formats-with-templates/templates/ios-plist.template index 3344a70fc..e62f75ae6 100644 --- a/examples/advanced/custom-formats-with-templates/templates/ios-plist.template +++ b/examples/advanced/custom-formats-with-templates/templates/ios-plist.template @@ -2,7 +2,7 @@ <% -var allProperties = _.each(allProperties, function(prop) { +var allTokens = _.each(allTokens, function(prop) { if(prop.type === 'color') { prop.tag = 'string'; } else if(prop.type === 'size') { @@ -17,7 +17,7 @@ var allProperties = _.each(allProperties, function(prop) { }); %> - <% _.each(allProperties, function(prop) { + <% _.each(allTokens, function(prop) { %><%= prop.name %><<%= prop.tag %>><%= prop.value %>><% if (prop.comment) { %><% } %> <% }); %> diff --git a/examples/advanced/custom-formats-with-templates/templates/ios-plist_alt.pug b/examples/advanced/custom-formats-with-templates/templates/ios-plist_alt.pug index 9a7659b09..f6cc4cf8a 100644 --- a/examples/advanced/custom-formats-with-templates/templates/ios-plist_alt.pug +++ b/examples/advanced/custom-formats-with-templates/templates/ios-plist_alt.pug @@ -1,6 +1,6 @@ -each prop in allProperties - case prop.attributes.category +each token in allTokens + case token.attributes.category when 'color' - var tag = 'string' when 'size' @@ -13,12 +13,12 @@ each prop in allProperties - var tag = 'string' default - var tag = 'string' - key #{prop.name} + key #{token.name} dict - if prop.comment - // #{prop.comment} - if prop.type + if token.comment + // #{token.comment} + if token.type key type - string #{prop.type} + string #{token.type} key value - #{tag}(name=prop.name) #{prop.value} + #{tag}(name=token.name) #{token.value} diff --git a/examples/advanced/custom-formats-with-templates/templates/web-scss.template b/examples/advanced/custom-formats-with-templates/templates/web-scss.template index f24364c8d..546acdb42 100644 --- a/examples/advanced/custom-formats-with-templates/templates/web-scss.template +++ b/examples/advanced/custom-formats-with-templates/templates/web-scss.template @@ -1,3 +1,3 @@ -<% _.each(allProperties, function(prop) { +<% _.each(allTokens, function(prop) { %>$<%= prop.name %>: <%= prop.value %>;<% if (prop.comment) { %> // <%= prop.comment %><% } %> <% }); %> \ No newline at end of file diff --git a/examples/advanced/custom-parser/README.md b/examples/advanced/custom-parser/README.md new file mode 100644 index 000000000..150ab1032 --- /dev/null +++ b/examples/advanced/custom-parser/README.md @@ -0,0 +1,56 @@ +## Custom Parsers + +Style Dictionary 3.0 added the ability to define custom parsers for source files. Before 3.0, the source files for Style Dictionary had to be JSON, JSON5, or Node modules (unless you wanted to read and merge the data yourself outside of Style Dictionary). Now you can define custom parsers that run on certain files based on a file path pattern regular expression (similar to how Webpack loaders work). + +Use cases include: + +- Using YAML instead of JSON, JSON5, or Node modules as the source language for Style Dictionary files +- Adding custom metadata when source files are parsed + + +#### Running the example + +First of all, set up the required dependencies running the command `npm ci` 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 output files in the `build` folder. Just to show how custom parsers work, this example only has 2 design tokens and outputs a single CSS variables file. + +#### How does it work + +You can define custom parsers in 2 ways: +1. With the `.registerParser` method +1. Adding a `parsers` array to the Style Dictionary configuration + +A parser is an object with a `pattern` attribute that is a regular expression, and a `parse` attribute that is a function. The `parse` function accepts `contents` and `filePath` as named arguments and should return a plain Javascript object. + +```javascript +{ + pattern: /\.json$/, + parse: ({contents, filePath}) => { + return JSON.parse(contents); + } +} +``` + +Because parsers work on the source files for Style Dictionary, they need to be defined at or before the configuration is passed to Style Dictionary through the `.extend` method. + +```javascript +const StyleDictionary = require('style-dictionary'); + +const styleDictionary = StyleDictionary.extend({ + source: [`tokens/**/*.json`], + //.. +}); + +// This won't work because Style Dictionary has already parsed the source files +// in the .extend method +styleDictionary.registerParser({ + pattern: /\.json$/, + parse: ({contents, filePath}) => { + return JSON.parse(contents); + } +}) +``` + +#### What to look at + +* **sd.config.js** Has everything you need \ No newline at end of file diff --git a/examples/advanced/custom-parser/package-lock.json b/examples/advanced/custom-parser/package-lock.json new file mode 100644 index 000000000..81b745d98 --- /dev/null +++ b/examples/advanced/custom-parser/package-lock.json @@ -0,0 +1,248 @@ +{ + "name": "style-dictionary-example-custom-parser", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs-extra": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", + "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "style-dictionary": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-2.10.0.tgz", + "integrity": "sha512-H4NpAKExmQdSMLNm9jVY8Kv+qfliFOgpxl07mqL+NyMMRs7HjR8IDvNJfxYqiVm0BhSpwFAp/hkUlD+8i7+P8w==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "commander": "^2.9.0", + "fs-extra": "^6.0.1", + "glob": "^7.1.1", + "json5": "^2.1.0", + "lodash": "^4.17.15", + "resolve-cwd": "^2.0.0", + "tinycolor2": "^1.4.1" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tinycolor2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", + "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/examples/advanced/custom-parser/package.json b/examples/advanced/custom-parser/package.json new file mode 100644 index 000000000..6e2fa9e12 --- /dev/null +++ b/examples/advanced/custom-parser/package.json @@ -0,0 +1,14 @@ +{ + "name": "style-dictionary-example-custom-parser", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "style-dictionary build --config ./sd.config.js" + }, + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "style-dictionary": "3.0.0-rc.10" + } +} \ No newline at end of file diff --git a/examples/advanced/custom-parser/sd.config.js b/examples/advanced/custom-parser/sd.config.js new file mode 100644 index 000000000..afcd3dc99 --- /dev/null +++ b/examples/advanced/custom-parser/sd.config.js @@ -0,0 +1,73 @@ +const StyleDictionary = require('style-dictionary'); + +// You can use the .registerParser() method like this +StyleDictionary.registerParser({ + pattern: /\.json$/, + parse: ({contents, filePath}) => { + // Probably a good idea to wrap this in a try/catch block + try { + const object = JSON.parse(contents); + // You can now perform any modifications to the file content + // or perform any side-effects based on the file + + // Here we are going to grab the filepath and turn it into a prefix. + // tokens/color/core.json will become 'color-core'. We will append this + // to all token names. + const pathParts = filePath.replace(__dirname + '/tokens/', '') + .replace('.json','') + .split('/') + .join('-'); + + const output = {}; + + for (const key in object) { + if (object.hasOwnProperty(key)) { + const element = object[key]; + output[`${pathParts}-${key}`] = element; + } + } + + return output; + } catch (error) { + console.log(error); + } + } +}); + +// Or you can add parsers directly on the configuration object here like this: +// StyleDictionary.extend({ +// parsers: [{ +// pattern: /\.json$/, +// parse: ({contents, filePath}) => {} +// }], +// source: [`tokens/**/*.json`], +// platforms: { +// css: { +// transformGroup: 'css', +// buildPath: 'build/', +// files: [{ +// destination: 'variables.css', +// format: 'css/variables' +// }] +// } +// } +// }).buildAllPlatforms(); + +module.exports = { + // Or you can add parsers directly on the configuration object here like this: + // parsers: [{ + // pattern: /\.json$/, + // parse: ({contents, filePath}) => {} + // }], + source: [`tokens/**/*.json`], + platforms: { + css: { + transformGroup: 'css', + buildPath: 'build/', + files: [{ + destination: 'variables.css', + format: 'css/variables' + }] + } + } +} diff --git a/examples/advanced/custom-parser/tokens/color/core.json b/examples/advanced/custom-parser/tokens/color/core.json new file mode 100644 index 000000000..ec0599de5 --- /dev/null +++ b/examples/advanced/custom-parser/tokens/color/core.json @@ -0,0 +1,4 @@ +{ + "blue": { "value": "#0000ff" }, + "red": { "value": "#ff0000" } +} diff --git a/examples/advanced/custom-transforms/README.md b/examples/advanced/custom-transforms/README.md index f7cdad8ed..b766b8503 100644 --- a/examples/advanced/custom-transforms/README.md +++ b/examples/advanced/custom-transforms/README.md @@ -1,15 +1,15 @@ ## Custom transforms (and transformGroups) -This example shows how to use custom transforms (and transformGroups) to apply custom "transformations" to the properties when converted to design tokens. +This example shows how to use custom transforms (and transformGroups) to apply custom "transformations" to the design tokens. -Transforms are functions that transform a property (in a non-destructive way). The reason for *transforms* is that in this way each platform can consume the property in different ways (eg. changing *pixel* values to *pt* values for iOS, and *dp* or *sp* for Android). +Transforms are functions that modify a design token (in a non-destructive way). The reason for *transforms* is that in this way each platform can consume the token in different ways (eg. changing *pixel* values to *pt* values for iOS, and *dp* or *sp* for Android). **Remember**: transforms are performed sequentially, hence the order you use transforms matters. -The need for custom transforms is that Style Dictionary expects the properties to be declared according to certain criteria, to use the pre-defined transforms and formats/templates. For example, the *web* transformGroup consists of the *attribute/cti*, *name/cti/kebab*, *size/px* and *color/css* transforms. -The *size/px* adds 'px' to the end of the number, and is applied only if `prop.attributes.category === 'size'`. This means that your property needs to be expressed without units, and be under the *'size'* "category. If you need a different logic or you want to organise your properties differently, probably you can't use the out-of-the-box transformation groups, but you have to declare your custom ones. +The need for custom transforms is that Style Dictionary expects the tokens to be declared according to certain criteria, to use the pre-defined transforms and formats/templates. For example, the *web* transformGroup consists of the *attribute/cti*, *name/cti/kebab*, *size/px* and *color/css* transforms. +The *size/px* adds 'px' to the end of the number, and is applied only if `token.attributes.category === 'size'`. This means that your token needs to be expressed without units, and be under the *'size'* "category. If you need a different logic or you want to organize your tokens differently, probably you can't use the out-of-the-box transformation groups, but you have to declare your custom ones. -If [custom formats](../custom-formats-with-templates/) are the way to allow users to customise the format of the *output* of Style Dictionary, custom transforms are the way to allow them to customise both the *input* (the property names/values/attributes) and the *output* (the actual values expressed in the design tokens). For these reasons, custom transforms are probably one of the **most powerful features** of Style Dictionary: they make it extremely versatile, allowing limitless possibilities of extension and customisation of the entire pipeline from properties to design tokens. +If [custom formats](../custom-formats-with-templates/) are the way to allow users to customize the format of the *output* of Style Dictionary, custom transforms are the way to allow them to customize both the *input* (the token names/values/attributes) and the *output* (the actual values expressed in the design tokens). For this reasons, custom transforms are probably one of the **most powerful features** of Style Dictionary: they make it extremely versatile, allowing limitless possibilities of extension and customization of the entire design token pipeline. #### Running the example @@ -25,11 +25,11 @@ To declare a custom **transform**, you have to call the `registerTransform` meth StyleDictionary.registerTransform({ name: 'ratio/%', type: 'value', - matcher: function(prop) { - return prop.group === 'ratio'; + matcher: function(token) { + return token.group === 'ratio'; }, - transformer: function(prop) { - return `${Math.floor(100 * prop.value)}%`; + transformer: function(token) { + return `${Math.floor(100 * token.value)}%`; } }); ``` @@ -53,7 +53,7 @@ Once registered, the custom group can be associated to one or more **platforms** ``` { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "web": { "transformGroup": "custom/web", @@ -75,16 +75,16 @@ in your code and look the array of transforms associated with the it, directly i Open the `config.json` file and see how for each platform there is a `transformGroup` declaration. In this specific example, all the transformGroups applied to the platforms are custom. -Now open a property file (eg. `colors|font|spacing.json`) to see how we have associated custom attributes to the properties, to be used later in the matcher functions. See also how the values are unitless, where the units are applied at build time accordingly to the destination platform. Compare the values in the input JSON files, and the values that appear in the files generated in `build`, and you will see where and how the transformations have been applied. +Now open a token file (eg. `tokens/colors|font|spacing.json`) to see how we have associated custom attributes to the tokens, to be used later in the matchers functions. See also how the values are unit-less, where the units are applied at build time accordingly to the destination platform. Compare the values in the input JSON files, and the values that appear in the files generated in `build`, and you will see where and how the transformations have been applied. Now open the `build.js` script and look at how these custom transforms/transformGroups are declared and registered via the `registerTransform` and `registerTransform` API methods. We have added as many comments as possible to make the code clear and show the interesting parts of it. A few things to notice in the file: - the name of a custom "transform" can be the same as an existing pre-defined method; in that case, the pre-defined method is overwritten -- beyond the existing attributes, you can use custom attributes to create **matcher** functions, used to filter the properties and apply the transform only to those that match the filter condition. -- if you don't specify a **matcher**, the transformation will be applied to all the properties -- the transformation can be applied not only to the **value** of a property, but also to its **name** (and also to its attributes) +- beyond the existing attributes, you can use custom attributes to create **matcher** functions, used to filter the tokens and apply the transform only to those that match the filter condition. +- if you don't specify a **matcher**, the transformation will be applied to all the tokens +- the transformation can be applied not only to the **value** of a token, but also to its **name** (and also to its attributes) **IMPORTANT**: the registration of custom transforms needs to be done _before_ applying the configuration (the methods needs to be already declared and registered in Style Dictionary to be used when extending it with the configuration). See the code in the `build.js` for more details. diff --git a/examples/advanced/custom-transforms/build.js b/examples/advanced/custom-transforms/build.js index a299ad0a6..7a363fe7b 100644 --- a/examples/advanced/custom-transforms/build.js +++ b/examples/advanced/custom-transforms/build.js @@ -9,58 +9,58 @@ console.log('\n=============================================='); StyleDictionary.registerTransform({ name: 'size/px', // notice: the name is an override of an existing predefined method (yes, you can do it) type: 'value', - matcher: function(prop) { + matcher: function(token) { // this is an example of a possible filter (based on the "cti" values) to show how a "matcher" works - return prop.attributes.category === 'font' || prop.attributes.category === 'margin'; + return token.attributes.category === 'font' || token.attributes.category === 'margin'; }, - transformer: function(prop) { - return `${prop.value}px`; + transformer: function(token) { + return `${token.value}px`; } }); StyleDictionary.registerTransform({ name: 'ratio/%', type: 'value', - matcher: function(prop) { - // here we are using a custom attribute, declared in the property, to match the values where apply the transform - return prop.group === 'ratio'; + matcher: function(token) { + // here we are using a custom attribute, declared in the token, to match the values where apply the transform + return token.group === 'ratio'; }, - transformer: function(prop) { - return `${Math.floor(100 * prop.value)}%`; + transformer: function(token) { + return `${Math.floor(100 * token.value)}%`; } }); StyleDictionary.registerTransform({ name: 'hexRGB/hexARGB', type: 'value', - matcher: function(prop) { - return prop.group === 'color'; + matcher: function(token) { + return token.group === 'color'; }, - transformer: function(prop) { + transformer: function(token) { // for sake of simplicity, in this example we assume colors are always in the format #xxxxxx - return prop.value.replace(/^#/,'#FF'); + return token.value.replace(/^#/,'#FF'); } }); StyleDictionary.registerTransform({ name: 'unitless/dp-sp', type: 'value', - matcher: function(prop) { - return prop.group === 'typography' || prop.group === 'spacing'; + matcher: function(token) { + return token.group === 'typography' || token.group === 'spacing'; }, - transformer: function(prop) { + transformer: function(token) { // in Android font sizes are expressed in "sp" units - let unit = (prop.group === 'typography') ? 'sp' : 'dp'; - return `${prop.value}${unit}`; + let unit = (token.group === 'typography') ? 'sp' : 'dp'; + return `${token.value}${unit}`; } }); StyleDictionary.registerTransform({ // this is a silly example, to show how you can apply transform to names name: 'name/squiggle', type: 'name', - // notice: if you don't specify a matcher, the transformation will be applied to all the properties - transformer: function(prop) { - return prop.path.join('~'); + // notice: if you don't specify a matcher, the transformation will be applied to all the tokens + transformer: function(token) { + return token.path.join('~'); } }); @@ -96,8 +96,8 @@ StyleDictionary.registerTransformGroup({ StyleDictionary.registerFormat({ name: 'custom/android/xml', formatter: function(dictionary) { - return dictionary.allProperties.map(function(prop) { - return `${prop.value}`; + return dictionary.allTokens.map(function(token) { + return `${token.value}`; }).join('\n'); } }); @@ -106,7 +106,7 @@ StyleDictionary.registerFormat({ // APPLY THE CONFIGURATION // IMPORTANT: the registration of custom transforms // needs to be done _before_ applying the configuration -StyleDictionaryExtended = StyleDictionary.extend(__dirname + '/config.json'); +const StyleDictionaryExtended = StyleDictionary.extend(__dirname + '/config.json'); // FINALLY, BUILD ALL THE PLATFORMS diff --git a/examples/advanced/custom-transforms/config.json b/examples/advanced/custom-transforms/config.json index ac0842a43..c916ea159 100644 --- a/examples/advanced/custom-transforms/config.json +++ b/examples/advanced/custom-transforms/config.json @@ -1,5 +1,5 @@ { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "web": { "transformGroup": "custom/web", diff --git a/examples/advanced/custom-transforms/package.json b/examples/advanced/custom-transforms/package.json index d0506f670..78b935e35 100644 --- a/examples/advanced/custom-transforms/package.json +++ b/examples/advanced/custom-transforms/package.json @@ -15,6 +15,6 @@ "author": "", "license": "Apache-2.0", "devDependencies": { - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/custom-transforms/properties/button.json b/examples/advanced/custom-transforms/tokens/button.json similarity index 100% rename from examples/advanced/custom-transforms/properties/button.json rename to examples/advanced/custom-transforms/tokens/button.json diff --git a/examples/advanced/custom-transforms/properties/colors.json b/examples/advanced/custom-transforms/tokens/colors.json similarity index 100% rename from examples/advanced/custom-transforms/properties/colors.json rename to examples/advanced/custom-transforms/tokens/colors.json diff --git a/examples/advanced/custom-transforms/properties/font.json b/examples/advanced/custom-transforms/tokens/font.json similarity index 100% rename from examples/advanced/custom-transforms/properties/font.json rename to examples/advanced/custom-transforms/tokens/font.json diff --git a/examples/advanced/custom-transforms/properties/spacing.json b/examples/advanced/custom-transforms/tokens/spacing.json similarity index 100% rename from examples/advanced/custom-transforms/properties/spacing.json rename to examples/advanced/custom-transforms/tokens/spacing.json diff --git a/examples/advanced/format-helpers/README.md b/examples/advanced/format-helpers/README.md new file mode 100644 index 000000000..873bbb773 --- /dev/null +++ b/examples/advanced/format-helpers/README.md @@ -0,0 +1,17 @@ +## Format Helpers + +This example shows how to use the format helper methods to create custom formats. + +#### 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, if you want to build the tokens you can run `npm run build`. This command will run the Style Dictionary CLI with the **sd.config.js** as the configuration file and will generate the files in the `build` folder. + +#### How does it work? + +Starting in version 3.0, Style Dictionary exposes internal helper methods for formats. In the configuration we are defining custom formats using some of those format helper methods. + +#### What to look at + +The [`sd.config.js`](sd.config.js) file has everything you need to know. diff --git a/examples/advanced/format-helpers/package-lock.json b/examples/advanced/format-helpers/package-lock.json new file mode 100644 index 000000000..cf73b7f6a --- /dev/null +++ b/examples/advanced/format-helpers/package-lock.json @@ -0,0 +1,842 @@ +{ + "name": "format-helpers", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "style-dictionary": "3.0.0-rc.9" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "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" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/style-dictionary": { + "version": "3.0.0-rc.9", + "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-3.0.0-rc.9.tgz", + "integrity": "sha512-DATZSs8IP89flgX1GpPmwPzZVYTGRceGbrV6tNAGunX0O9KHiB087hadCh+Ai5krqlA4sagBJJcTCFXCFSP9BA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "change-case": "^4.1.2", + "commander": "^5.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.6", + "json5": "^2.1.3", + "lodash": "^4.17.15", + "tinycolor2": "^1.4.1" + }, + "bin": { + "style-dictionary": "bin/style-dictionary" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "requires": { + "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" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "requires": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "style-dictionary": { + "version": "3.0.0-rc.9", + "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-3.0.0-rc.9.tgz", + "integrity": "sha512-DATZSs8IP89flgX1GpPmwPzZVYTGRceGbrV6tNAGunX0O9KHiB087hadCh+Ai5krqlA4sagBJJcTCFXCFSP9BA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "change-case": "^4.1.2", + "commander": "^5.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.6", + "json5": "^2.1.3", + "lodash": "^4.17.15", + "tinycolor2": "^1.4.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", + "dev": true + }, + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/examples/advanced/format-helpers/package.json b/examples/advanced/format-helpers/package.json new file mode 100644 index 000000000..b948eb878 --- /dev/null +++ b/examples/advanced/format-helpers/package.json @@ -0,0 +1,15 @@ +{ + "name": "format-helpers", + "version": "1.0.0", + "description": "", + "main": "sd.config.js", + "scripts": { + "build": "style-dictionary build --config ./sd.config.js" + }, + "keywords": [], + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "style-dictionary": "3.0.0-rc.10" + } +} \ No newline at end of file diff --git a/examples/advanced/format-helpers/sd.config.js b/examples/advanced/format-helpers/sd.config.js new file mode 100644 index 000000000..1c9b25269 --- /dev/null +++ b/examples/advanced/format-helpers/sd.config.js @@ -0,0 +1,94 @@ +const StyleDictionary = require('style-dictionary'); + +const { + createPropertyFormatter, + fileHeader, + formattedVariables, + sortByReference +} = StyleDictionary.formatHelpers; + +module.exports = { + format: { + myFormat: ({ dictionary, options, file }) => { + const { outputReferences } = options; + // createPropertyFormatter will return a function that can be passed to + // .map() to format each token. Pass it the `outputReferences` and dictionary + // along with a formatting object that tells the function how to format + // each line. + const formatProperty = createPropertyFormatter({ + outputReferences, + dictionary, + formatting: { + prefix: '$', + separator: ':', + suffix: ';' + } + }); + + // fileHeader takes in the file configuration as well as a commentStyle + // or formatting object and will generate a file header comment in the + // proper style. If the file has a custom file header defined, or + // showFileHeader option, it will honor those. + return fileHeader({file, commentStyle: 'short'}) + + dictionary.allProperties + // sortByReference returns a function that can be used as to sort + // an array. This will sort the array so that references always + // come after their instantiation so that there are no errors + // when consuming this file. + .sort(sortByReference(dictionary)) + .map(formatProperty) + .join('\n'); + }, + + // You could also use the formattedVariables function which is a quicker + // way to do all the steps above. It will take formatting information + // and sort and map all the tokens. + myOtherFormat: ({ dictionary, options, file }) => { + const { outputReferences } = options; + const lineSeparator = `\n`; + + // Here we are using fileHeader with a formatting object, + // this will show the file header with a block-style comment + return fileHeader({file, formatting: { + lineSeparator, + prefix: ` * `, + header: `/**${lineSeparator}`, + footer: `${lineSeparator} */${lineSeparator}${lineSeparator}` + }}) + + formattedVariables({ + dictionary, + outputReferences, + formatting: { + prefix: '$', + separator: ':', + suffix: ';' + } + }); + } + }, + source: ['tokens/**/*'], + platforms: { + scss: { + transformGroup: 'scss', + buildPath: 'build/', + files: [{ + destination: 'variables.scss', + format: 'myFormat' + },{ + destination: 'variablesWithReferences.scss', + format: 'myOtherFormat', + options: { + outputReferences: true, + // Creates a custom file header message + // the `fileHeader` format helper function will use this file header + // for this file. + fileHeader: (defaultMessage) => [ + ...defaultMessage, + "hello", + "is it me you're looking for?" + ] + } + }] + } + } +} \ No newline at end of file diff --git a/examples/advanced/format-helpers/tokens/color.json b/examples/advanced/format-helpers/tokens/color.json new file mode 100644 index 000000000..856a2c4dd --- /dev/null +++ b/examples/advanced/format-helpers/tokens/color.json @@ -0,0 +1,10 @@ +{ + "color": { + "core": { + "greener": { "value": "{color.core.green.value}" }, + "red": { "value": "#ff0000" }, + "blue": { "value": "#0000ff" }, + "green": { "value": "#00ff00" } + } + } +} \ No newline at end of file diff --git a/examples/advanced/matching-build-files/.gitignore b/examples/advanced/matching-build-files/.gitignore new file mode 100644 index 000000000..3e2e84b08 --- /dev/null +++ b/examples/advanced/matching-build-files/.gitignore @@ -0,0 +1,2 @@ +build/ +node_modules/ diff --git a/examples/advanced/matching-build-files/README.md b/examples/advanced/matching-build-files/README.md new file mode 100644 index 000000000..7dc140bea --- /dev/null +++ b/examples/advanced/matching-build-files/README.md @@ -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 `tokens` 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 +# tokens/color/base.json +{ + "color": { + "red": { + "value": "#FF0000" + } + } +} +``` + +```sh +# tokens/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 `tokens` 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: tokens.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! diff --git a/examples/advanced/matching-build-files/config.js b/examples/advanced/matching-build-files/config.js new file mode 100644 index 000000000..72d568d00 --- /dev/null +++ b/examples/advanced/matching-build-files/config.js @@ -0,0 +1,89 @@ +const StyleDictionary = require("style-dictionary"); +const tokens = require("./tokens"); + +module.exports = { + source: ["tokens/**/*.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.allTokens.map( + (token) => `\n\t${token.name}: "${token.value}"` + )}\n};`; + }, +}); diff --git a/examples/advanced/matching-build-files/package-lock.json b/examples/advanced/matching-build-files/package-lock.json new file mode 100644 index 000000000..fc77894ec --- /dev/null +++ b/examples/advanced/matching-build-files/package-lock.json @@ -0,0 +1,248 @@ +{ + "name": "style-dictionary-matching-build-files", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/commander/-/commander-2.20.3.tgz", + "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs-extra": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/fs-extra/-/fs-extra-6.0.1.tgz", + "integrity": "sha1-irwSj3lG4xATXdyTuYvdtBDno0s=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/glob/-/glob-7.1.6.tgz", + "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha1-Ila94U02MpWMRl68ltxGfKB6Kfs=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/json5/-/json5-2.1.3.tgz", + "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "style-dictionary": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/style-dictionary/-/style-dictionary-2.8.2.tgz", + "integrity": "sha1-babNxUdhD+Lw9dnwYVaLYIwaBvQ=", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "commander": "^2.9.0", + "fs-extra": "^6.0.1", + "glob": "^7.1.1", + "json5": "^2.1.0", + "lodash": "^4.17.15", + "resolve-cwd": "^2.0.0", + "tinycolor2": "^1.4.1" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha1-P2pNEHGtB2dtf6Ry4frECnGdiAM=", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/examples/advanced/matching-build-files/package.json b/examples/advanced/matching-build-files/package.json new file mode 100644 index 000000000..fa99ff182 --- /dev/null +++ b/examples/advanced/matching-build-files/package.json @@ -0,0 +1,21 @@ +{ + "name": "style-dictionary-matching-build-files", + "version": "1.0.0", + "description": "An example to show how to automate build files that match folders", + "main": "build/js/cjs/index.js", + "module": "build/js/esm/index.js", + "files": [ + "build", + "properties" + ], + "scripts": { + "build": "style-dictionary build --config ./config.js", + "clean": "rm -rf build", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Kelly Harrop ", + "license": "Apache-2.0", + "devDependencies": { + "style-dictionary": "3.0.0-rc.10" + } +} \ No newline at end of file diff --git a/examples/advanced/matching-build-files/tokens/button/base.json b/examples/advanced/matching-build-files/tokens/button/base.json new file mode 100644 index 000000000..b6c780698 --- /dev/null +++ b/examples/advanced/matching-build-files/tokens/button/base.json @@ -0,0 +1,14 @@ +{ + "button": { + "background": { + "color": { + "value": "{color.blue.value}" + } + }, + "text": { + "color": { + "value": "#FFFFFF" + } + } + } +} \ No newline at end of file diff --git a/examples/advanced/matching-build-files/tokens/color/base.json b/examples/advanced/matching-build-files/tokens/color/base.json new file mode 100644 index 000000000..d8b83723d --- /dev/null +++ b/examples/advanced/matching-build-files/tokens/color/base.json @@ -0,0 +1,10 @@ +{ + "color": { + "red": { + "value": "#FF0000" + }, + "blue": { + "value": "#0000FF" + } + } + } \ No newline at end of file diff --git a/examples/advanced/matching-build-files/tokens/index.js b/examples/advanced/matching-build-files/tokens/index.js new file mode 100644 index 000000000..4a2e37f27 --- /dev/null +++ b/examples/advanced/matching-build-files/tokens/index.js @@ -0,0 +1,5 @@ +const { readdirSync, statSync } = require("fs"); +const { join } = require("path"); +const dirs = (p) => + readdirSync(p).filter((f) => statSync(join(p, f)).isDirectory()); +module.exports = dirs(__dirname); diff --git a/examples/advanced/matching-build-files/tokens/size/base.json b/examples/advanced/matching-build-files/tokens/size/base.json new file mode 100644 index 000000000..76ffc555e --- /dev/null +++ b/examples/advanced/matching-build-files/tokens/size/base.json @@ -0,0 +1,13 @@ +{ + "size": { + "small": { + "value": "2px" + }, + "medium": { + "value": "8px" + }, + "large": { + "value": "16px" + } + } +} \ No newline at end of file diff --git a/examples/advanced/multi-brand-multi-platform/README.md b/examples/advanced/multi-brand-multi-platform/README.md index b2179d090..cd763dc72 100644 --- a/examples/advanced/multi-brand-multi-platform/README.md +++ b/examples/advanced/multi-brand-multi-platform/README.md @@ -1,10 +1,10 @@ ## Multi Brand & Multi Platform -While it's pretty standard to use a common set of properties to generate the same design tokens for different platforms (only in different format), this example shows how to setup a **multi-brand, multi-platform suite** of design tokens, with values that may depend on the brand (eg. a brand color) or the platform (eg. a font family). +While it's pretty standard to use a common set of tokens to generate the same design tokens for different platforms (only in different format), this example shows how to setup a **multi-brand, multi-platform suite** of design tokens, with values that may depend on the brand (eg. a brand color) or the platform (eg. a font family). -In this specific case it's necessary to use a **custom build script** to process the properties for each one of the possible brand/platform combinations. In the script the configuration used by Style Dictionary becomes parametric, with "brand" and "platform" used as arguments of a function that returns the "config" object used to extend Style Dictionary. +In this specific case it's necessary to use a **custom build script** to process the tokens for each one of the possible brand/platform combinations. In the script the configuration used by Style Dictionary becomes parametric, with "brand" and "platform" used as arguments of a function that returns the "config" object used to extend Style Dictionary. -The properties are organised in **specific folders**, depending if they are "platform" dependent, "brand" dependent or "global" (independent of platform or brand). The organisation of the files used in this example is not strictly required, but has the advantage that it's easier to see what the properties depend on, and it's easier to use global paths to include the correct files for a specific combination of "brand" and "platform" (see the "source" declaration block in the `getStyleDictionaryConfig` function of the build script). +The tokens are organized in **specific folders**, depending if they are "platform" dependent, "brand" dependent or "global" (independent of platform or brand). The organization of the files used in this example is not strictly required, but has the advantage that it's easier to see what the tokens depend on, and it's easier to use global paths to include the correct files for a specific combination of "brand" and "platform" (see the "source" declaration block in the `getStyleDictionaryConfig` function of the build script). #### Running the example @@ -26,15 +26,15 @@ The "build" command will run the custom script `build.js`. This script loops on ``` -For each combination it receives a parametric configuration object from the `getStyleDictionaryConfig` function, where the input property files to read and the output paths where to write the generaed files depend on the "platform" and "brand" values: +For each combination it receives a parametric configuration object from the `getStyleDictionaryConfig` function, where the input token files to read and the output paths where to write the generated files depend on the "platform" and "brand" values: ``` function getStyleDictionaryConfig(brand, platform) { return { "source": [ - `properties/brands/${brand}/*.json`, - "properties/globals/**/*.json", - `properties/platforms/${platform}/*.json` + `tokens/brands/${brand}/*.json`, + "tokens/globals/**/*.json", + `tokens/platforms/${platform}/*.json` ], "platforms": { "web": { @@ -50,19 +50,19 @@ function getStyleDictionaryConfig(brand, platform) { }; } ``` -The properties are stored in three different folders: +The tokens are stored in three different folders: -* **brands**: this folder contain properties that depend on the "brand", eg. the "primary" and "secondary" colors (generally these are called "brand colors", think of the blue of Facebook, the orange of Amazon, or the red of Gmail). -* **platforms**: this folder contain properties that depend on the "platform", eg. the font family used in the application or website (eg. a font stack like "Tahoma, Arial, 'Helvetica Neue', sans" on web, "San Francisco" in iOS, "Roboto" in Android). -* **global**: this folder contain properties that are common, that don't depend on the specific "platform" or "brand", eg. the base grayscale colors, the font sizes, etc. +* **brands**: this folder contain tokens that depend on the "brand", eg. the "primary" and "secondary" colors (generally these are called "brand colors", think of the blue of Facebook, the orange of Amazon, or the red of Gmail). +* **platforms**: this folder contain tokens that depend on the "platform", eg. the font family used in the application or website (eg. a font stack like "Tahoma, Arial, 'Helvetica Neue', sans" on web, "San Francisco" in iOS, "Roboto" in Android). +* **global**: this folder contain tokens that are common, that don't depend on the specific "platform" or "brand", eg. the base grayscale colors, the font sizes, etc. -Leveraging the ability of Style Dictionary to reference other properties values as "aliases", we can have generic properties like `font.family.base` or `color.primary` whose values actually depend on the "platform" and "brand" and whose values are computed dynamically at build time depending on the specific "platform/brand" files, included dynamically by the `getStyleDictionaryConfig` function. +Leveraging the ability of Style Dictionary to reference other tokens values as "aliases", we can have generic tokens like `font.family.base` or `color.primary` whose values actually depend on the "platform" and "brand" and whose values are computed dynamically at build time depending on the specific "platform/brand" files, included dynamically by the `getStyleDictionaryConfig` function. #### What to look at Open the `build.js` script and look how the `StyleDictionary.buildPlatform` function is called multiple times, looping on the combination of platform and brand, and how the configuration object is returned by the `getStyleDictionaryConfig` function. -Now look at the properties folders, and see how they are organised. Open `properties/brands/brand-1/color.json`. You will see this declaration: +Now look at the tokens folders, and see how they are organized. Open `tokens/brands/brand-1/color.json`. You will see this declaration: ``` { @@ -75,7 +75,7 @@ Now look at the properties folders, and see how they are organised. Open `proper } ``` -The actual values depend on the "brand" (compare this file with `brand-2/color.json` and `brand-3/color.json`. These values are used as "aliases" in the `properties/global/color/base.json` file: +The actual values depend on the "brand" (compare this file with `brand-2/color.json` and `brand-3/color.json`. These values are used as "aliases" in the `tokens/global/color/base.json` file: ``` { @@ -92,7 +92,7 @@ The actual values depend on the "brand" (compare this file with `brand-2/color.j Depending on the file included at build time, the actual value of `color.primary` will depend on the "brand". To see how this works out, open the file `build/web/brand-1/tokens.scss` and compare it with the similar files for "brand-2" and "brand-3": you will see how the values for `color.primary`, `color.action.primary` are different for different brands, and how they are actually the values declared in the "brands" source folders. -In the same way, now open `properties/platforms/android/font.json` and you will see: +In the same way, now open `tokens/platforms/android/font.json` and you will see: ``` { @@ -103,7 +103,7 @@ In the same way, now open `properties/platforms/android/font.json` and you will } } ``` -the value `font.platform.system` is consumed by the `properties/globals/font/index.json` file: +the value `font.platform.system` is consumed by the `tokens/globals/font/index.json` file: ``` { diff --git a/examples/advanced/multi-brand-multi-platform/build.js b/examples/advanced/multi-brand-multi-platform/build.js index e43c8d3e5..305ddfb74 100644 --- a/examples/advanced/multi-brand-multi-platform/build.js +++ b/examples/advanced/multi-brand-multi-platform/build.js @@ -5,9 +5,9 @@ const StyleDictionaryPackage = require('style-dictionary'); function getStyleDictionaryConfig(brand, platform) { return { "source": [ - `properties/brands/${brand}/*.json`, - "properties/globals/**/*.json", - `properties/platforms/${platform}/*.json` + `tokens/brands/${brand}/*.json`, + "tokens/globals/**/*.json", + `tokens/platforms/${platform}/*.json` ], "platforms": { "web": { diff --git a/examples/advanced/multi-brand-multi-platform/package.json b/examples/advanced/multi-brand-multi-platform/package.json index 47fb775c0..54e83d48f 100644 --- a/examples/advanced/multi-brand-multi-platform/package.json +++ b/examples/advanced/multi-brand-multi-platform/package.json @@ -15,6 +15,6 @@ "author": "", "license": "Apache-2.0", "devDependencies": { - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/multi-brand-multi-platform/properties/brands/brand-1/color.json b/examples/advanced/multi-brand-multi-platform/tokens/brands/brand-1/color.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/brands/brand-1/color.json rename to examples/advanced/multi-brand-multi-platform/tokens/brands/brand-1/color.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/brands/brand-2/color.json b/examples/advanced/multi-brand-multi-platform/tokens/brands/brand-2/color.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/brands/brand-2/color.json rename to examples/advanced/multi-brand-multi-platform/tokens/brands/brand-2/color.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/brands/brand-3/color.json b/examples/advanced/multi-brand-multi-platform/tokens/brands/brand-3/color.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/brands/brand-3/color.json rename to examples/advanced/multi-brand-multi-platform/tokens/brands/brand-3/color.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/globals/button.json b/examples/advanced/multi-brand-multi-platform/tokens/globals/button.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/globals/button.json rename to examples/advanced/multi-brand-multi-platform/tokens/globals/button.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/globals/color/base.json b/examples/advanced/multi-brand-multi-platform/tokens/globals/color/base.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/globals/color/base.json rename to examples/advanced/multi-brand-multi-platform/tokens/globals/color/base.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/globals/color/font.json b/examples/advanced/multi-brand-multi-platform/tokens/globals/color/font.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/globals/color/font.json rename to examples/advanced/multi-brand-multi-platform/tokens/globals/color/font.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/globals/font/index.json b/examples/advanced/multi-brand-multi-platform/tokens/globals/font/index.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/globals/font/index.json rename to examples/advanced/multi-brand-multi-platform/tokens/globals/font/index.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/globals/size/font.json b/examples/advanced/multi-brand-multi-platform/tokens/globals/size/font.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/globals/size/font.json rename to examples/advanced/multi-brand-multi-platform/tokens/globals/size/font.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/platforms/android/button.json b/examples/advanced/multi-brand-multi-platform/tokens/platforms/android/button.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/platforms/android/button.json rename to examples/advanced/multi-brand-multi-platform/tokens/platforms/android/button.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/platforms/android/font.json b/examples/advanced/multi-brand-multi-platform/tokens/platforms/android/font.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/platforms/android/font.json rename to examples/advanced/multi-brand-multi-platform/tokens/platforms/android/font.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/platforms/ios/button.json b/examples/advanced/multi-brand-multi-platform/tokens/platforms/ios/button.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/platforms/ios/button.json rename to examples/advanced/multi-brand-multi-platform/tokens/platforms/ios/button.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/platforms/ios/font.json b/examples/advanced/multi-brand-multi-platform/tokens/platforms/ios/font.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/platforms/ios/font.json rename to examples/advanced/multi-brand-multi-platform/tokens/platforms/ios/font.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/platforms/web/button.json b/examples/advanced/multi-brand-multi-platform/tokens/platforms/web/button.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/platforms/web/button.json rename to examples/advanced/multi-brand-multi-platform/tokens/platforms/web/button.json diff --git a/examples/advanced/multi-brand-multi-platform/properties/platforms/web/font.json b/examples/advanced/multi-brand-multi-platform/tokens/platforms/web/font.json similarity index 100% rename from examples/advanced/multi-brand-multi-platform/properties/platforms/web/font.json rename to examples/advanced/multi-brand-multi-platform/tokens/platforms/web/font.json diff --git a/examples/advanced/node-modules-as-config-and-properties/README.md b/examples/advanced/node-modules-as-config-and-properties/README.md index 70c24edd0..7ea288d85 100644 --- a/examples/advanced/node-modules-as-config-and-properties/README.md +++ b/examples/advanced/node-modules-as-config-and-properties/README.md @@ -1,4 +1,4 @@ -## Node Modules as Config and Property files +## Node Modules as Config and Token files This example shows some advanced features using Style Dictionary with node modules. Make sure you are familiar with Style Dictionary concepts first by reading the [docs](https://amzn.github.io/style-dictionary) or taking a look at the [basic example](../../basic) first. @@ -10,7 +10,7 @@ At this point, if you want to build the tokens you can run `npm run build`. This #### How does it work? -Style Dictionary understands node modules that export a simple object for both a config file as well as the property source files. Using node module exports allows you to do some pretty cool things like generating properties programmatically (design tokens). +Style Dictionary understands node modules that export a simple object for both a config file as well as the token source files. Using node module exports allows you to do some pretty cool things like generating tokens programmatically. The `.extend()` method on the Style Dictionary module can take an object or a path to a JSON or node module and it copies the object attributes onto a new copy of the Style Dictionary object. The Style Dictionary object stores the transforms, transformGroups, and formats as attributes on the SD object. You can override these defaults by directly adding these attributes to your config object. This allows you to add custom transforms and formats without calling `.registerTransform()`! @@ -18,8 +18,8 @@ The `.extend()` method on the Style Dictionary module can take an object or a pa The [`config.js`](config.js) file is the first thing to look at. It has a lot of comments how everything works. It shows how you can add custom transforms and formats without calling the register methods. It also shows how you can extend built-in transforms and transformGroups. -If you take a look at any of the `index.js` files in `properties/` or `components/` you can see how using node module exports can simplify the object structure. Now you don't have to copy the same top-level object paths in the JSON object. Some specific files to look at: +If you take a look at any of the `index.js` files in `tokens/` or `components/` you can see how using node module exports can simplify the object structure. Now you don't have to copy the same top-level object paths in the JSON object. Some specific files to look at: -* [`components/index.js`](components/index.js) Uses node module export/require to merge the property files together without Style Dictionary -* [`components/button/primary.js`](components/button/primary.js) Extends a default set of properties -* [`properties/color/core.js`](properties/color/core.js) Creates a color ramp programmatically based on base colors +* [`components/index.js`](components/index.js) Uses node module export/require to merge the token files together without Style Dictionary +* [`components/button/primary.js`](components/button/primary.js) Extends a default set of tokens +* [`tokens/color/core.js`](tokens/color/core.js) Creates a color ramp programmatically based on base colors diff --git a/examples/advanced/node-modules-as-config-and-properties/config.js b/examples/advanced/node-modules-as-config-and-properties/config.js index c17da6bb1..0f13b2ef4 100644 --- a/examples/advanced/node-modules-as-config-and-properties/config.js +++ b/examples/advanced/node-modules-as-config-and-properties/config.js @@ -1,9 +1,9 @@ const StyleDictionary = require('style-dictionary'); -// Rather than have Style Dictionary handle the merging of property files, +// Rather than have Style Dictionary handle the merging of token files, // you could use node module export/require to do it yourself. This will // allow you to not have to copy object namespaces like you normally would. -// Take a look at any of the .js files in components/ or properties/ -const properties = require('./properties'); +// Take a look at any of the .js files in components/ or tokens/ +const tokens = require('./tokens'); const buildPath = 'build/'; @@ -12,14 +12,14 @@ const buildPath = 'build/'; StyleDictionary.registerTransform({ name: 'myRegisteredTransform', type: 'value', - matcher: (prop) => prop.attributes.category === 'size', - transformer: (prop) => `${parseInt(prop.value) * 16}px` + matcher: (token) => token.attributes.category === 'size', + transformer: (token) => `${parseInt(token.value) * 16}px` }); StyleDictionary.registerFormat({ name: 'myRegisteredFormat', formatter: (dictionary) => { - return dictionary.allProperties.map((prop) => prop.value).join('\n'); + return dictionary.allTokens.map((token) => token.value).join('\n'); } }) @@ -29,7 +29,7 @@ module.exports = { // We are relying on node modules to merge all the objects together // thus we only want to reference top level node modules that export // the whole objects. - source: ['properties/index.js', 'components/index.js'], + source: ['tokens/index.js', 'components/index.js'], // If you don't want to call the registerTransform method a bunch of times // you can override the whole transform object directly. This works because // the .extend method copies everything in the config @@ -39,20 +39,20 @@ module.exports = { // Now we can use the transform 'myTransform' below myTransform: { type: 'name', - transformer: (prop) => prop.path.join('_').toUpperCase() + transformer: (token) => token.path.join('_').toUpperCase() } }, // Same with formats, you can now write them directly to this config // object. The name of the format is the key. format: { - myFormat: (dictionary, platform) => { - return dictionary.allProperties.map(prop => `${prop.name}: ${prop.value}`).join('\n'); + myFormat: ({dictionary}) => { + return dictionary.allTokens.map(token => `${token.name}: ${token.value}`).join('\n'); } }, // You can also bypass the merging of files Style Dictionary does - // by adding a 'properties' object directly like this: + // by adding a 'tokens' object directly like this: // - // properties: properties, + // tokens: tokens, platforms: { custom: { // Using the custom transforms we defined above @@ -87,14 +87,14 @@ module.exports = { transforms: StyleDictionary.transformGroup.js.concat('myRegisteredTransform'), buildPath: buildPath, // If you want to get super fancy, you can use node modules - // to create a properties object first, and then you can + // to create a tokens object first, and then you can // reference attributes of that object. This allows you to // output 1 file per color namespace. - files: Object.keys(properties.color).map((colorType) => ({ + files: Object.keys(tokens.color).map((colorType) => ({ destination: `${colorType}.js`, format: 'javascript/es6', // Filters can be functions that return a boolean - filter: (prop) => prop.attributes.type === colorType + filter: (token) => token.attributes.type === colorType })) }, @@ -103,7 +103,7 @@ module.exports = { transformGroup: 'js', buildPath: buildPath, files: [{ - destination: 'properties.json', + destination: 'tokens.json', format: 'json' }] } diff --git a/examples/advanced/node-modules-as-config-and-properties/package.json b/examples/advanced/node-modules-as-config-and-properties/package.json index e8d59671c..00233ae1e 100644 --- a/examples/advanced/node-modules-as-config-and-properties/package.json +++ b/examples/advanced/node-modules-as-config-and-properties/package.json @@ -19,7 +19,7 @@ }, "homepage": "https://github.com/dbanksdesign/style-dictionary-node#readme", "devDependencies": { - "style-dictionary": "2.10.3", + "style-dictionary": "3.0.0-rc.10", "tinycolor2": "^1.4.1" } } \ No newline at end of file diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/color/background.js b/examples/advanced/node-modules-as-config-and-properties/tokens/color/background.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/color/background.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/color/background.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/color/border.js b/examples/advanced/node-modules-as-config-and-properties/tokens/color/border.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/color/border.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/color/border.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/color/brand.js b/examples/advanced/node-modules-as-config-and-properties/tokens/color/brand.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/color/brand.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/color/brand.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/color/core.js b/examples/advanced/node-modules-as-config-and-properties/tokens/color/core.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/color/core.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/color/core.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/color/font.js b/examples/advanced/node-modules-as-config-and-properties/tokens/color/font.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/color/font.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/color/font.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/color/index.js b/examples/advanced/node-modules-as-config-and-properties/tokens/color/index.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/color/index.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/color/index.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/index.js b/examples/advanced/node-modules-as-config-and-properties/tokens/index.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/index.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/index.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/size/border.js b/examples/advanced/node-modules-as-config-and-properties/tokens/size/border.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/size/border.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/size/border.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/size/font.js b/examples/advanced/node-modules-as-config-and-properties/tokens/size/font.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/size/font.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/size/font.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/size/index.js b/examples/advanced/node-modules-as-config-and-properties/tokens/size/index.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/size/index.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/size/index.js diff --git a/examples/advanced/node-modules-as-config-and-properties/properties/size/padding.js b/examples/advanced/node-modules-as-config-and-properties/tokens/size/padding.js similarity index 100% rename from examples/advanced/node-modules-as-config-and-properties/properties/size/padding.js rename to examples/advanced/node-modules-as-config-and-properties/tokens/size/padding.js diff --git a/examples/advanced/npm-module/config.json b/examples/advanced/npm-module/config.json index 87e55d92c..bb24ac06f 100644 --- a/examples/advanced/npm-module/config.json +++ b/examples/advanced/npm-module/config.json @@ -1,5 +1,5 @@ { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "scss": { "transformGroup": "scss", diff --git a/examples/advanced/npm-module/package.json b/examples/advanced/npm-module/package.json index 643f78a30..1473d1ba7 100644 --- a/examples/advanced/npm-module/package.json +++ b/examples/advanced/npm-module/package.json @@ -16,6 +16,6 @@ "author": "", "license": "Apache-2.0", "devDependencies": { - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/npm-module/properties/color/base.json b/examples/advanced/npm-module/tokens/color/base.json similarity index 100% rename from examples/advanced/npm-module/properties/color/base.json rename to examples/advanced/npm-module/tokens/color/base.json diff --git a/examples/advanced/npm-module/properties/color/font.json b/examples/advanced/npm-module/tokens/color/font.json similarity index 100% rename from examples/advanced/npm-module/properties/color/font.json rename to examples/advanced/npm-module/tokens/color/font.json diff --git a/examples/advanced/npm-module/properties/size/font.json b/examples/advanced/npm-module/tokens/size/font.json similarity index 100% rename from examples/advanced/npm-module/properties/size/font.json rename to examples/advanced/npm-module/tokens/size/font.json diff --git a/examples/advanced/referencing_aliasing/README.md b/examples/advanced/referencing_aliasing/README.md index ba57cdc47..34bea5d2f 100644 --- a/examples/advanced/referencing_aliasing/README.md +++ b/examples/advanced/referencing_aliasing/README.md @@ -1,6 +1,6 @@ ## Referencing (Aliasing) -This example shows how to use referencing (or "aliasing") to reference a value -or an attribute– of a property and assign it to the value –or attribute– of another property. +This example shows how to use referencing (or "aliasing") to reference a value -or an attribute– of a token and assign it to the value –or attribute– of another token. This is quite handy when you want to create a system that uses some basic design definitions (base colors, base font sizes, base scales, etc) but then exposes them in a more complex and detailed set of design tokens, typically to describe a complete UI pattern library. @@ -12,20 +12,20 @@ At this point, you can run `npm run build`. This command will generate the outpu #### How does it work -The "build" command processes the JSON files in the `properties` folder. Whenever it finds a reference declared via this syntax: +The "build" command processes the JSON files in the `tokens` folder. Whenever it finds a reference declared via this syntax: ``` - property: { + token: { "value": "{ref.to.object.value}" } ``` -the build process resolves the reference using the declared path (`ref.to.object`) to retrieve the actual value of the referenced property inside the Style Dictionary object. +the build process resolves the reference using the declared path (`ref.to.object`) to retrieve the actual value of the referenced token inside the Style Dictionary object. **Notice**: if the path is not valid, doesn't exist or is a circular reference, Style Dictionary generates an error in the console. #### What to look at -Open the JSON files in the `properties` folder and see how certain properties are referencing the values of other properties via "aliases". +Open the JSON files in the `tokens` folder and see how certain tokens are referencing the values of other tokens via "aliases". For example, open `color/base.json` and see how the value of the "primary" color is a **reference** to the value of the "green" color, declared as: @@ -35,7 +35,7 @@ For example, open `color/base.json` and see how the value of the "primary" color ``` In this case, the string `"{color.base.green.value}"` is resolved at build time, and gets its value from the value of the "green" base color, `"#00FF00"`. -The reference can point to another property in a **different JSON file**. For example open `color/font.json` and see how the value for the base/secondary font colors are references to the properties declared in `color/base.json`: +The reference can point to another token in a **different JSON file**. For example open `color/font.json` and see how the value for the base/secondary font colors are references to the tokens declared in `color/base.json`: ``` { @@ -57,7 +57,7 @@ It is also possible to create **chains of references**, where a value references ... ``` -The value associated to a property can be an **object** (eg. an RGB color). In that case, the reference still works. If you open `color/font.json` you will see that the "faded" color of text is a reference to `color.base.gray.medium.value`, but if you look in `color/base.json` you will see that the value of the "medium gray" color is not a string, but an RGB oject: +The value associated to a token can be an **object** (eg. an RGB color). In that case, the reference still works. If you open `color/font.json` you will see that the "faded" color of text is a reference to `color.base.gray.medium.value`, but if you look in `color/base.json` you will see that the value of the "medium gray" color is not a string, but an RGB object: ``` { @@ -74,7 +74,7 @@ In that case Style Dictionary still resolves correctly the alias to the corresp "color-base-gray-medium": "#9299a2" ``` -You can also reference **other attributes of a property**, not only its value. For example in `button/button.json` the value of text size is composed as concatenation (remember, it's a string, think of it as template literals) of two properties of the "global" object, declared in the `globals.json` file: +You can also reference **other attributes of a token**, not only its value. For example in `button/button.json` the value of text size is composed as concatenation (remember, it's a string, think of it as template literals) of two tokens of the "global" object, declared in the `globals.json` file: ``` "text": { diff --git a/examples/advanced/referencing_aliasing/config.json b/examples/advanced/referencing_aliasing/config.json index 51b2de809..22e5b1c75 100644 --- a/examples/advanced/referencing_aliasing/config.json +++ b/examples/advanced/referencing_aliasing/config.json @@ -1,5 +1,5 @@ { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "example": { "transformGroup": "web", diff --git a/examples/advanced/referencing_aliasing/package.json b/examples/advanced/referencing_aliasing/package.json index 95a0305c1..89b817348 100644 --- a/examples/advanced/referencing_aliasing/package.json +++ b/examples/advanced/referencing_aliasing/package.json @@ -15,6 +15,6 @@ "author": "", "license": "Apache-2.0", "devDependencies": { - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/referencing_aliasing/properties/button/button.json b/examples/advanced/referencing_aliasing/tokens/button/button.json similarity index 100% rename from examples/advanced/referencing_aliasing/properties/button/button.json rename to examples/advanced/referencing_aliasing/tokens/button/button.json diff --git a/examples/advanced/referencing_aliasing/properties/color/base.json b/examples/advanced/referencing_aliasing/tokens/color/base.json similarity index 100% rename from examples/advanced/referencing_aliasing/properties/color/base.json rename to examples/advanced/referencing_aliasing/tokens/color/base.json diff --git a/examples/advanced/referencing_aliasing/properties/color/font.json b/examples/advanced/referencing_aliasing/tokens/color/font.json similarity index 100% rename from examples/advanced/referencing_aliasing/properties/color/font.json rename to examples/advanced/referencing_aliasing/tokens/color/font.json diff --git a/examples/advanced/referencing_aliasing/properties/globals.json b/examples/advanced/referencing_aliasing/tokens/globals.json similarity index 100% rename from examples/advanced/referencing_aliasing/properties/globals.json rename to examples/advanced/referencing_aliasing/tokens/globals.json diff --git a/examples/advanced/referencing_aliasing/properties/size/font.json b/examples/advanced/referencing_aliasing/tokens/size/font.json similarity index 100% rename from examples/advanced/referencing_aliasing/properties/size/font.json rename to examples/advanced/referencing_aliasing/tokens/size/font.json diff --git a/examples/advanced/s3/package.json b/examples/advanced/s3/package.json index ed2799f45..91413d70d 100644 --- a/examples/advanced/s3/package.json +++ b/examples/advanced/s3/package.json @@ -15,6 +15,6 @@ "devDependencies": { "aws-sdk": "^2.7.21", "fs-extra": "^1.0.0", - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/tokens-deprecation/README.md b/examples/advanced/tokens-deprecation/README.md index bd6112032..bd0642057 100644 --- a/examples/advanced/tokens-deprecation/README.md +++ b/examples/advanced/tokens-deprecation/README.md @@ -16,8 +16,8 @@ Using extra attributes associated to a design token, is possible (at build time) #### What to look at -Open the `properties/color/base.json` and `properties/size/font.json` files and see how some of the properties have a custom `deprecated` attribute (and an additional `deprecated_comment` attribute). +Open the `tokens/color/base.json` and `tokens/size/font.json` files and see how some of the tokens have a custom `deprecated` attribute (and an additional `deprecated_comment` attribute). -Now open the custom template files in `templates` and see how this attributes are used to - conditionally, when a property is deprecated - add extra comments to the output files. +Now open the custom template files in `templates` and see how this attributes are used to - conditionally, when a token is deprecated - add extra comments to the output files. -Finally, once generated the output files, open the `build/scss/_variables.scss` and `build/ios/tokens.plist` files and see how the `deprecated` attributes have been converted to comments (and extra properties in the plist) in the output files. \ No newline at end of file +Finally, once generated the output files, open the `build/scss/_variables.scss` and `build/ios/tokens.plist` files and see how the `deprecated` attributes have been converted to comments (and extra tokens in the plist) in the output files. \ No newline at end of file diff --git a/examples/advanced/tokens-deprecation/config.json b/examples/advanced/tokens-deprecation/config.json index f8df60380..f48a15c9f 100644 --- a/examples/advanced/tokens-deprecation/config.json +++ b/examples/advanced/tokens-deprecation/config.json @@ -1,5 +1,5 @@ { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "scss": { "transformGroup": "scss", diff --git a/examples/advanced/tokens-deprecation/package.json b/examples/advanced/tokens-deprecation/package.json index bdb6abc9a..b751f2a32 100644 --- a/examples/advanced/tokens-deprecation/package.json +++ b/examples/advanced/tokens-deprecation/package.json @@ -5,7 +5,7 @@ "main": "build/index.js", "files": [ "build", - "properties" + "tokens" ], "scripts": { "build": "node ./build.js", @@ -16,6 +16,6 @@ "license": "Apache-2.0", "devDependencies": { "lodash": "^4.17.11", - "style-dictionary": "2.10.3" + "style-dictionary": "3.0.0-rc.10" } } \ No newline at end of file diff --git a/examples/advanced/tokens-deprecation/templates/ios-plist.template b/examples/advanced/tokens-deprecation/templates/ios-plist.template index 14beec7ee..6c01c25f4 100644 --- a/examples/advanced/tokens-deprecation/templates/ios-plist.template +++ b/examples/advanced/tokens-deprecation/templates/ios-plist.template @@ -3,7 +3,7 @@ -<% _.each(allProperties, function(prop) { +<% _.each(allTokens, function(prop) { // NOTICE: this is a simplified version of a PLIST file for iOS // please refer to the documentation for a proper format // or speak with one of your iOS developers to agree on a format that works for them diff --git a/examples/advanced/tokens-deprecation/templates/web-scss.template b/examples/advanced/tokens-deprecation/templates/web-scss.template index 5a016b3d6..099d97b7c 100644 --- a/examples/advanced/tokens-deprecation/templates/web-scss.template +++ b/examples/advanced/tokens-deprecation/templates/web-scss.template @@ -1,4 +1,4 @@ -<% _.each(allProperties, function(prop) { +<% _.each(allTokens, function(prop) { var output = ""; if(prop.deprecated) { output += "// Notice: the following value is deprecated"; diff --git a/examples/advanced/tokens-deprecation/properties/color/base.json b/examples/advanced/tokens-deprecation/tokens/color/base.json similarity index 100% rename from examples/advanced/tokens-deprecation/properties/color/base.json rename to examples/advanced/tokens-deprecation/tokens/color/base.json diff --git a/examples/advanced/tokens-deprecation/properties/color/font.json b/examples/advanced/tokens-deprecation/tokens/color/font.json similarity index 100% rename from examples/advanced/tokens-deprecation/properties/color/font.json rename to examples/advanced/tokens-deprecation/tokens/color/font.json diff --git a/examples/advanced/tokens-deprecation/properties/size/font.json b/examples/advanced/tokens-deprecation/tokens/size/font.json similarity index 100% rename from examples/advanced/tokens-deprecation/properties/size/font.json rename to examples/advanced/tokens-deprecation/tokens/size/font.json diff --git a/examples/advanced/transitive-transforms/README.md b/examples/advanced/transitive-transforms/README.md new file mode 100644 index 000000000..67e2f7ac1 --- /dev/null +++ b/examples/advanced/transitive-transforms/README.md @@ -0,0 +1,34 @@ +## Transitive Transforms + +Style Dictionary 3.0 added the ability to have transitive transforms, transforms that work on token values that reference/alias other tokens. This example shows a few ways to take advantage of transitive transforms. + +Common use cases include: + +- Referencing and modifying colors, such as brightening/darkening colors or adding transparencies to colors +- Splitting colors into re-usable parts, like having hue, lightness, and saturation shared across colors. + + +#### Running the example + +First of all, set up the required dependencies running the command `npm ci` 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 output files in the `build` folder. For brevity, it only builds CSS variables as an output, but you could add any platforms to this example. + +#### How does it work + +In version 3.0, Style Dictionary added the ability to transitively transform token values, meaning you could transform a token value that referenced another token. This functionality allows you to now _modify_ a referenced value; darkening a color for example. This example does this by creating a custom transform that uses [chromajs](https://gka.github.io/chroma.js) to modify colors. + +You can also define data that isn't a design token itself, but can be referenced in a design token. This example defines [alpha](tokens/alpha.json5), [hue](tokens/hue.json5), [lightness](tokens/lightness.json5), and [saturation](tokens/saturation.json5) data that is then used elsewhere in design tokens. This works because how Style Dictionary handles references is very un-opinionated. When Style Dictionary sees any string attribute with curly braces, it will grab whatever it finds at that object path and replace the string with it. + +Before version 3.0, Style Dictionary did not have transitive transforms though. While you could reference non-token values, you would not be able to then transform the value if it had a reference in it. + +_NOTE: This example uses [json5](https://json5.org/) for the design tokens so that it can be marked up with comments for reference. If you are using plain JSON make sure to change the contents of the design token files accordingly._ + +#### What to look at + +* **sd.config.js** This file holds the Style Dictionary configuration and custom transforms. It defines a custom transform that uses chromajs to modify color tokens that have a `modify` array on the token, which the transform uses to call certain methods on chromajs to modify the color. +* **tokens/** This directory holds all the design tokens being used for this example. +* **tokens/(alpha|hue|lightness|saturation).json5** These files define color parts that are used in color design tokens. Because these files don't use the `{"value": ""}` syntax like design tokens in Style Dictionary, they are not included in any output by default. But because they are included in the `source` they can still be referenced in design tokens. +* **tokens/color/core.json5** This file defines a core color palette. The interesting thing here is that each color value is defined as an HSL object rather than a HEX string. The HSL value references hue, saturation, and lightness defined in the above files. +* **tokens/color/overlay.json5** This file defines some overlay colors that reference core colors but modifies their transparency. +* **tokens/color/font.json5** This file defines some font colors by modifying core colors. \ No newline at end of file diff --git a/examples/advanced/transitive-transforms/package-lock.json b/examples/advanced/transitive-transforms/package-lock.json new file mode 100644 index 000000000..d1b072cd6 --- /dev/null +++ b/examples/advanced/transitive-transforms/package-lock.json @@ -0,0 +1,306 @@ +{ + "name": "transitive-transforms", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chroma-js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.1.0.tgz", + "integrity": "sha512-uiRdh4ZZy+UTPSrAdp8hqEdVb1EllLtTHOt5TMaOjJUvi+O54/83Fc5K2ld1P+TJX+dw5B+8/sCgzI6eaur/lg==", + "dev": true, + "requires": { + "cross-env": "^6.0.3" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cross-env": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz", + "integrity": "sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "style-dictionary": { + "version": "3.0.0-rc.2", + "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-3.0.0-rc.2.tgz", + "integrity": "sha512-iW2zuJZGOAsMLW7GupNY9JRATdLQkoIceV875HgSeFQf4fcha3DfXYlpW3QQKf9Bt98auOYCZ5zCb3qmmAFD3A==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.6", + "json5": "^2.1.3", + "lodash": "^4.17.15", + "resolve-cwd": "^3.0.0", + "tinycolor2": "^1.4.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/examples/advanced/transitive-transforms/package.json b/examples/advanced/transitive-transforms/package.json new file mode 100644 index 000000000..6bc90334b --- /dev/null +++ b/examples/advanced/transitive-transforms/package.json @@ -0,0 +1,16 @@ +{ + "name": "transitive-transforms", + "version": "1.0.0", + "description": "", + "main": "sd.config.js", + "scripts": { + "build": "style-dictionary build --config ./sd.config.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "chroma-js": "^2.1.0", + "style-dictionary": "3.0.0-rc.10" + } +} \ No newline at end of file diff --git a/examples/advanced/transitive-transforms/sd.config.js b/examples/advanced/transitive-transforms/sd.config.js new file mode 100644 index 000000000..5f5cca89c --- /dev/null +++ b/examples/advanced/transitive-transforms/sd.config.js @@ -0,0 +1,57 @@ +const StyleDictionary = require('style-dictionary'); +const chroma = require('chroma-js'); + +const colorTransform = (token) => { + const { value, modify = [] } = token; + let color = chroma(value); + + // iterate over the modify array (see tokens/color.json) + // and apply each modification in order + modify.forEach(({ type, amount }) => { + // modifier type must match a method name in chromajs + // https://gka.github.io/chroma.js/ + // chroma methods can be chained, so each time we override the color variable + // we can still call other chroma methods, similar to + // chroma(value).brighten(1).darken(1).hex(); + color = color[type](amount); + }); + + return color.hex(); +} + +module.exports = { + // This will match any files ending in json or json5 + // I am using json5 here so I can add comments in the token files for reference + source: [`tokens/**/*.@(json|json5)`], + + // I am directly defining transforms here + // This would work if you were to call StyleDictionary.registerTransform() as well + transform: { + colorTransform: { + type: `value`, + // only transforms that have transitive: true will be applied to tokens + // that alias/reference other tokens + transitive: true, + matcher: (token) => token.attributes.category === 'color' + && token.modify, + transformer: colorTransform + }, + + // For backwards compatibility, all built-in transforms are not transitive + // by default. This will make the 'color/css' transform transitive + 'color/css': Object.assign({}, StyleDictionary.transform[`color/css`], { + transitive: true + }), + }, + + platforms: { + css: { + transforms: [`attribute/cti`, `name/cti/kebab`, `colorTransform`, `color/css`], + buildPath: `build/`, + files: [{ + destination: `variables.css`, + format: `css/variables` + }] + } + } +} diff --git a/examples/advanced/transitive-transforms/tokens/alpha.json5 b/examples/advanced/transitive-transforms/tokens/alpha.json5 new file mode 100644 index 000000000..9abde6775 --- /dev/null +++ b/examples/advanced/transitive-transforms/tokens/alpha.json5 @@ -0,0 +1,14 @@ +{ + // Because these are not like a token object with a 'value' attribute, + // Style Dictionary won't consider them tokens and therefore won't output them. + // But, you can still access/reference them in tokens using the same reference + // syntax: "value": "{alpha.0}" + // This is an array, you can access its members with dot notation and + // the index of the item. + alpha: [ + 1, + 0.9, + 0.75, + 0.5 + ] +} diff --git a/examples/advanced/transitive-transforms/tokens/color/core.json5 b/examples/advanced/transitive-transforms/tokens/color/core.json5 new file mode 100644 index 000000000..960b1d8d8 --- /dev/null +++ b/examples/advanced/transitive-transforms/tokens/color/core.json5 @@ -0,0 +1,255 @@ +{ + "color": { + "core": { + "white": { "value": "#ffffff" }, + "black": { "value": "#000000" }, + + red: { + "100": { + // hue, saturation, and lightness are defined in + // tokens/hue.json5, tokens/saturation.json5, and tokens/lightness.json5 + // The {h, s, l} object structure conforms to the input structure for + // chromajs: https://gka.github.io/chroma.js/#chroma + value: { h: "{hue.red}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.red}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.red}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.red}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.red}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.red}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.red}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.red}", s: "{saturation.0}", l: "{lightness.0}" } + }, + }, + + orange: { + "100": { + value: { h: "{hue.orange}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.orange}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.orange}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.orange}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.orange}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.orange}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.orange}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.orange}", s: "{saturation.0}", l: "{lightness.0}" } + }, + }, + + yellow: { + "100": { + value: { h: "{hue.yellow}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.yellow}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.yellow}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.yellow}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.yellow}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.yellow}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.yellow}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.yellow}", s: "{saturation.0}", l: "{lightness.0}" } + }, + }, + + lime: { + "100": { + value: { h: "{hue.lime}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.lime}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.lime}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.lime}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.lime}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.lime}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.lime}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.lime}", s: "{saturation.0}", l: "{lightness.0}" } + }, + }, + + green: { + "100": { + value: { h: "{hue.green}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.green}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.green}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.green}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.green}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.green}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.green}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.green}", s: "{saturation.0}", l: "{lightness.0}" } + }, + }, + + teal: { + "100": { + value: { h: "{hue.teal}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.teal}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.teal}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.teal}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.teal}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.teal}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.teal}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.teal}", s: "{saturation.0}", l: "{lightness.0}" } + }, + }, + + blue: { + "100": { + value: { h: "{hue.blue}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.blue}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.blue}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.blue}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.blue}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.blue}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.blue}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.blue}", s: "{saturation.0}", l: "{lightness.0}" } + }, + }, + + purple: { + "100": { + value: { h: "{hue.purple}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.purple}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.purple}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.purple}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.purple}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.purple}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.purple}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.purple}", s: "{saturation.0}", l: "{lightness.0}" } + }, + }, + + pink: { + "100": { + value: { h: "{hue.pink}", s: "{saturation.7}", l: "{lightness.7}" } + }, + "80": { + value: { h: "{hue.pink}", s: "{saturation.6}", l: "{lightness.6}" } + }, + "60": { + value: { h: "{hue.pink}", s: "{saturation.5}", l: "{lightness.5}" } + }, + "40": { + value: { h: "{hue.pink}", s: "{saturation.4}", l: "{lightness.4}" } + }, + "20": { + value: { h: "{hue.pink}", s: "{saturation.3}", l: "{lightness.3}" } + }, + "10": { + value: { h: "{hue.pink}", s: "{saturation.2}", l: "{lightness.2}" } + }, + "5": { + value: { h: "{hue.pink}", s: "{saturation.1}", l: "{lightness.1}" } + }, + "0": { + value: { h: "{hue.pink}", s: "{saturation.0}", l: "{lightness.0}" } + }, + } + } + } +} diff --git a/examples/advanced/transitive-transforms/tokens/color/font.json5 b/examples/advanced/transitive-transforms/tokens/color/font.json5 new file mode 100644 index 000000000..d32e91df8 --- /dev/null +++ b/examples/advanced/transitive-transforms/tokens/color/font.json5 @@ -0,0 +1,26 @@ +{ + color: { + font: { + primary: { value: "{color.core.black.value}" }, + secondary: { + value: "{color.font.primary.value}", + modify: [{ + type: "brighten", + // See https://gka.github.io/chroma.js/#color-brighten + // for definition of brighten + amount: 1 + }] + }, + tertiary: { + // transitive transforms allow you to modify a modified reference + value: "{color.font.secondary.value}", + modify: [{ + // this will brighten the secondary value, which is a brightened version + // of primary + type: "brighten", + amount: 1 + }] + }, + } + } +} diff --git a/examples/advanced/transitive-transforms/tokens/color/overlay.json5 b/examples/advanced/transitive-transforms/tokens/color/overlay.json5 new file mode 100644 index 000000000..e9a4a912c --- /dev/null +++ b/examples/advanced/transitive-transforms/tokens/color/overlay.json5 @@ -0,0 +1,23 @@ +{ + color: { + overlay: { + primary: { + value: "{color.core.white.value}", + modify: [{ + type: "alpha", + // You can access other parts of your style dictionary in here too: + amount: "{alpha.1}" + }] + }, + + secondary: { + value: "{color.core.white.value}", + modify: [{ + type: "alpha", + // You can access other parts of your style dictionary in here too: + amount: "{alpha.2}" + }] + } + } + } +} diff --git a/examples/advanced/transitive-transforms/tokens/hue.json5 b/examples/advanced/transitive-transforms/tokens/hue.json5 new file mode 100644 index 000000000..1af9eece8 --- /dev/null +++ b/examples/advanced/transitive-transforms/tokens/hue.json5 @@ -0,0 +1,13 @@ +{ + hue: { + red: 0, + orange: 25, + yellow: 50, + lime: 75, + green: 125, + teal: 175, + blue: 225, + purple: 275, + pink: 325 + } +} diff --git a/examples/advanced/transitive-transforms/tokens/lightness.json5 b/examples/advanced/transitive-transforms/tokens/lightness.json5 new file mode 100644 index 000000000..b40b24ae0 --- /dev/null +++ b/examples/advanced/transitive-transforms/tokens/lightness.json5 @@ -0,0 +1,18 @@ +{ + // Because these are not like a token object with a 'value' attribute, + // Style Dictionary won't consider them tokens and therefore won't output them. + // But, you can still access/reference them in tokens using the same reference + // syntax: "value": "{lightness.0}" + // This can be used when defining colors as HSL: + // "value": {"h": "{hue.red}", "l": "{lightness.0}", "s": "{saturation.0}"} + lightness: [ + 96, + 90, + 77, + 67, + 63, + 58, + 55, + 50 + ] +} diff --git a/examples/advanced/transitive-transforms/tokens/saturation.json5 b/examples/advanced/transitive-transforms/tokens/saturation.json5 new file mode 100644 index 000000000..9c4798755 --- /dev/null +++ b/examples/advanced/transitive-transforms/tokens/saturation.json5 @@ -0,0 +1,18 @@ +{ + // Because these are not like a token object with a 'value' attribute, + // Style Dictionary won't consider them tokens and therefore won't output them. + // But, you can still access/reference them in tokens using the same reference + // syntax: "value": "{lightness.0}" + // This can be used when defining colors as HSL: + // "value": {"h": "{hue.red}", "l": "{lightness.0}", "s": "{saturation.0}"} + saturation: [ + 100, + 90, + 85, + 80, + 75, + 70, + 65, + 50 + ] +} diff --git a/examples/advanced/variables-in-outputs/.gitignore b/examples/advanced/variables-in-outputs/.gitignore new file mode 100644 index 000000000..e3fbd9833 --- /dev/null +++ b/examples/advanced/variables-in-outputs/.gitignore @@ -0,0 +1,2 @@ +build +node_modules diff --git a/examples/advanced/variables-in-outputs/README.md b/examples/advanced/variables-in-outputs/README.md new file mode 100644 index 000000000..00a000cda --- /dev/null +++ b/examples/advanced/variables-in-outputs/README.md @@ -0,0 +1,49 @@ +## Use variables in output files + +This example shows how you keep aliases/references intact in certain types of formats as well as in custom formats. + +Common use cases include: + +- Vending theme-able output like CSS variables + +#### 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 uses the `sd.config.js` file as the Style Dictionary configuration. It is configured to use JSON files in the `tokens/` directory as the source files. It adds a custom format directly in the configuration (as opposed to using the `.registerFormat()` method) that uses 2 new methods added onto the internal dictionary object that is passed to formats and actions: `.usesReference()` and `.resolveReference()`. Also, it uses a new configuration on some formats: `keepReferences: true` to include variable references in the output. + + +#### What to look at + +The `sd.config.js` file has everything you need to see. The tokens included in this example are just enough to show these new techniques. + +Here is an example that shows how to get an alias's name within a custom format: +```javascript +//... +function(dictionary) { + return dictionary.allTokens.map(token => { + let value = JSON.stringify(token.value); + // the `dictionary` object now has `usesReference()` and + // `getReferences()` methods. `usesReference()` will return true if + // the value has a reference in it. `getReferences()` will return + // an array of references to the whole tokens so that you can access its + // name or any other attributes. + if (dictionary.usesReference(token.original.value)) { + const reference = dictionary.getReferences(token.original.value); + value = reference.name; + } + return `export const ${token.name} = ${value};` + }).join(`\n`) +} +``` + +The `build/` directory is where all the files are being built to. After Style Dictionary is run, take a look at the files it generates: + +* `build/tokens.js` This file is generated from the custom format in this example. Tokens that are references to other tokens use the variable name instead of raw value. +* `build/tokens.json` This file does not use variable references to show that other outputs work as intended. +* `build/tokens.css` This file is generated using the `css/variables` built-in format with the new `keepReferences` configuration. +* `build/tokens.scss` This file is generated using the `scss/variables` built-in format with the new `keepReferences` configuration. diff --git a/examples/advanced/variables-in-outputs/package.json b/examples/advanced/variables-in-outputs/package.json new file mode 100644 index 000000000..94c07c0a8 --- /dev/null +++ b/examples/advanced/variables-in-outputs/package.json @@ -0,0 +1,15 @@ +{ + "name": "style-dictionary-example-variables-in-outputs", + "version": "1.0.0", + "description": "", + "main": "sd.config.js", + "scripts": { + "build": "style-dictionary build --config ./sd.config.js" + }, + "keywords": [], + "author": "", + "license": "MIT", + "devDependencies": { + "style-dictionary": "3.0.0-rc.10" + } +} \ No newline at end of file diff --git a/examples/advanced/variables-in-outputs/sd.config.js b/examples/advanced/variables-in-outputs/sd.config.js new file mode 100644 index 000000000..e93105e07 --- /dev/null +++ b/examples/advanced/variables-in-outputs/sd.config.js @@ -0,0 +1,63 @@ +module.exports = { + format: { + // Adding a custom format to show how to get an alias's name. + customFormat: function({dictionary, options}) { + return dictionary.allTokens.map(token => { + let value = JSON.stringify(token.value); + // new option added to decide whether or not to output references + if (options.outputReferences) { + // the `dictionary` object now has `usesReference()` and + // `getReferences()` methods. `usesReference()` will return true if + // the value has a reference in it. `getReferences()` will return + // an array of references to the whole tokens so that you can access its + // name or any other attributes. + if (dictionary.usesReference(token.original.value)) { + const reference = dictionary.getReferences(token.original.value); + value = reference.name; + } + } + + return `export const ${token.name} = ${value};` + }).join(`\n`) + } + }, + + source: ['tokens/**/*.json'], + platforms: { + json: { + buildPath: 'build/', + files: [{ + destination: 'tokens.json', + format: 'json/nested' + }] + }, + js: { + buildPath: 'build/', + transformGroup: 'js', + files: [{ + destination: 'tokens.js', + format: 'customFormat', + options: { + outputReferences: true + } + }] + }, + css: { + transformGroup: 'css', + buildPath: 'build/', + files: [{ + destination: 'tokens.css', + format: 'css/variables', + options: { + outputReferences: true, // new setting, if true will use variable references + } + },{ + destination: 'tokens.scss', + format: 'scss/variables', + options: { + outputReferences: true, // new setting, if true will use variable references + } + }] + } + } +}; diff --git a/examples/advanced/variables-in-outputs/tokens/color/background.json b/examples/advanced/variables-in-outputs/tokens/color/background.json new file mode 100644 index 000000000..284b75a80 --- /dev/null +++ b/examples/advanced/variables-in-outputs/tokens/color/background.json @@ -0,0 +1,10 @@ +{ + "color": { + "background": { + "primary": { "value": "{color.palette.neutral.0.value}" }, + "secondary": { "value": "{color.palette.neutral.5.value}" }, + "tertiary": { "value": "{color.palette.neutral.10.value}" }, + "base": { "value": "{color.background.primary.value}" } + } + } +} diff --git a/examples/advanced/variables-in-outputs/tokens/color/palette.json b/examples/advanced/variables-in-outputs/tokens/color/palette.json new file mode 100644 index 000000000..d10980e6e --- /dev/null +++ b/examples/advanced/variables-in-outputs/tokens/color/palette.json @@ -0,0 +1,17 @@ +{ + "color" : { + "palette" : { + "neutral": { + "140" : { "value" : "#192026" }, + "100" : { "value" : "#303942" }, + "80" : { "value" : "#63676B" }, + "60" : { "value" : "#8C8F92" }, + "40" : { "value" : "#ADB0B3" }, + "20" : { "value" : "#D1D2D3" }, + "10" : { "value" : "#EAEBEC" }, + "5" : { "value" : "#F2F4F5" }, + "0" : { "value" : "#FFFFFF" } + } + } + } +} diff --git a/examples/advanced/yaml-tokens/README.md b/examples/advanced/yaml-tokens/README.md new file mode 100644 index 000000000..f2b554291 --- /dev/null +++ b/examples/advanced/yaml-tokens/README.md @@ -0,0 +1,18 @@ +## Yaml Tokens + +This example shows how to use a custom parser to define yaml token files. + +#### 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, if you want to build the tokens you can run `npm run build`. This command will run the Style Dictionary CLI with the **sd.config.js** as the configuration file and will generate the files in the `build` folder. + +#### How does it work? + +Style Dictionary added the ability to use custom parsers for token files in the 3.0 release. A custom parser has a regular expression pattern to match against source filenames. The parse function is then run taking the text content of the file and returning an object. A custom parser is like a module rule in a webpack configuration. + +#### What to look at + +The [`sd.config.js`](sd.config.js) file is the first thing to look at. It has a lot of comments how everything works. It shows how you can add a custom parser and set it to the yaml parser. You can also look in the [`tokens/`](tokens/) directory to see a yaml token file. + diff --git a/examples/advanced/yaml-tokens/package-lock.json b/examples/advanced/yaml-tokens/package-lock.json new file mode 100644 index 000000000..c41640c1d --- /dev/null +++ b/examples/advanced/yaml-tokens/package-lock.json @@ -0,0 +1,247 @@ +{ + "name": "style-dictionary-example-yaml-tokens", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "style-dictionary": { + "version": "3.0.0-rc.1", + "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-3.0.0-rc.1.tgz", + "integrity": "sha512-tSFRc/dz7IgTA/YeP3hDIMPi90cFtC1dbcrak2/DCmIBllI/u1yYovyBOejgwJjv6N8ite0iUtnM6Z5NnBcqpQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.6", + "json5": "^2.1.3", + "lodash": "^4.17.15", + "resolve-cwd": "^3.0.0", + "tinycolor2": "^1.4.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + } + } +} diff --git a/examples/advanced/yaml-tokens/package.json b/examples/advanced/yaml-tokens/package.json new file mode 100644 index 000000000..3333ca94e --- /dev/null +++ b/examples/advanced/yaml-tokens/package.json @@ -0,0 +1,15 @@ +{ + "name": "style-dictionary-example-yaml-tokens", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "style-dictionary build --config ./sd.config.js" + }, + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "style-dictionary": "3.0.0-rc.10", + "yaml": "^1.10.0" + } +} \ No newline at end of file diff --git a/examples/advanced/yaml-tokens/sd.config.js b/examples/advanced/yaml-tokens/sd.config.js new file mode 100644 index 000000000..a4782de18 --- /dev/null +++ b/examples/advanced/yaml-tokens/sd.config.js @@ -0,0 +1,26 @@ +const yaml = require('yaml'); + +module.exports = { + parsers: [{ + // A custom parser will only run against filenames that match the pattern + // This pattern will match any file with the .yaml extension. + // This allows you to mix different types of files in your token source + pattern: /\.yaml$/, + // the parse function takes a single argument, which is an object with + // 2 attributes: contents which is a string of the file contents, and + // filePath which is the path of the file. + // The function is expected to return a plain object. + parse: ({contents, filePath}) => yaml.parse(contents) + }], + source: [`tokens/**/*.yaml`], + platforms: { + css: { + transformGroup: 'css', + buildPath: 'build/', + files: [{ + destination: 'variables.css', + format: 'css/variables' + }] + } + } +} diff --git a/examples/advanced/yaml-tokens/tokens/color/core.yaml b/examples/advanced/yaml-tokens/tokens/color/core.yaml new file mode 100644 index 000000000..a7de733e8 --- /dev/null +++ b/examples/advanced/yaml-tokens/tokens/color/core.yaml @@ -0,0 +1,13 @@ +color: + base: + white: + value: "#fff" + red: + value: + r: 255 + g: 0 + b: 0 + green: + value: "rgb(0,255,0)" + success: + value: "{color.base.green.value}" diff --git a/examples/basic/README.md b/examples/basic/README.md index 599cd4908..985b48fe1 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -21,6 +21,10 @@ 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 @@ -39,7 +43,7 @@ Good for you! You have now built your first style dictionary! Moving on, take a ``` ├── README.md ├── config.json -├── properties/ +├── tokens/ │ ├── color/ │ ├── base.json │ ├── font.json @@ -49,6 +53,9 @@ Good for you! You have now built your first style dictionary! Moving on, take a │ ├── android/ │ ├── font_dimens.xml │ ├── colors.xml +│ ├── compose/ +│ ├── StyleDictionaryColor.kt +│ ├── StyleDictionarySize.kt │ ├── scss/ │ ├── _variables.scss │ ├── ios/ @@ -62,7 +69,7 @@ Good for you! You have now built your first style dictionary! Moving on, take a │ ├── StyleDictionarySize.swift ``` -If you open `config.json` you will see there are 3 platforms defined: scss, android, ios. 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: +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 @@ -87,6 +94,31 @@ If you open `config.json` you will see there are 3 platforms defined: scss, andr ``` +**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 @@ -138,11 +170,11 @@ $size-font-base: 1rem; ``` Pretty nifty! This shows a few things happening: -1. The build system does a deep merge of all the property JSON files defined in the `source` attribute of `config.json`. This allows you to split up the property 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 style properties. `{size.font.medium.value}` gets resolved properly. -1. The build system handles references to property values in other files as well as you can see in `properties/color/font.json`. +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 `properties/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. +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!** diff --git a/examples/basic/config.json b/examples/basic/config.json index 7376e16e8..968f321da 100644 --- a/examples/basic/config.json +++ b/examples/basic/config.json @@ -1,5 +1,5 @@ { - "source": ["properties/**/*.json"], + "source": ["tokens/**/*.json"], "platforms": { "scss": { "transformGroup": "scss", @@ -20,6 +20,32 @@ "format": "android/colors" }] }, + "compose": { + "transformGroup": "compose", + "buildPath": "build/compose/", + "files": [{ + "destination": "StyleDictionaryColor.kt", + "format": "compose/object", + "className": "StyleDictionaryColor", + "packageName": "StyleDictionaryColor", + "filter": { + "attributes": { + "category": "color" + } + } + },{ + "destination": "StyleDictionarySize.kt", + "format": "compose/object", + "className": "StyleDictionarySize", + "packageName": "StyleDictionarySize", + "type": "float", + "filter": { + "attributes": { + "category": "size" + } + } + }] + }, "ios": { "transformGroup": "ios", "buildPath": "build/ios/", diff --git a/examples/basic/properties/color/base.json b/examples/basic/tokens/color/base.json similarity index 100% rename from examples/basic/properties/color/base.json rename to examples/basic/tokens/color/base.json diff --git a/examples/basic/properties/color/font.json b/examples/basic/tokens/color/font.json similarity index 100% rename from examples/basic/properties/color/font.json rename to examples/basic/tokens/color/font.json diff --git a/examples/basic/properties/size/font.json b/examples/basic/tokens/size/font.json similarity index 100% rename from examples/basic/properties/size/font.json rename to examples/basic/tokens/size/font.json diff --git a/examples/complete/README.md b/examples/complete/README.md index 280697893..622511457 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -4,7 +4,7 @@ This starter project has everything you need to get started. ## How it works -All of the style properties and assets are in this package. Make any changes to suit your needs. This package has iOS, Android, and web code. +All of the design tokens and assets are in this package. Make any changes to suit your needs. This package has iOS, Android, and web code. To get started, run ``` @@ -12,7 +12,6 @@ $ npm install $ npm run build ``` -The npm build task is what performs the style dictionary build steps to generate the files for each platform. Every time you change something in the style dictionary, like changing colors or adding properties, you will have to run this command again to generate the files. +The npm build task is what performs the style dictionary build steps to generate the files for each platform. Every time you change something in the style dictionary, like changing colors or adding design tokens, you will have to run this command again to generate the files. ## iOS - diff --git a/examples/complete/android/build.gradle b/examples/complete/android/build.gradle index ad705ab40..988efbf2e 100644 --- a/examples/complete/android/build.gradle +++ b/examples/complete/android/build.gradle @@ -1,12 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - repositories { - jcenter() + ext.kotlin_version = '1.4.32' + repositories { mavenCentral() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:4.1.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -15,7 +17,7 @@ buildscript { allprojects { repositories { - jcenter() + google() mavenCentral() } } diff --git a/examples/complete/android/demo/build.gradle b/examples/complete/android/demo/build.gradle index be058082f..306362e31 100644 --- a/examples/complete/android/demo/build.gradle +++ b/examples/complete/android/demo/build.gradle @@ -1,13 +1,13 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' android { - compileSdkVersion 25 - buildToolsVersion '25.0.0' + compileSdkVersion 30 defaultConfig { applicationId "com.amazon.styledictionaryexample" minSdkVersion 23 - targetSdkVersion 25 + targetSdkVersion 30 versionCode 1 versionName "1.0" } @@ -24,18 +24,14 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile project(":styledictionary") - compile 'com.android.support:appcompat-v7:25.1.1' - compile 'com.jakewharton:butterknife:8.5.1' - compile 'com.fasterxml.jackson.core:jackson-core:2.8.6' - compile 'com.fasterxml.jackson.core:jackson-annotations:2.8.6' - compile 'com.fasterxml.jackson.core:jackson-databind:2.8.6' - compile 'com.fasterxml.jackson.datatype:jackson-datatype-json-org:2.8.6' - compile 'com.android.support:recyclerview-v7:25.1.1' - compile 'com.android.support:cardview-v7:25.1.1' - compile 'com.android.support:support-v4:25.1.1' - compile 'com.android.support:design:25.1.1' - testCompile 'junit:junit:4.12' - annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' + implementation project(":styledictionary") + implementation 'com.fasterxml.jackson.core:jackson-core:2.12.3' + implementation "androidx.recyclerview:recyclerview:1.1.0" + implementation "com.google.android.material:material:1.3.0" + implementation 'com.fasterxml.jackson.core:jackson-annotations:2.12.3' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-json-org:2.12.3' + implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.3" + testImplementation 'junit:junit:4.13.2' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/BaseActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/BaseActivity.java deleted file mode 100644 index 966f811ef..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/BaseActivity.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample; - -import android.app.Activity; -import android.content.Intent; -import android.view.MenuItem; - -public class BaseActivity extends Activity { - - @Override - public void finish() { - super.finish(); - overridePendingTransitionExit(); - } - - @Override - public void startActivity(Intent intent) { - super.startActivity(intent); - overridePendingTransitionEnter(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, as long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - - if (id == android.R.id.home) { - finish(); - overridePendingTransition(R.anim.slide_from_left, R.anim.slide_to_right); - return true; - } - - return super.onOptionsItemSelected(item); - } - - /** - * Overrides the pending Activity transition by performing the "Enter" animation. - */ - protected void overridePendingTransitionEnter() { - overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left); - } - - /** - * Overrides the pending Activity transition by performing the "Exit" animation. - */ - protected void overridePendingTransitionExit() { - overridePendingTransition(R.anim.slide_from_left, R.anim.slide_to_right); - } - -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/BaseActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/BaseActivity.kt new file mode 100644 index 000000000..49da043d7 --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/BaseActivity.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample + +import android.content.Intent +import android.view.MenuItem +import androidx.fragment.app.FragmentActivity + +open class BaseActivity : FragmentActivity() { + override fun finish() { + super.finish() + overridePendingTransitionExit() + } + + override fun startActivity(intent: Intent) { + super.startActivity(intent) + overridePendingTransitionEnter() + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, as long + // as you specify a parent activity in AndroidManifest.xml. + val id = item.itemId + if (id == android.R.id.home) { + finish() + overridePendingTransition(R.anim.slide_from_left, R.anim.slide_to_right) + return true + } + return super.onOptionsItemSelected(item) + } + + /** + * Overrides the pending Activity transition by performing the "Enter" animation. + */ + private fun overridePendingTransitionEnter() { + overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left) + } + + /** + * Overrides the pending Activity transition by performing the "Exit" animation. + */ + private fun overridePendingTransitionExit() { + overridePendingTransition(R.anim.slide_from_left, R.anim.slide_to_right) + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/ColorAdapter.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/ColorAdapter.java deleted file mode 100644 index b8a0ea2c9..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/ColorAdapter.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.amazon.styledictionaryexample; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.TextView; - -import com.amazon.styledictionaryexample.models.Property; - -import java.util.ArrayList; - -/** - * Created by djb on 2/12/17. - */ - -public class ColorAdapter extends BaseAdapter { - - private Context mContext; - private LayoutInflater mInflater; - private ArrayList mDataSource; - - public ColorAdapter(Context context, ArrayList items) { - mContext = context; - mDataSource = items; - mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - } - - /** - * How many items are in the data set represented by this Adapter. - * - * @return Count of items. - */ - @Override - public int getCount() { - return mDataSource.size(); - } - - - /** - * Get the data item associated with the specified position in the data set. - * - * @param position Position of the item whose data we want within the adapter's - * data set. - * @return The data at the specified position. - */ - @Override - public Object getItem(int position) { - return mDataSource.get(position); - } - - /** - * Get the row id associated with the specified position in the list. - * - * @param position The position of the item within the adapter's data set whose row id we want. - * @return The id of the item at the specified position. - */ - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - - ViewHolder holder; - - // no need to inflate and findViewById again, if the view already exists - if (convertView == null) { - - // Inflate the custom row layout from your XML. - convertView = mInflater.inflate(R.layout.list_item_color, parent, false); - - // create a new "Holder" with subviews - holder = new ViewHolder(); - holder.titleTextView = (TextView) convertView.findViewById(R.id.recipe_list_title); - holder.subtitleTextView = (TextView) convertView.findViewById(R.id.recipe_list_subtitle); - - // hang onto this holder for future recyclage - convertView.setTag(holder); - } - else { - - // skip all the expensive inflation/findViewById and get the holder you already made - holder = (ViewHolder) convertView.getTag(); - } - - // Get relevant subviews of row view - TextView titleTextView = holder.titleTextView; - TextView subtitleTextView = holder.subtitleTextView; - - //Get corresponding recipe for row - Property property = (Property) getItem(position); - - // Update row view's textviews to display recipe information - titleTextView.setText(property.name); - subtitleTextView.setText(property.value); - - return convertView; - } - - private static class ViewHolder { - public TextView titleTextView; - public TextView subtitleTextView; - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/MainActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/MainActivity.java deleted file mode 100644 index be81914a2..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/MainActivity.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample; - -import android.content.Intent; -import android.graphics.Typeface; -import android.os.Bundle; -import android.widget.Button; - -import com.amazon.styledictionaryexample.color.ColorsActivity; -import com.amazon.styledictionaryexample.icon.IconListActivity; -import com.amazon.styledictionaryexample.property.PropertiesActivity; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; - -public class MainActivity extends BaseActivity { - private static final String TAG = MainActivity.class.getSimpleName(); - private Typeface iconFont; - - @BindView(R.id.activity_main_properties_button) Button propertiesButton; - @BindView(R.id.activity_main_colors_button) Button colorsButton; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - StyleDictionaryHelper.loadJSON(this); - ButterKnife.bind(this); - } - - @OnClick(R.id.activity_main_colors_button) - public void colorsButton() { - Intent colorsIntent = new Intent(this, ColorsActivity.class); - startActivity(colorsIntent); - } - - - @OnClick(R.id.activity_main_properties_button) - public void propertiesButton() { - Intent propertiesIntent = new Intent(this, PropertiesActivity.class); - startActivity(propertiesIntent); - } - - @OnClick(R.id.activity_main_icons_button) - public void iconsButton() { - Intent iconsIntent = new Intent(this, IconListActivity.class); - startActivity(iconsIntent); - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/MainActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/MainActivity.kt new file mode 100644 index 000000000..7556e13ce --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/MainActivity.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample + +import android.content.Intent +import android.graphics.Typeface +import android.os.Bundle +import android.view.View +import android.widget.Button +import com.amazon.styledictionaryexample.color.ColorsActivity +import com.amazon.styledictionaryexample.icon.IconListActivity +import com.amazon.styledictionaryexample.property.PropertiesActivity +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper + +@Suppress("UNUSED_PARAMETER") +class MainActivity : BaseActivity() { + private var propertiesButton: Button? = null + private var colorsButton: Button? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + StyleDictionaryHelper.loadJSON(this) + propertiesButton = findViewById(R.id.activity_main_properties_button) + colorsButton = findViewById(R.id.activity_main_colors_button) + } + + fun colorsButton(view: View) { + val colorsIntent = Intent(this, ColorsActivity::class.java) + startActivity(colorsIntent) + } + + fun propertiesButton(view: View) { + val propertiesIntent = Intent(this, PropertiesActivity::class.java) + startActivity(propertiesIntent) + } + + fun iconsButton(view: View) { + val iconsIntent = Intent(this, IconListActivity::class.java) + startActivity(iconsIntent) + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BackgroundColorActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BackgroundColorActivity.java deleted file mode 100644 index 728c7c8cc..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BackgroundColorActivity.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.amazon.styledictionaryexample.color; - -import android.os.Bundle; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.amazon.styledictionaryexample.BaseActivity; -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.Property; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class BackgroundColorActivity extends BaseActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_background_color); - - View recyclerView = findViewById(R.id.background_color_list); - assert recyclerView != null; - - ((RecyclerView) recyclerView).setAdapter( - new SimpleItemRecyclerViewAdapter( getBackgroundColors() ) - ); - } - - protected ArrayList getBackgroundColors() { - ArrayList path = new ArrayList<>(); - path.add("color"); - path.add("background"); - return StyleDictionaryHelper.getArrayOfProps(path); - } - - public class SimpleItemRecyclerViewAdapter - extends RecyclerView.Adapter { - - private final List mValues; - - public SimpleItemRecyclerViewAdapter(List items) { - mValues = items; - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.background_color_list_item, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int position) { - holder.mItem = mValues.get(position); - int id = getResources().getIdentifier(holder.mItem.name, "color", getPackageName()); - holder.mSwatchView.setBackgroundColor(getResources().getColor(id, null)); - holder.mTitleView.setText(holder.mItem.attributes.get("item")); - - holder.mView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { -// Context context = v.getContext(); -// Intent intent = new Intent(context, IconDetailActivity.class); -// intent.putStringArrayListExtra(IconDetailFragment.ARG_ITEM_PATH, holder.mItem.path); -// context.startActivity(intent); - } - }); - } - - @Override - public int getItemCount() { - return mValues.size(); - } - - public class ViewHolder extends RecyclerView.ViewHolder { - public final View mView; - @BindView(R.id.swatch) - View mSwatchView; - @BindView(R.id.title) TextView mTitleView; - public Property mItem; - - public ViewHolder(View view) { - super(view); - mView = view; - ButterKnife.bind(this, view); - } - - @Override - public String toString() { - return super.toString() + " '" + mTitleView.getText() + "'"; - } - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BackgroundColorActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BackgroundColorActivity.kt new file mode 100644 index 000000000..48443dd20 --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BackgroundColorActivity.kt @@ -0,0 +1,63 @@ +package com.amazon.styledictionaryexample.color + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.amazon.styledictionaryexample.BaseActivity +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.models.Property +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper +import java.util.* + +class BackgroundColorActivity : BaseActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_background_color) + val recyclerView = findViewById(R.id.background_color_list)!! + (recyclerView as RecyclerView).adapter = SimpleItemRecyclerViewAdapter(backgroundColors) + } + + private val backgroundColors: ArrayList + get() { + val path = ArrayList() + path.add("color") + path.add("background") + return StyleDictionaryHelper.getArrayOfProps(path) + } + + inner class SimpleItemRecyclerViewAdapter(private val mValues: List) : + RecyclerView.Adapter() { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.background_color_list_item, parent, false) + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.item = mValues[position] + .apply { + val id = resources.getIdentifier(name, "color", packageName) + holder.swatchView.setBackgroundColor(resources.getColor(id, null)) + holder.titleView.text = attributes["item"] + } + } + + override fun getItemCount(): Int { + return mValues.size + } + + inner class ViewHolder(val view: View) : RecyclerView.ViewHolder( + view) { + val swatchView: View = view.findViewById(R.id.swatch) + val titleView: TextView = view.findViewById(R.id.title) + var item: Property? = null + override fun toString(): String { + return super.toString() + " '" + titleView.text + "'" + } + + } + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorActivity.java deleted file mode 100644 index dd59498d2..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorActivity.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample.color; - -import android.app.ActionBar; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.amazon.styledictionaryexample.BaseActivity; -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.Property; -import com.amazon.styledictionaryexample.models.StyleDictionaryNode; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class BaseColorActivity extends BaseActivity { - - private static final String TAG = BaseColorActivity.class.getSimpleName(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_base_color); - ActionBar ab = getActionBar(); - if (ab != null) { - ab.setDisplayHomeAsUpEnabled(true); - } - - View recyclerView = findViewById(R.id.base_color_list); - assert recyclerView != null; - - ((RecyclerView) recyclerView).setAdapter( - new SimpleItemRecyclerViewAdapter( getAllBaseColors() ) - ); - } - - - protected ArrayList getBaseColorList() { - ArrayList path = new ArrayList<>(); - path.add("color"); - path.add("base"); - return StyleDictionaryHelper.getArrayAtPath(path); - } - - protected ArrayList getAllBaseColors() { - ArrayList baseColors = getBaseColorList(); - ArrayList allColors = new ArrayList<>(); - ArrayList path = new ArrayList<>(); - path.add("color"); - path.add("base"); - for (StyleDictionaryNode node : baseColors) { - if (!node.name.equals("white") && !node.name.equals("black")) { - path.add(node.name); - path.add("500"); - Property header = StyleDictionaryHelper.getProperty(path); - allColors.add( new BaseColorListItem.BaseColorHeaderItem(header)); - path.remove( path.size() -1 ); - ArrayList props = StyleDictionaryHelper.getArrayOfProps(path); - for (Property prop : props) { - allColors.add( new BaseColorListItem.BaseColorItem(prop) ); - } - path.remove( path.size() -1 ); - } - } - return allColors; - } - - - public class SimpleItemRecyclerViewAdapter - extends RecyclerView.Adapter { - - private final List mValues; - - public SimpleItemRecyclerViewAdapter(List items) { - mValues = items; - } - - @Override - public int getItemViewType(int position) { - if (mValues.get(position).isHeader()) { - return 1; - } else { - return 0; - } - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view; - switch (viewType) { - case 0: - view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.base_color_list_content, parent, false); - break; - case 1: - view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.base_color_list_header, parent, false); - break; - default: - view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.base_color_list_content, parent, false); - break; - } - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - holder.mItem = mValues.get(position); - - int id = getResources().getIdentifier(holder.mItem.getProperty().name, "color", getPackageName()); - int fontColor; - - if (holder.mItem.getProperty().attributes.get("font").equals("inverse")) { - fontColor = getResources().getColor(R.color.color_font_inverse_base, null); - } else { - fontColor = getResources().getColor(R.color.color_font_base, null); - } - - holder.mTitleView.setText(holder.mItem.getTitle()); - holder.mTitleView.setTextColor(fontColor); - - if (holder.mValueView != null) { - holder.mValueView.setText(holder.mItem.getSubtitle()); - holder.mValueView.setTextColor(fontColor); - } - - holder.mView.setBackgroundColor(getResources().getColor(id, null)); - holder.mView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { -// Context context = v.getContext(); -// Intent intent = new Intent(context, IconDetailActivity.class); -// intent.putStringArrayListExtra(IconDetailFragment.ARG_ITEM_PATH, holder.mItem.path); -// context.startActivity(intent); - } - }); - } - - @Override - public int getItemCount() { - return mValues.size(); - } - - public class ViewHolder extends RecyclerView.ViewHolder { - public final View mView; - @BindView(R.id.title) TextView mTitleView; - @Nullable - @BindView(R.id.value) TextView mValueView; - public BaseColorListItem mItem; - - public ViewHolder(View view) { - super(view); - mView = view; - ButterKnife.bind(this, view); - } - - @Override - public String toString() { - return super.toString() + " '" + mTitleView.getText() + "'"; - } - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorActivity.kt new file mode 100644 index 000000000..8126e991d --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorActivity.kt @@ -0,0 +1,135 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample.color + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.amazon.styledictionaryexample.BaseActivity +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.color.BaseColorListItem.BaseColorHeaderItem +import com.amazon.styledictionaryexample.color.BaseColorListItem.BaseColorItem +import com.amazon.styledictionaryexample.models.StyleDictionaryNode +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper +import java.util.* + +class BaseColorActivity : BaseActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_base_color) + val ab = actionBar + ab?.setDisplayHomeAsUpEnabled(true) + val recyclerView = findViewById(R.id.base_color_list)!! + (recyclerView as RecyclerView).adapter = SimpleItemRecyclerViewAdapter(allBaseColors) + } + + private val baseColorList: ArrayList + get() { + val path = ArrayList() + path.add("color") + path.add("base") + return StyleDictionaryHelper.getArrayAtPath(path) + } + + private val allBaseColors: ArrayList + get() { + val baseColors = baseColorList + val allColors = ArrayList() + val path = ArrayList() + path.add("color") + path.add("base") + for (node in baseColors) { + if (node.name != "white" && node.name != "black") { + path.add(node.name) + path.add("500") + val header = StyleDictionaryHelper.getProperty(path) + allColors.add(BaseColorHeaderItem(header)) + path.removeAt(path.size - 1) + val props = StyleDictionaryHelper.getArrayOfProps(path) + for (prop in props) { + allColors.add(BaseColorItem(prop)) + } + path.removeAt(path.size - 1) + } + } + return allColors + } + + inner class SimpleItemRecyclerViewAdapter(private val values: List) : + RecyclerView.Adapter() { + override fun getItemViewType(position: Int): Int { + return if (values[position].isHeader) { + 1 + } else { + 0 + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = when (viewType) { + 0 -> LayoutInflater.from(parent.context) + .inflate(R.layout.base_color_list_content, parent, false) + 1 -> LayoutInflater.from(parent.context) + .inflate(R.layout.base_color_list_header, parent, false) + else -> LayoutInflater.from(parent.context) + .inflate(R.layout.base_color_list_content, parent, false) + } + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.item = values[position] + with(values[position]) { + + val id = resources.getIdentifier(property.name, "color", packageName) + val fontColor: Int = if (property.attributes["font"] == "inverse") { + resources.getColor(R.color.color_font_inverse_base, null) + } else { + resources.getColor(R.color.color_font_base, null) + } + + holder.titleView.text = title + holder.titleView.setTextColor(fontColor) + + if (holder.valueView != null) { + holder.valueView.text = subtitle + holder.valueView.setTextColor(fontColor) + } + + holder.view.setBackgroundColor(resources.getColor(id, null)) + holder.view.setOnClickListener { + } + } + } + + override fun getItemCount(): Int { + return values.size + } + + inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + + val titleView: TextView = view.findViewById(R.id.title) + val valueView: TextView? = view.findViewById(R.id.value) + + var item: BaseColorListItem? = null + + override fun toString(): String { + return super.toString() + " '${titleView.text} '" + } + + } + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorListItem.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorListItem.java deleted file mode 100644 index a64bf8a82..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorListItem.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.styledictionaryexample.color; - -import com.amazon.styledictionaryexample.models.Property; - -public interface BaseColorListItem { - boolean isHeader(); - String getTitle(); - String getSubtitle(); - Property getProperty(); - - - class BaseColorItem implements BaseColorListItem { - private final String title; - private final String subtitle; - public Property property; - - public BaseColorItem(String t, String s) { - title = t; - subtitle = s; - } - - public BaseColorItem(Property p) { - property = p; - title = p.attributes.get("subitem"); - subtitle = p.value; - } - - public Property getProperty() { return property; } - public String getTitle() { return title; } - public String getSubtitle() { return subtitle; } - public boolean isHeader() { return false; } - } - - class BaseColorHeaderItem implements BaseColorListItem { - private final String title; - private final String subtitle; - public Property property; - - public BaseColorHeaderItem(String t, String s) { - title = t; - subtitle = s; - } - - public BaseColorHeaderItem(Property p) { - property = p; - title = p.attributes.get("item"); - subtitle = p.name; - } - - public Property getProperty() { return property; } - public String getTitle() { return title; } - public String getSubtitle() { return subtitle; } - public boolean isHeader() { return true; } - } -} - - diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorListItem.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorListItem.kt new file mode 100644 index 000000000..c5da6140e --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/BaseColorListItem.kt @@ -0,0 +1,40 @@ +/** + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package com.amazon.styledictionaryexample.color + +import com.amazon.styledictionaryexample.models.Property + +interface BaseColorListItem { + val isHeader: Boolean + val title: String? + val subtitle: String + val property: Property + + class BaseColorItem(override val property: Property) : BaseColorListItem { + override val title: String? = property.attributes["subitem"] + override val subtitle: String = property.value + + override val isHeader: Boolean + get() = false + } + + class BaseColorHeaderItem(override var property: Property) : BaseColorListItem { + override val title: String? = property.attributes["item"] + override val subtitle: String = property.name + + override val isHeader: Boolean + get() = true + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorDetailFragment.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorDetailFragment.java deleted file mode 100644 index 590e4d6cb..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorDetailFragment.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample.color; - -import android.app.Fragment; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.Property; -import com.amazon.styledictionaryexample.property.PropertyDetailActivity; -import com.amazon.styledictionaryexample.util.StringHelper; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import java.util.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; - - -public class ColorDetailFragment extends Fragment { - - private Property property; - @BindView(R.id.color_swatch) View swatch; - @BindView(R.id.color_title) TextView title; - @BindView(R.id.color_detail_body) TextView body; - - public ColorDetailFragment() { - // Required empty public constructor - } - - public static ColorDetailFragment newInstance(ArrayList path) { - ColorDetailFragment fragment = new ColorDetailFragment(); - Bundle args = new Bundle(); - args.putStringArrayList(PropertyDetailActivity.ARG_PATH, path); - fragment.setArguments(args); - return fragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.fragment_color_detail, container, false); - ButterKnife.bind(this, view); - ArrayList path = getActivity().getIntent().getStringArrayListExtra(PropertyDetailActivity.ARG_PATH); - - if (path != null) { - property = StyleDictionaryHelper.getProperty( path ); - int id = getResources().getIdentifier(property.name, "color", getActivity().getPackageName()); - swatch.setBackgroundColor(getResources().getColor(id, null)); - title.setText( getTitle() ); - body.setText( "@color/".concat(property.name) ); - } - return view; - } - - - private String getTitle() { - switch(property.attributes.get("type")) { - case "base": - return StringHelper.nameToDisplay(property.attributes.get("item")) + " " + property.attributes.get("subitem"); - default: - return StringHelper.nameToDisplay(property.attributes.get("item")) + " " + property.attributes.get("subitem"); - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorDetailFragment.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorDetailFragment.kt new file mode 100644 index 000000000..6b7479b69 --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorDetailFragment.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample.color + +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.fragment.app.Fragment +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.models.Property +import com.amazon.styledictionaryexample.property.PropertyDetailActivity +import com.amazon.styledictionaryexample.util.StringHelper +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper + +class ColorDetailFragment : Fragment() { + private var property: Property? = null + private var swatch: View? = null + private var title: TextView? = null + private var body: TextView? = null + + @SuppressLint("SetTextI18n") + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + val view = inflater.inflate(R.layout.fragment_color_detail, container, false) + swatch = view.findViewById(R.id.color_swatch) + title = view.findViewById(R.id.color_title) + body = view.findViewById(R.id.color_detail_body) + val path = activity?.intent?.getStringArrayListExtra(PropertyDetailActivity.ARG_PATH) + if (path != null) { + property = StyleDictionaryHelper.getProperty(path).apply { + val id = resources.getIdentifier(name, "color", activity?.packageName) + swatch?.setBackgroundColor(resources.getColor(id, null)) + title?.text = getTitle() + body?.text = "@color/${property?.name}" + } + } + return view + } + + private fun Property.getTitle(): String { + return when (attributes["type"]) { + "base" -> StringHelper.nameToDisplay(attributes["item"].orEmpty()) + " " + attributes["subitem"] + else -> StringHelper.nameToDisplay(attributes["item"].orEmpty()) + " " + attributes["subitem"] + } + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorsActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorsActivity.java deleted file mode 100644 index f0b5aaeec..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorsActivity.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample.color; - -import android.content.Intent; -import android.os.Bundle; -import android.widget.Button; - -import com.amazon.styledictionaryexample.BaseActivity; -import com.amazon.styledictionaryexample.R; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; - -public class ColorsActivity extends BaseActivity { - - private static final String TAG = ColorsActivity.class.getSimpleName(); - - @BindView(R.id.activity_colors_base_button) - Button baseButton; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_colors); - ButterKnife.bind(this); - } - - @OnClick(R.id.activity_colors_base_button) - public void baseButton() { - Intent baseColorIntent = new Intent(this, BaseColorActivity.class); - startActivity(baseColorIntent); - } - - @OnClick(R.id.activity_colors_background_button) - public void backgroundButton() { - Intent backgroundColorIntent = new Intent(this, BackgroundColorActivity.class); - startActivity(backgroundColorIntent); - } - - @OnClick(R.id.activity_colors_font_button) - public void fontButton() { - Intent fontColorIntent = new Intent(this, FontColorActivity.class); - startActivity(fontColorIntent); - } - -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorsActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorsActivity.kt new file mode 100644 index 000000000..6c083676b --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/ColorsActivity.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +@file:Suppress("UNUSED_PARAMETER") + +package com.amazon.styledictionaryexample.color + +import android.content.Intent +import android.os.Bundle +import android.view.View +import android.widget.Button +import com.amazon.styledictionaryexample.BaseActivity +import com.amazon.styledictionaryexample.R + +class ColorsActivity : BaseActivity() { + private var baseButton: Button? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_colors) + baseButton = findViewById(R.id.activity_colors_base_button) + } + + fun baseButton(view: View?) { + val baseColorIntent = Intent(this, BaseColorActivity::class.java) + startActivity(baseColorIntent) + } + + fun backgroundButton(view: View?) { + val backgroundColorIntent = Intent(this, BackgroundColorActivity::class.java) + startActivity(backgroundColorIntent) + } + + fun fontButton(view: View?) { + val fontColorIntent = Intent(this, FontColorActivity::class.java) + startActivity(fontColorIntent) + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/FontColorActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/FontColorActivity.java deleted file mode 100644 index 64b170b61..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/FontColorActivity.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.amazon.styledictionaryexample.color; - -import android.os.Bundle; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.amazon.styledictionaryexample.BaseActivity; -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.Property; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class FontColorActivity extends BaseActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_font_color); - - View recyclerView = findViewById(R.id.font_color_list); - assert recyclerView != null; - - ((RecyclerView) recyclerView).setAdapter( - new SimpleItemRecyclerViewAdapter( getFontColors() ) - ); - } - - protected ArrayList getFontColors() { - ArrayList path = new ArrayList<>(); - path.add("color"); - path.add("font"); - return StyleDictionaryHelper.getArrayOfProps(path); - } - - public class SimpleItemRecyclerViewAdapter - extends RecyclerView.Adapter { - - private final List mValues; - - public SimpleItemRecyclerViewAdapter(List items) { - mValues = items; - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.background_color_list_item, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int position) { - holder.mItem = mValues.get(position); - int id = getResources().getIdentifier(holder.mItem.name, "color", getPackageName()); - holder.mSwatchView.setBackgroundColor(getResources().getColor(id, null)); - holder.mTitleView.setText(holder.mItem.attributes.get("item")); - - holder.mView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { -// Context context = v.getContext(); -// Intent intent = new Intent(context, IconDetailActivity.class); -// intent.putStringArrayListExtra(IconDetailFragment.ARG_ITEM_PATH, holder.mItem.path); -// context.startActivity(intent); - } - }); - } - - @Override - public int getItemCount() { - return mValues.size(); - } - - public class ViewHolder extends RecyclerView.ViewHolder { - public final View mView; - @BindView(R.id.swatch) - View mSwatchView; - @BindView(R.id.title) - TextView mTitleView; - public Property mItem; - - public ViewHolder(View view) { - super(view); - mView = view; - ButterKnife.bind(this, view); - } - - @Override - public String toString() { - return super.toString() + " '" + mTitleView.getText() + "'"; - } - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/FontColorActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/FontColorActivity.kt new file mode 100644 index 000000000..d1f04eb65 --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/color/FontColorActivity.kt @@ -0,0 +1,66 @@ +package com.amazon.styledictionaryexample.color + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.amazon.styledictionaryexample.BaseActivity +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.models.Property +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper +import java.util.* + +class FontColorActivity : BaseActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_font_color) + val recyclerView = findViewById(R.id.font_color_list)!! + (recyclerView as RecyclerView).adapter = + SimpleItemRecyclerViewAdapter( + fontColors) + } + + private val fontColors: ArrayList + get() { + val path = ArrayList() + path.add("color") + path.add("font") + return StyleDictionaryHelper.getArrayOfProps(path) + } + + inner class SimpleItemRecyclerViewAdapter(private val mValues: List) : + RecyclerView.Adapter() { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.background_color_list_item, parent, false) + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.item = mValues[position] + .apply { + + val id = resources.getIdentifier(name, "color", packageName) + holder.swatchView.setBackgroundColor(resources.getColor(id, null)) + holder.titleView.text = attributes["item"] + } + } + + override fun getItemCount(): Int { + return mValues.size + } + + inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + var swatchView: View = view.findViewById(R.id.swatch) + var titleView: TextView = view.findViewById(R.id.title) + + var item: Property? = null + override fun toString(): String { + return super.toString() + " '" + titleView.text + "'" + } + + } + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailActivity.java deleted file mode 100644 index a98a06086..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailActivity.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample.icon; - -import android.app.ActionBar; -import android.os.Bundle; - -import com.amazon.styledictionaryexample.BaseActivity; -import com.amazon.styledictionaryexample.R; - -/** - * An activity representing a single Icon detail screen. This - * activity is only used narrow width devices. On tablet-size devices, - * item details are presented side-by-side with a list of items - * in a {@link IconListActivity}. - */ -public class IconDetailActivity extends BaseActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_icon_detail); - - // Show the Up button in the action bar. - ActionBar actionBar = getActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } - - if (savedInstanceState == null) { - // Create the detail fragment and add it to the activity - // using a fragment transaction. - IconDetailFragment fragment = new IconDetailFragment(); - getFragmentManager() - .beginTransaction() - .add(R.id.icon_detail_container, fragment) - .commit(); - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailActivity.kt new file mode 100644 index 000000000..418a370e6 --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailActivity.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample.icon + +import android.os.Bundle +import com.amazon.styledictionaryexample.BaseActivity +import com.amazon.styledictionaryexample.R + +/** + * An activity representing a single Icon detail screen. This + * activity is only used narrow width devices. On tablet-size devices, + * item details are presented side-by-side with a list of items + * in a [IconListActivity]. + */ +class IconDetailActivity : BaseActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_icon_detail) + + // Show the Up button in the action bar. + val actionBar = actionBar + actionBar?.setDisplayHomeAsUpEnabled(true) + if (savedInstanceState == null) { + // Create the detail fragment and add it to the activity + // using a fragment transaction. + val fragment = IconDetailFragment() + supportFragmentManager + .beginTransaction() + .add(R.id.icon_detail_container, fragment) + .commit() + } + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailFragment.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailFragment.java deleted file mode 100644 index a1f8bcd90..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailFragment.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample.icon; - -import android.app.Fragment; -import android.graphics.Typeface; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.Property; -import com.amazon.styledictionaryexample.util.StringHelper; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import java.util.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; - -/** - * A fragment representing a single Icon detail screen. - * This fragment is either contained in a {@link IconListActivity} - * in two-pane mode (on tablets) or a {@link IconDetailActivity} - * on handsets. - */ -public class IconDetailFragment extends Fragment { - private static final String TAG = IconDetailFragment.class.getSimpleName(); - private Typeface iconFont; - public static final String ARG_ITEM_PATH = "path"; - private Property mItem; - @BindView(R.id.icon_detail_title) TextView title; - @BindView(R.id.icon_display) TextView icon; - @BindView(R.id.icon_detail_body) TextView body; - - /** - * Mandatory empty constructor for the fragment manager to instantiate the - * fragment (e.g. upon screen orientation changes). - */ - public IconDetailFragment() { - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.icon_detail, container, false); - ButterKnife.bind(this, view); - - ArrayList path = getActivity().getIntent().getStringArrayListExtra(ARG_ITEM_PATH); - iconFont = Typeface.createFromAsset(getActivity().getAssets(), "fonts/MaterialIcons-Regular.ttf"); - - if (path != null) { - mItem = StyleDictionaryHelper.getProperty( path ); - title.setText( StringHelper.nameToDisplay(mItem.attributes.get("item")) ); - icon.setTypeface(iconFont); - icon.setText(mItem.value); - body.setText("@string/".concat(mItem.name)); - } - - return view; - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailFragment.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailFragment.kt new file mode 100644 index 000000000..743eaec30 --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconDetailFragment.kt @@ -0,0 +1,72 @@ +/** + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample.icon + +import android.annotation.SuppressLint +import android.graphics.Typeface +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.fragment.app.Fragment +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.models.Property +import com.amazon.styledictionaryexample.util.StringHelper +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper + +/** + * A fragment representing a single Icon detail screen. + * This fragment is either contained in a [IconListActivity] + * in two-pane mode (on tablets) or a [IconDetailActivity] + * on handsets. + */ +class IconDetailFragment +/** + * Mandatory empty constructor for the fragment manager to instantiate the + * fragment (e.g. upon screen orientation changes). + */ + : Fragment() { + private var iconFont: Typeface? = null + private var item: Property? = null + private var title: TextView? = null + private var icon: TextView? = null + private var body: TextView? = null + + @SuppressLint("SetTextI18n") + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val view = inflater.inflate(R.layout.icon_detail, container, false) + icon = view.findViewById(R.id.icon_display) + title = view.findViewById(R.id.icon_detail_title) + body = view.findViewById(R.id.icon_detail_body) + val path = activity!!.intent.getStringArrayListExtra(ARG_ITEM_PATH) + iconFont = Typeface.createFromAsset(activity!!.assets, "fonts/MaterialIcons-Regular.ttf") + if (path != null) { + item = StyleDictionaryHelper.getProperty(path).apply { + title?.text = StringHelper.nameToDisplay(attributes["item"]!!) + icon?.typeface = iconFont + icon?.text = value + body?.text = "@string/$name" + } + } + return view + } + + companion object { + const val ARG_ITEM_PATH = "path" + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconListActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconListActivity.java deleted file mode 100644 index a46ccf666..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconListActivity.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample.icon; - -import android.app.ActionBar; -import android.content.Context; -import android.content.Intent; -import android.graphics.Typeface; -import android.os.Bundle; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.amazon.styledictionaryexample.BaseActivity; -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.Property; -import com.amazon.styledictionaryexample.util.StringHelper; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -/** - * An activity representing a list of Icons. - */ -public class IconListActivity extends BaseActivity { - private static final String TAG = IconListActivity.class.getSimpleName(); - private Typeface iconFont; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_icon_list); - // Show the Up button in the action bar. - ActionBar actionBar = getActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } - - iconFont = Typeface.createFromAsset(getAssets(), "fonts/MaterialIcons-Regular.ttf"); - - View recyclerView = findViewById(R.id.icon_list); - assert recyclerView != null; - - ((RecyclerView) recyclerView).setAdapter( - new SimpleItemRecyclerViewAdapter( getIconList() ) - ); - } - - protected ArrayList getIconList() { - ArrayList path = new ArrayList<>(); - path.add("content"); - path.add("icon"); - return StyleDictionaryHelper.getArrayOfProps(path); - } - - - public class SimpleItemRecyclerViewAdapter - extends RecyclerView.Adapter { - - private final List mValues; - - public SimpleItemRecyclerViewAdapter(List items) { - mValues = items; - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.icon_list_content, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int position) { - holder.mItem = mValues.get(position); - holder.mIconView.setText(holder.mItem.value); - holder.mTitleView.setText( StringHelper.nameToDisplay(holder.mItem.attributes.get("item")) ); - - holder.mView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Context context = v.getContext(); - Intent intent = new Intent(context, IconDetailActivity.class); - intent.putStringArrayListExtra(IconDetailFragment.ARG_ITEM_PATH, holder.mItem.path); - context.startActivity(intent); - } - }); - } - - @Override - public int getItemCount() { - return mValues.size(); - } - - public class ViewHolder extends RecyclerView.ViewHolder { - public final View mView; - @BindView(R.id.icon) TextView mIconView; - @BindView(R.id.title) TextView mTitleView; - public Property mItem; - - public ViewHolder(View view) { - super(view); - mView = view; - ButterKnife.bind(this, view); - mIconView.setTypeface(iconFont); - } - - @Override - public String toString() { - return super.toString() + " '" + mTitleView.getText() + "'"; - } - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconListActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconListActivity.kt new file mode 100644 index 000000000..892b8b33d --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/icon/IconListActivity.kt @@ -0,0 +1,97 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample.icon + +import android.content.Intent +import android.graphics.Typeface +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.amazon.styledictionaryexample.BaseActivity +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.models.Property +import com.amazon.styledictionaryexample.util.StringHelper +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper +import java.util.* + +/** + * An activity representing a list of Icons. + */ +class IconListActivity : BaseActivity() { + private var iconFont: Typeface? = null + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_icon_list) + // Show the Up button in the action bar. + val actionBar = actionBar + actionBar?.setDisplayHomeAsUpEnabled(true) + iconFont = Typeface.createFromAsset(assets, "fonts/MaterialIcons-Regular.ttf") + val recyclerView = findViewById(R.id.icon_list)!! + (recyclerView as RecyclerView).adapter = + SimpleItemRecyclerViewAdapter( + iconList) + } + + private val iconList: ArrayList + get() { + val path = ArrayList() + path.add("content") + path.add("icon") + return StyleDictionaryHelper.getArrayOfProps(path) + } + + inner class SimpleItemRecyclerViewAdapter(private val mValues: List) : + RecyclerView.Adapter() { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.icon_list_content, parent, false) + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.item = mValues[position] + .apply { + holder.iconView.text = value + holder.titleView.text = StringHelper.nameToDisplay(attributes["item"]!!) + holder.view.setOnClickListener { v -> + val context = v.context + val intent = Intent(context, IconDetailActivity::class.java) + intent.putStringArrayListExtra( + IconDetailFragment.ARG_ITEM_PATH, + ArrayList(this.path)) + context.startActivity(intent) + } + } + } + + override fun getItemCount(): Int { + return mValues.size + } + + inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + var iconView: TextView = view.findViewById(R.id.icon) + var titleView: TextView = view.findViewById(R.id.title) + var item: Property? = null + override fun toString(): String { + return super.toString() + " '" + titleView.text + "'" + } + + init { + iconView.typeface = iconFont + } + } + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/Property.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/Property.kt similarity index 56% rename from examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/Property.java rename to examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/Property.kt index ae6ae4e6f..5fc7e5a21 100644 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/Property.java +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/Property.kt @@ -12,24 +12,14 @@ * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ +package com.amazon.styledictionaryexample.models -package com.amazon.styledictionaryexample.models; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import java.util.ArrayList; -import java.util.Map; - -@JsonIgnoreProperties({"original"}) -public class Property { - - private static final String TAG = Property.class.getSimpleName(); - - public String name; - public String value; - public Map attributes; - public ArrayList path; - - public Property() {} -} +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +@JsonIgnoreProperties("original", "filePath", "isSource") +data class Property( + var name: String = "", + var value: String ="", + var attributes: Map = mutableMapOf(), + var path: List = emptyList() +) diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StringHelper.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/StyleDictionaryNode.kt similarity index 76% rename from examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StringHelper.java rename to examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/StyleDictionaryNode.kt index 7ff51c60b..22d3e950d 100644 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StringHelper.java +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/StyleDictionaryNode.kt @@ -12,12 +12,10 @@ * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ +package com.amazon.styledictionaryexample.models -package com.amazon.styledictionaryexample.util; - -public class StringHelper { - - public static String nameToDisplay(String str) { - return str.replaceAll("_", " "); - } -} +data class StyleDictionaryNode( + val name: String, + val count: Int = 0, + val isLeaf: Boolean = false +) \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertiesActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertiesActivity.java deleted file mode 100644 index 287c95ace..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertiesActivity.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample.property; - -import android.app.ActionBar; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.content.Intent; -import android.os.Bundle; -import android.transition.Slide; -import android.view.Gravity; - -import com.amazon.styledictionaryexample.BaseActivity; -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.StyleDictionaryNode; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import java.util.ArrayList; - - -public class PropertiesActivity extends BaseActivity implements PropertyFragment.OnListFragmentInteractionListener { - - public ArrayList path; - private static final String TAG = PropertiesActivity.class.getSimpleName(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - path = new ArrayList<>(); - setContentView(R.layout.activity_properties); - ActionBar ab = getActionBar(); - if (ab != null) { - ab.setDisplayHomeAsUpEnabled(true); - - } - } - - - public void onListFragmentInteraction(StyleDictionaryNode item) { - if (item.isLeaf) { - // Clone the path list because we don't want to - // add the properties key to the path - when the user goes back - // we don't need to try to pop off the last item - ArrayList _path = new ArrayList<>(path); - _path.add(item.name); - Intent intent = new Intent(this, PropertyDetailActivity.class); - intent.putStringArrayListExtra(PropertyDetailActivity.ARG_PATH, _path); - startActivity(intent); - } else { - path.add(item.name); - - ArrayList nodeList = StyleDictionaryHelper.getArrayAtPath(path); - - // Create new fragment and transaction - Fragment newFragment = PropertyFragment.newInstance(nodeList); - newFragment.setExitTransition( new Slide(Gravity.LEFT) ); - newFragment.setEnterTransition( new Slide(Gravity.RIGHT) ); - FragmentTransaction transaction = getFragmentManager().beginTransaction(); - - transaction.add(R.id.activity_properties, newFragment, item.name); - transaction.addToBackStack(item.name); - - // Commit the transaction - transaction.commit(); - } - } - - @Override - public void onBackPressed() { - if (getFragmentManager().getBackStackEntryCount() > 0) { - getFragmentManager().popBackStack(); - if (path.size() >= 1) { - path.remove(path.size() - 1); - } - } else { - super.onBackPressed(); - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertiesActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertiesActivity.kt new file mode 100644 index 000000000..4f60acb2e --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertiesActivity.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample.property + +import android.content.Intent +import android.os.Bundle +import android.transition.Slide +import android.view.Gravity +import androidx.fragment.app.Fragment +import com.amazon.styledictionaryexample.BaseActivity +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.models.StyleDictionaryNode +import com.amazon.styledictionaryexample.property.PropertyFragment.OnListFragmentInteractionListener +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper +import java.util.* + +class PropertiesActivity : BaseActivity(), OnListFragmentInteractionListener { + val path: MutableList = mutableListOf() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_properties) + val ab = actionBar + ab?.setDisplayHomeAsUpEnabled(true) + } + + override fun onListFragmentInteraction(item: StyleDictionaryNode?) { + if (item!!.isLeaf) { + // Clone the path list because we don't want to + // add the properties key to the path - when the user goes back + // we don't need to try to pop off the last item + val _path = ArrayList(path) + _path.add(item.name) + val intent = Intent(this, PropertyDetailActivity::class.java) + intent.putStringArrayListExtra(PropertyDetailActivity.ARG_PATH, _path) + startActivity(intent) + } else { + path.add(item.name) + val nodeList = StyleDictionaryHelper.getArrayAtPath(path) + + // Create new fragment and transaction + val newFragment: Fragment = PropertyFragment.newInstance(nodeList) + newFragment.exitTransition = Slide(Gravity.START) + newFragment.enterTransition = Slide(Gravity.END) + val transaction = supportFragmentManager.beginTransaction() + transaction.add(R.id.activity_properties, newFragment, item.name) + transaction.addToBackStack(item.name) + + // Commit the transaction + transaction.commit() + } + } + + override fun onBackPressed() { + if (supportFragmentManager.backStackEntryCount > 0) { + supportFragmentManager.popBackStack() + if (path.size >= 1) { + path.removeAt(path.size - 1) + } + } else { + super.onBackPressed() + } + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyDetailActivity.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyDetailActivity.java deleted file mode 100644 index 3681130f0..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyDetailActivity.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with - * the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -package com.amazon.styledictionaryexample.property; - -import android.app.ActionBar; -import android.app.Fragment; -import android.os.Bundle; - -import com.amazon.styledictionaryexample.BaseActivity; -import com.amazon.styledictionaryexample.icon.IconDetailFragment; -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.color.ColorDetailFragment; - -import java.util.ArrayList; - -public class PropertyDetailActivity extends BaseActivity { - public static final String ARG_PATH = "path"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_property_detail); - - // Show the Up button in the action bar. - ActionBar actionBar = getActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } - - if (savedInstanceState == null) { - // Create the detail fragment and add it to the activity - // using a fragment transaction. - ArrayList path = getIntent().getStringArrayListExtra(ARG_PATH); - String category = path.get(0); - Fragment fragment; - - switch (category) { - case "color": - fragment = new ColorDetailFragment(); - break; - case "content": - fragment = new IconDetailFragment(); - break; - default: - fragment = new ColorDetailFragment(); - break; - } - - getFragmentManager() - .beginTransaction() - .add(R.id.property_detail_container, fragment) - .commit(); - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyDetailActivity.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyDetailActivity.kt new file mode 100644 index 000000000..e47e78ec6 --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyDetailActivity.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with + * the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package com.amazon.styledictionaryexample.property + +import android.os.Bundle +import androidx.fragment.app.Fragment +import com.amazon.styledictionaryexample.BaseActivity +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.color.ColorDetailFragment +import com.amazon.styledictionaryexample.icon.IconDetailFragment + +class PropertyDetailActivity : BaseActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_property_detail) + + // Show the Up button in the action bar. + val actionBar = actionBar + actionBar?.setDisplayHomeAsUpEnabled(true) + if (savedInstanceState == null) { + // Create the detail fragment and add it to the activity + // using a fragment transaction. + val path = intent.getStringArrayListExtra(ARG_PATH) + val fragment: Fragment = when (path!![0]) { + "color" -> ColorDetailFragment() + "content" -> IconDetailFragment() + else -> ColorDetailFragment() + } + supportFragmentManager + .beginTransaction() + .add(R.id.property_detail_container, fragment) + .commit() + } + } + + companion object { + const val ARG_PATH = "path" + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyFragment.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyFragment.java deleted file mode 100644 index 67cbc1664..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyFragment.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.amazon.styledictionaryexample.property; - -import android.app.Fragment; -import android.content.Context; -import android.os.Bundle; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.StyleDictionaryNode; -import com.amazon.styledictionaryexample.util.StyleDictionaryHelper; - -import java.util.ArrayList; - -/** - * A fragment representing a list of Items. - *

- * Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener} - * interface. - */ -public class PropertyFragment extends Fragment { - - private static final String TAG = PropertyFragment.class.getSimpleName(); - - private OnListFragmentInteractionListener mListener; - private ArrayList nodeList; - - /** - * Mandatory empty constructor for the fragment manager to instantiate the - * fragment (e.g. upon screen orientation changes). - */ - public PropertyFragment() { - nodeList = StyleDictionaryHelper.getNodeArrayForObject(StyleDictionaryHelper.DICTIONARY_JSON); - } - - public static PropertyFragment newInstance(ArrayList nodeList) { - PropertyFragment fragment = new PropertyFragment(); - fragment.nodeList = nodeList; - return fragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_property_list, container, false); - - // Set the adapter - if (view instanceof RecyclerView) { - RecyclerView recyclerView = (RecyclerView) view; - recyclerView.setAdapter(new PropertyRecyclerViewAdapter(nodeList, mListener)); - } - return view; - } - - - @Override - public void onAttach(Context context) { - super.onAttach(context); - if (context instanceof OnListFragmentInteractionListener) { - mListener = (OnListFragmentInteractionListener) context; - } else { - throw new RuntimeException(context.toString() - + " must implement OnListFragmentInteractionListener"); - } - } - - @Override - public void onDetach() { - super.onDetach(); - mListener = null; - } - - /** - * This interface must be implemented by activities that contain this - * fragment to allow an interaction in this fragment to be communicated - * to the activity and potentially other fragments contained in that - * activity. - *

- * See the Android Training lesson Communicating with Other Fragments for more information. - */ - public interface OnListFragmentInteractionListener { - void onListFragmentInteraction(StyleDictionaryNode item); - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyFragment.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyFragment.kt new file mode 100644 index 000000000..bc1a528dc --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyFragment.kt @@ -0,0 +1,79 @@ +package com.amazon.styledictionaryexample.property + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.RecyclerView +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.models.StyleDictionaryNode +import com.amazon.styledictionaryexample.property.PropertyFragment.OnListFragmentInteractionListener +import com.amazon.styledictionaryexample.util.StyleDictionaryHelper +import java.util.* + +/** + * A fragment representing a list of Items. + * + * + * Activities containing this fragment MUST implement the [OnListFragmentInteractionListener] + * interface. + */ +class PropertyFragment : Fragment() { + private var mListener: OnListFragmentInteractionListener? = null + private var nodeList: ArrayList = + StyleDictionaryHelper.getNodeArrayForObject(StyleDictionaryHelper.DICTIONARY_JSON) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val view = inflater.inflate(R.layout.fragment_property_list, container, false) + + // Set the adapter + if (view is RecyclerView) { + view.adapter = PropertyRecyclerViewAdapter(nodeList, mListener) + } + return view + } + + override fun onAttach(context: Context) { + super.onAttach(context) + mListener = if (context is OnListFragmentInteractionListener) { + context + } else { + throw RuntimeException( + context.toString() + + " must implement OnListFragmentInteractionListener") + } + } + + override fun onDetach() { + super.onDetach() + mListener = null + } + + /** + * This interface must be implemented by activities that contain this + * fragment to allow an interaction in this fragment to be communicated + * to the activity and potentially other fragments contained in that + * activity. + * + * + * See the Android Training lesson [Communicating with Other Fragments](http://developer.android.com/training/basics/fragments/communicating.html) for more information. + */ + interface OnListFragmentInteractionListener { + fun onListFragmentInteraction(item: StyleDictionaryNode?) + } + + companion object { + fun newInstance(nodeList: ArrayList): PropertyFragment { + val fragment = PropertyFragment() + fragment.nodeList = nodeList + return fragment + } + } + +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyRecyclerViewAdapter.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyRecyclerViewAdapter.java deleted file mode 100644 index 2fa6325ae..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyRecyclerViewAdapter.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.amazon.styledictionaryexample.property; - -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.amazon.styledictionaryexample.R; -import com.amazon.styledictionaryexample.models.StyleDictionaryNode; -import com.amazon.styledictionaryexample.property.PropertyFragment.OnListFragmentInteractionListener; - -import java.util.List; - -/** - * {@link RecyclerView.Adapter} that can display a {@link StyleDictionaryNode} and makes a call to the - * specified {@link OnListFragmentInteractionListener}. - */ -public class PropertyRecyclerViewAdapter extends RecyclerView.Adapter { - - private static final String TAG = PropertyRecyclerViewAdapter.class.getSimpleName(); - private final List mValues; - private final OnListFragmentInteractionListener mListener; - - public PropertyRecyclerViewAdapter(List items, OnListFragmentInteractionListener listener) { - mValues = items; - mListener = listener; - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.fragment_property_list_item, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(final ViewHolder holder, int position) { - holder.mItem = mValues.get(position); - holder.mIdView.setText(mValues.get(position).name); - - if (mValues.get(position).isLeaf) { - - } else { - holder.mContentView.setText(String.valueOf(mValues.get(position).count)); - } - - holder.mView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (null != mListener) { - // Notify the active callbacks interface (the activity, if the - // fragment is attached to one) that an item has been selected. - mListener.onListFragmentInteraction(holder.mItem); - } - } - }); - } - - @Override - public int getItemCount() { - return mValues.size(); - } - - public class ViewHolder extends RecyclerView.ViewHolder { - public final View mView; - public final TextView mIdView; - public final TextView mContentView; - public StyleDictionaryNode mItem; - - public ViewHolder(View view) { - super(view); - mView = view; - mIdView = (TextView) view.findViewById(R.id.id); - mContentView = (TextView) view.findViewById(R.id.content); - } - - @Override - public String toString() { - return super.toString() + " '" + mContentView.getText() + "'"; - } - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyRecyclerViewAdapter.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyRecyclerViewAdapter.kt new file mode 100644 index 000000000..82121fc75 --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/property/PropertyRecyclerViewAdapter.kt @@ -0,0 +1,51 @@ +package com.amazon.styledictionaryexample.property + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.amazon.styledictionaryexample.R +import com.amazon.styledictionaryexample.models.StyleDictionaryNode +import com.amazon.styledictionaryexample.property.PropertyFragment.OnListFragmentInteractionListener + +/** + * [RecyclerView.Adapter] that can display a [StyleDictionaryNode] and makes a call to the + * specified [OnListFragmentInteractionListener]. + */ +class PropertyRecyclerViewAdapter( + private val values: List, + private val listener: OnListFragmentInteractionListener? +) : RecyclerView.Adapter() { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.fragment_property_list_item, parent, false) + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.item = values[position] + holder.idView.text = values[position].name + if (!values[position].isLeaf) { + holder.contentView.text = java.lang.String.valueOf(values[position].count) + } + holder.view.setOnClickListener { listener?.onListFragmentInteraction(holder.item) } + } + + override fun getItemCount(): Int { + return values.size + } + + inner class ViewHolder(val view: View) : RecyclerView.ViewHolder( + view) { + val idView: TextView = view.findViewById(R.id.id) as TextView + val contentView: TextView = view.findViewById(R.id.content) as TextView + + var item: StyleDictionaryNode? = null + + override fun toString(): String { + return super.toString() + " '" + contentView.text + "'" + } + + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/StyleDictionaryNode.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StringHelper.kt similarity index 76% rename from examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/StyleDictionaryNode.java rename to examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StringHelper.kt index b0e460614..8b19a223e 100644 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/models/StyleDictionaryNode.java +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StringHelper.kt @@ -1,22 +1,21 @@ -package com.amazon.styledictionaryexample.models; - /** * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ +package com.amazon.styledictionaryexample.util -public class StyleDictionaryNode { - public String name; - public int count; - public boolean isLeaf; -} +object StringHelper { + fun nameToDisplay(str: String): String { + return str.replace("_".toRegex(), " ") + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StyleDictionaryHelper.java b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StyleDictionaryHelper.java deleted file mode 100644 index 377960d7f..000000000 --- a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StyleDictionaryHelper.java +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - *

- * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.styledictionaryexample.util; - -import android.content.Context; - -import com.amazon.styledictionaryexample.models.Property; -import com.amazon.styledictionaryexample.models.StyleDictionaryNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Iterator; - -public class StyleDictionaryHelper { - - public static ObjectMapper MAPPER; - public static String DICTIONARY_JSON_STRING; - public static JSONObject DICTIONARY_JSON; - static { - MAPPER = new ObjectMapper().registerModule(new JsonOrgModule()); - } - - public static void loadJSON(Context context) { - DICTIONARY_JSON_STRING = loadJsonFromAsset("data/properties.json", context); - try { - DICTIONARY_JSON = new JSONObject(DICTIONARY_JSON_STRING); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - public static ArrayList getNodeArrayForObject(JSONObject json) { - final ArrayList nodeList = new ArrayList<>(); - Iterator keys = json.keys(); - while(keys.hasNext()) { - String key = keys.next(); - StyleDictionaryNode node = new StyleDictionaryNode(); - node.name = key; - try { - JSONObject jsonNode = json.getJSONObject(key); - if (jsonNode.has("value")) { - node.isLeaf = true; - } else { - node.count = jsonNode.length(); - } - } catch (JSONException e) { - e.printStackTrace(); - } - nodeList.add(node); - } - return nodeList; - } - - public static ArrayList getArrayAtPath(ArrayList path) { - final ArrayList nodeList = new ArrayList<>(); - JSONObject json = DICTIONARY_JSON; - try { - for (String pathPart : path) { - json = json.getJSONObject(pathPart); - } - - return getNodeArrayForObject(json); - } catch (JSONException e) { - e.printStackTrace(); - } - - return nodeList; - } - - public static JSONObject getObjectAtPath(ArrayList path) { - JSONObject json = DICTIONARY_JSON; - try { - for (String pathPart : path) { - json = json.getJSONObject(pathPart); - } - } catch (JSONException e) { - e.printStackTrace(); - } - - return json; - } - - public static JSONObject getObjectAtPath(ArrayList path, JSONObject json) { - try { - for (String pathPart : path) { - json = json.getJSONObject(pathPart); - } - } catch (JSONException e) { - e.printStackTrace(); - } - - return json; - } - - - public static Property getProperty(ArrayList path, JSONObject json) { - Property property; - try { - for (String pathPart : path) { - json = json.getJSONObject(pathPart); - } - - if (json.has("value")) { - property = MAPPER.convertValue(json, Property.class); - return property; - } else { - throw new RuntimeException("Property doesn't exist"); - } - } catch (JSONException e) { - e.printStackTrace(); - } - return new Property(); - } - - public static Property getProperty(ArrayList path) { - return getProperty(path, DICTIONARY_JSON); - } - - - public static ArrayList getArrayOfProps(ArrayList path) { - final ArrayList propertyList = new ArrayList<>(); - JSONObject json = DICTIONARY_JSON; - - try { - for (String pathPart : path) { - json = json.getJSONObject(pathPart); - } - Iterator keys = json.keys(); - - while(keys.hasNext()) { - String key = keys.next(); - JSONObject jsonProperty = json.getJSONObject(key); - if (jsonProperty.has("value")) { - Property property = MAPPER.convertValue(jsonProperty, Property.class); - propertyList.add(property); - } - } - } catch (JSONException e) { - e.printStackTrace(); - } - - return propertyList; - } - - - public static String loadJsonFromAsset(String filename, Context context) { - String json = null; - - try { - InputStream is = context.getAssets().open(filename); - int size = is.available(); - byte[] buffer = new byte[size]; - is.read(buffer); - is.close(); - json = new String(buffer, "UTF-8"); - } - catch (java.io.IOException ex) { - ex.printStackTrace(); - return null; - } - - return json; - } -} diff --git a/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StyleDictionaryHelper.kt b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StyleDictionaryHelper.kt new file mode 100644 index 000000000..edd628dff --- /dev/null +++ b/examples/complete/android/demo/src/main/java/com/amazon/styledictionaryexample/util/StyleDictionaryHelper.kt @@ -0,0 +1,135 @@ +/** + * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package com.amazon.styledictionaryexample.util + +import android.content.Context +import com.amazon.styledictionaryexample.models.Property +import com.amazon.styledictionaryexample.models.StyleDictionaryNode +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule +import org.json.JSONException +import org.json.JSONObject +import java.nio.charset.Charset +import java.util.* + +object StyleDictionaryHelper { + private var MAPPER: ObjectMapper? = null + private var DICTIONARY_JSON_STRING: String = "" + var DICTIONARY_JSON: JSONObject? = null + + fun loadJSON(context: Context) { + DICTIONARY_JSON_STRING = loadJsonFromAsset("data/properties.json", context) + try { + DICTIONARY_JSON = JSONObject(DICTIONARY_JSON_STRING) + } catch (e: JSONException) { + e.printStackTrace() + } + } + + fun getNodeArrayForObject(json: JSONObject?): ArrayList { + val nodeList = ArrayList() + val keys = json!!.keys() + while (keys.hasNext()) { + val key = keys.next() + var isLeaf = false + var count = 0 + try { + val jsonNode = json.getJSONObject(key) + if (jsonNode.has("value")) { + isLeaf = true + } else { + count = jsonNode.length() + } + } catch (e: JSONException) { + e.printStackTrace() + } + nodeList.add(StyleDictionaryNode(key, count, isLeaf)) + } + return nodeList + } + + fun getArrayAtPath(path: List): ArrayList { + val nodeList = ArrayList() + var json = DICTIONARY_JSON + try { + for (pathPart in path) { + json = json!!.getJSONObject(pathPart) + } + return getNodeArrayForObject(json) + } catch (e: JSONException) { + e.printStackTrace() + } + return nodeList + } + + private fun getProperty(path: ArrayList, jsonObject: JSONObject?): Property { + var json = jsonObject + val property: Property + try { + for (pathPart in path) { + json = json!!.getJSONObject(pathPart) + } + return if (json!!.has("value")) { + property = MAPPER!!.convertValue(json, Property::class.java) + property + } else { + throw RuntimeException("Property doesn't exist") + } + } catch (e: JSONException) { + e.printStackTrace() + throw e + } + } + + fun getProperty(path: ArrayList): Property { + return getProperty(path, DICTIONARY_JSON) + } + + fun getArrayOfProps(path: ArrayList): ArrayList { + val propertyList = ArrayList() + var json = DICTIONARY_JSON + try { + for (pathPart in path) { + json = json!!.getJSONObject(pathPart) + } + val keys = json!!.keys() + while (keys.hasNext()) { + val key = keys.next() + val jsonProperty = json.getJSONObject(key) + if (jsonProperty.has("value")) { + val property = MAPPER!!.convertValue(jsonProperty, Property::class.java) + propertyList.add(property) + } + } + } catch (e: JSONException) { + e.printStackTrace() + } + return propertyList + } + + @Suppress("SameParameterValue") + private fun loadJsonFromAsset(filename: String, context: Context): String { + val inputStream = context.assets.open(filename) + val size = inputStream.available() + val buffer = ByteArray(size) + inputStream.read(buffer) + inputStream.close() + return String(buffer, Charset.forName("UTF-8")) + } + + init { + MAPPER = ObjectMapper().registerModule(JsonOrgModule()) + } +} \ No newline at end of file diff --git a/examples/complete/android/demo/src/main/res/layout/activity_background_color.xml b/examples/complete/android/demo/src/main/res/layout/activity_background_color.xml index 9bb8bc0c6..421e51d5c 100644 --- a/examples/complete/android/demo/src/main/res/layout/activity_background_color.xml +++ b/examples/complete/android/demo/src/main/res/layout/activity_background_color.xml @@ -1,5 +1,5 @@ - - @@ -29,11 +30,13 @@ android:layout_height="wrap_content" android:id="@+id/activity_colors_background_button" android:layout_marginBottom="@dimen/size_padding_base" + android:onClick="backgroundButton" android:text="Background Colors"/>