Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New cut at documentation PR using current develop branch #198

Merged
merged 13 commits into from
Nov 30, 2018
2 changes: 1 addition & 1 deletion bin/style-dictionary
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ program

program
.command('clean')
.description('Removes files specificed in the config of the style dictionary package of the current directory.')
.description('Removes files specified in the config of the style dictionary package of the current directory.')
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved
.option('-c, --config <path>', 'set config path. defaults to ./config.json')
.option('-p, --platform [platform]', 'only clean specific platform(s). Must be defined in the config', collect, [])
.action(styleDictionaryClean);
Expand Down
101 changes: 18 additions & 83 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,102 +8,37 @@
# Style Dictionary
> *Style once, use everywhere.*

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 through npm, but can also be used like any normal node module if you want to extend its functionality.
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 through npm, but can also be used like any normal node module 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.

## Watch the Demo on Youtube
[![Watch the video](assets/fake_player.png)](http://youtu.be/1HREvonfqhY)

## Examples
[See examples of Style Dictionary here](examples.md)

## The basics
__A style dictionary consists of:__
1. [Style properties](#style-properties) organized in JSON files
1. Static assets that can be used across platforms
1. [Style properties](properties.md), which are organized in JSON files
1. Static assets, which are delivered across platforms
1. Configuration, which defines the transformation of the properties and assets into deliverables
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved

__What a style dictionary does:__
1. Allows the style properties and assets to be consumed in any platform or language

Let's take a look at a very basic example.

```json
{
"size": {
"font": {
"small" : { "value": "10px" },
"medium": { "value": "16px" },
"large" : { "value": "24px" },
"base" : { "value": "{size.font.medium.value}" }
}
}
}
```

Here we are creating some basic font size properties. The style property `size.font.small` is "10px" for example. The style definition size.font.base.value is automatically aliased to the value found in size.font.medium.value, so both of those resolve to "16px".

Now what the style dictionary build system will do with this information is convert it to different formats so that you can use these values in any type of codebase. From this one file you can generate any number of files like:

```scss
$size-font-small: 10px;
$size-font-medium: 16px;
$size-font-large: 24px;
$size-font-base: 16px;
```

```xml
<dimen name="font-small">10sp</dimen>
<dimen name="font-medium">16sp</dimen>
<dimen name="font-large">24sp</dimen>
<dimen name="font-base">16sp</dimen>
```

```objectivec
float const SizeFontSmall = 10.00f;
float const SizeFontMedium = 16.00f;
float const SizeFontLarge = 24.00f;
float const SizeFontBase = 16.00f;
```

This is a very simple example, take a deeper dive into the style dictionary framework in

The style dictionary framework is completely extensible and modular so you can create any type of file from a style dictionary.
If there is a new language, platform, file type, you can extend the style dictionary framework to create the files you need.

__Some other things you can build with a style dictionary__
1. Allows style properties and assets to be consumed in any platform or language for rendering styles
1. Allows the creation of digital media for use by humans (e.g. documentation, design libraries, etc)

__Things you can build with a style dictionary:__
1. Styling files for any platform
1. Images and graphics
1. Sketch files
1. Documentation site
1. _Literally anything_


## Style Properties

> Synonyms: design token, design variable, design constant, atom

A style property is a key/value data to describe any fundamental/atomic visual properties. This information is stored in a canonical
source, the style dictionary, and transformed for use in different platforms, languages, and contexts. A simple example is a 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 style dictionary organizes style properties in a structured way for easy access. Style properties are organized as a deep object
with the leaf nodes being the style properties.

```json
{
"color": {
"font": {
"base": { "value": "#111111" },
"secondary": { "value": "#333333" },
"tertiary": { "value": "#666666" },
"inverse": {
"base": { "value": "#ffffff" }
}
}
}
}
```

In this example there are 4 style properties: `color.font.base`, `color.font.secondary`, `color.font.tertiary`, and `color.font.inverse.base`.
A style property is any object in the JSON that has a `value` attribute on it. In this way you can nest properties at different levels.
This allows you to easily access the property as well as do things like get all the inverse font colors.
1. _Literally anything you want styles or style data in_

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 so 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 extend the style dictionary framework to create the necessary files.
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved


## Contributing
Expand Down
7 changes: 6 additions & 1 deletion docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
- [Overview](README.md)
- [Quick Start](quick_start.md)
- [Examples](examples.md)
- [Config](config.md)
- [Properties](properties.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)
- [Transforms](transforms.md)
- [Transform groups](transform_groups.md)
- [Formats](formats.md)
- [Templates](templates.md)
- [Actions](actions.md)
- [Build process](build_process.md)
13 changes: 13 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Architecture Overview

This is how Style Dictionary works under the hood.

## TODO

1. We need to replace the picture with one that is more representative of the process.
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved
1. The picture needs to remove the data ovals, which are confusing - this is supposed to show the process
1. The picture should have more examples underneath the sections to show what is happening
1. Each platform should be an actual example (android, ios, css), showing some actual differences between the platforms
1. We need to add a section below the image that contains a step by step walkthrough of each item in the image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbanksdesign After reviewing the image with @didoo's comments, can you modify it to show that the iOS, android, and web are just examples?. I think maybe if you replaced them with purple bubbles of "Start Platform Build" and then put the value of "iOS" underneath maybe?

Also maybe the final step should be "built files can then be consumed in each platform"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add an initial step for reading or processing the configuration?

![build structure](assets/build-diagram.png)
129 changes: 129 additions & 0 deletions docs/assets/properties.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Properties
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved

> Synonyms: design token, design variable, design constant, atom
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved

Style properties are stored a collection of JSON or JS module files. We usually keep them in a `properties` directory, but you can put them wherever you like,
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved
they just need to be referenced in the `source` attribute on your `config.json` file.

A property is 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, design variable, design constant, design atom).
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved

![](assets/property-definitions.png)
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved

A property is transformed for use in different platforms, languages, and contexts. A simple example is a 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 easy 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, so 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 "size.font.\*"
Multiple properties in a single file are simple to read and understand using the [`Category / Type / Item (CTI)`](#category-type-item-(cti)) method
```json
{
"size": {
"font": {
"small" : { "value": "10" },
"medium": { "value": "16" },
"large" : { "value": "24" },
}
}
}
```

# Attribute reference / alias
You can reference (alias) existing attributes by using the property name in brackets
```json
{
"size": {
"font": {
"small" : { "value": "10" },
"medium": { "value": "16" },
"large" : { "value": "24" },
"base" : { "value": "{size.font.medium.value}" }
}
}
}
```

# Property reference / alias
You can reference (alias) any part of the Style Dictionary the same way
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this example. It works only when you reference a leaf with a value. If you try to do this:

{
   "size": {
     "font": {
       "small" : { "value": "10" },
       "medium": { "value": "16" },
       "large" : { "value": "24" }
     }
   },
   "something": {
     "else": "{size.font}"
  }
 }

it will not produce in output a token $something-else-size-font-*** so it may be confusing/misleading report it in the documentation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbanksdesign whoa - it doesn't? This is a bug right?

```json
{
"size": {
"font": {
"small" : { "value": "10" },
"medium": { "value": "16" },
"large" : { "value": "24" },
"base" : "{size.font.medium}"
}
}
}
```


#### 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 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 structure to know if it should be applied. For instance, the 'color/hex' transform only applies to properties of the category 'color'.

----
41 changes: 6 additions & 35 deletions docs/build_process.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,10 @@ Here is what the build system is doing under the hood.

![build structure](assets/build-diagram.png)

## CLI

1. The build system looks for a config file. By default it looks for config.json in the current directory, or you can specify the config path with the `-c --config` flag.
1. If there is an `includes` attribute in the config, it will take those JSON files and deep merge them into the `properties` object.
1. It then takes all the JSON files in the `source` attribute in the config and performs a deep merge onto the `properties` object.
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. Perform all transforms, in order, defined in the transforms attribute or transformGroup.
1. Build all files defined in the files array
1. Perform any actions defined in the actions attribute


## Node

If you use this as a node module, the steps are slightly different, but the overall.

1. When you call the [`extend`](api.md#extend) method, you can either pass it a path to a JSON or JS config file, or give it a plain object that has the configuration. This will perform steps 1-3 above.
1. Then you can now call `buildAllPlatforms` or other methods like `buildPlatform('scss')` or `exportPlatform('javascript')`. This is equivalent to step 4 above.

```javascript
const StyleDictionary = require('style-dictionary');

const styleDictionary = StyleDictionary.extend( 'config.json' );
// is equivalent to this:
// const styleDictionary = StyleDictionary.extend(
// JSON.parse( fs.readFileSync( 'config.json' ) )
// )

// You can also extend with an object
// const styleDictionary = StyleDictionary.extend({ /* config options */ });

// This will perform step 3 above, for each platform:
// 1. Apply transforms
// 2. Build files
// 3. Perform actions
styleDictionary.buildAllPlatforms();
```
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a link to the "how_to_build" after the explanation of the build process?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deleted that / broke it into two - using the CLI and using the npm module. You think that works ok?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works ok :)

49 changes: 49 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Configuration

Style dictionaries are configuration driven. Your config file defines what executes and what to output when the style dictionary builds.

By default, Style Dictionary looks for a config.json file in the root of your package. You can also specify a custom location when you use the [CLI](how_to_build#cli). If you are using a [custom build system](how_to_build#custom-build-system), you can specify a custom location for a configuration file or use a plain Javascript object.
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved

## config.json
Here is a quick example:
```json
{
"source": ["properties/**/*.json"],
"platforms": {
"scss": {
"transformGroup": "scss",
"prefix": "sd",
"buildPath": "build/scss/",
"files": [{
"destination": "_variables.scss",
"format": "scss/variables"
}],
"actions": ["copy_assets"]
},
"android": {
"transforms": ["attribute/cti", "name/cti/snake", "color/hex", "size/remToSp", "size/remToDp"],
"buildPath": "build/android/src/main/res/values/",
"files": [{
"destination": "style_dictionary_colors.xml",
"format": "android/colors"
}]
}
}
}
```

| Attribute | Type | Description |
| :--- | :--- | :--- |
| includes | Array[String] (optional) | An array of paths 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 includes. |
| source | Array[String] | An array of paths to Style Dictionary property files that contain the project styles. The Style Dictionary will do a deep merge of all of the JSON files so you can 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/templates 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 so each platform can 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`. |
| 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. |
chazzmoney marked this conversation as resolved.
Show resolved Hide resolved
| 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. Must declare a format or a template. |
| platform.file.template | String (optional) | [Template](templates.md) used to generate the file. Can be a built-in one or you can create your own. |
| 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. |

----
Loading