Comparing version 8.0.1 to 8.1.1
@@ -8,3 +8,10 @@ // Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
module.exports = ({ src = "", dest, setup, formats, transform }) => { | ||
module.exports = ({ | ||
src = "", | ||
dest, | ||
setup, | ||
formats, | ||
transform, | ||
resolveMetaAliases | ||
}) => { | ||
if (setup) { | ||
@@ -21,3 +28,4 @@ const setupModuleFile = path.resolve(process.cwd(), setup); | ||
type: transform, | ||
file: path.resolve(process.cwd(), src) | ||
file: path.resolve(process.cwd(), src), | ||
resolveMetaAliases | ||
}, | ||
@@ -24,0 +32,0 @@ format: { |
@@ -14,3 +14,4 @@ #!/usr/bin/env node | ||
formats: (argv.format || "raw.json").split(","), | ||
transform: argv.transform || "raw" | ||
transform: argv.transform || "raw", | ||
resolveMetaAliases: argv.resolveMetaAliases || false | ||
}; | ||
@@ -17,0 +18,0 @@ |
@@ -8,2 +8,6 @@ # Change Log | ||
## [8.1.1] | ||
- Added `resolveMetaAliases` option to resolve aliases in metadata. - see [#172](https://github.com/salesforce-ux/theo/issues/172) | ||
## [8.0.1] | ||
@@ -10,0 +14,0 @@ |
21
CLI.md
@@ -15,8 +15,9 @@ # Theo CLI | ||
|Name|Description|Default| | ||
|----|-----------|-------| | ||
|`--transform`|valid theo transform|`raw`| | ||
|`--format`|Comma separated list of valid theo formats|`raw.json`| | ||
|`--dest`|The path where the result should be written|stdout| | ||
|`--setup`|The path to an optional JS module that can set up Theo before transformation.|| | ||
| Name | Description | Default | | ||
| ---------------------- | ----------------------------------------------------------------------------- | ---------- | | ||
| `--transform` | valid theo transform | `raw` | | ||
| `--format` | Comma separated list of valid theo formats | `raw.json` | | ||
| `--dest` | The path where the result should be written | stdout | | ||
| `--setup` | The path to an optional JS module that can set up Theo before transformation. | | | ||
| `--resolveMetaAliases` | Resolve aliases in metadata | `false` | | ||
@@ -28,4 +29,6 @@ ### transforms / formats | ||
Usage example with formats: | ||
``` | ||
$ theo tokens.yml --transform web --format scss,cssmodules.css | ||
$ theo tokens.yml --transform web --format scss,cssmodules.css --resolveMetaAliases | ||
``` | ||
@@ -38,7 +41,8 @@ | ||
Example module (example.js): | ||
``` | ||
module.exports = theo => { | ||
theo.registerValueTransform( | ||
'addpx', | ||
prop => prop.get('type') === 'size', | ||
'addpx', | ||
prop => prop.get('type') === 'size', | ||
prop => prop.get('value') + 'px' | ||
@@ -51,2 +55,3 @@ ); | ||
Usage example with setup | ||
``` | ||
@@ -53,0 +58,0 @@ $ theo tokens.yml --setup example.js --transform web --format scss |
@@ -46,2 +46,8 @@ // Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
) | ||
.chain( | ||
def => | ||
options.get("resolveMetaAliases") === false | ||
? Either.of(def) | ||
: Either.try(resolveMetaAliases)(def) | ||
) | ||
.map(addPropName); | ||
@@ -161,2 +167,3 @@ /** | ||
.delete("imports"); | ||
/** | ||
@@ -179,2 +186,3 @@ * Resolve aliases that refer to other aliases | ||
}); | ||
/** | ||
@@ -186,5 +194,6 @@ * Resolve aliases inside prop values | ||
const aliases = def.get("aliases", Immutable.Map()); | ||
return props.map((value, key) => | ||
value.update("value", v => | ||
recursiveMap(v, v => { | ||
return props.map((value, key) => { | ||
return value.update("value", v => { | ||
return recursiveMap(v, v => { | ||
if (typeof v !== "string") return v; | ||
@@ -196,7 +205,37 @@ return allMatches(v, ALIAS_PATTERN).reduce((v, [alias, key]) => { | ||
}, v); | ||
}) | ||
) | ||
); | ||
}); | ||
}); | ||
}); | ||
}); | ||
/** | ||
* Resolve aliases inside prop meta data | ||
*/ | ||
const resolveMetaAliases = def => { | ||
return def.update("props", data => { | ||
const aliases = def.get("aliases", Immutable.Map()); | ||
return data.map((value, key) => { | ||
if (Immutable.Map.isMap(value.get("meta"))) { | ||
return value.update("meta", md => { | ||
return recursiveMap(md, md => { | ||
if (typeof md !== "string") return md; | ||
return allMatches(md, ALIAS_PATTERN).reduce( | ||
(md, [alias, key]) => { | ||
if (!aliases.has(key)) | ||
throw new Error(`Alias "${key}" not found`); | ||
return md.replace(alias, aliases.getIn([key, "value"])); | ||
}, | ||
md | ||
); | ||
}); | ||
}); | ||
} else { | ||
return value; | ||
} | ||
}); | ||
}); | ||
}; | ||
/** | ||
* | ||
@@ -203,0 +242,0 @@ */ |
@@ -120,6 +120,9 @@ // Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
.chain(data => format(Object.assign({}, options.format, { data }))) | ||
.fold(e => { | ||
if (isString(e)) throw new Error(e); | ||
throw e; | ||
}, r => r); | ||
.fold( | ||
e => { | ||
if (isString(e)) throw new Error(e); | ||
throw e; | ||
}, | ||
r => r | ||
); | ||
@@ -126,0 +129,0 @@ const convert = options => |
{ | ||
"name": "theo", | ||
"version": "8.0.1", | ||
"version": "8.1.1", | ||
"license": "BSD-3-Clause", | ||
@@ -5,0 +5,0 @@ "description": "Design Tokens formatter", |
194
README.md
@@ -34,3 +34,3 @@ # <img src="https://raw.githubusercontent.com/salesforce-ux/theo/master/assets/theo.png" alt="Theo logo" width="28" /> Theo | ||
```js | ||
const theo = require('theo'); | ||
const theo = require("theo"); | ||
@@ -40,7 +40,7 @@ theo | ||
transform: { | ||
type: 'web', | ||
file: 'buttons.yml' | ||
type: "web", | ||
file: "buttons.yml" | ||
}, | ||
format: { | ||
type: 'scss' | ||
type: "scss" | ||
} | ||
@@ -60,8 +60,8 @@ }) | ||
| Name | Value Transforms | ||
|-- | --- | ||
| `raw` | `[]` | ||
| `web` | `['color/rgb']` | ||
| `ios` | `['color/rgb', 'relative/pixelValue', 'percentage/float']` | ||
| `android` | `['color/hex8argb', 'relative/pixelValue', 'percentage/float']` | ||
| Name | Value Transforms | | ||
| --------- | --------------------------------------------------------------- | | ||
| `raw` | `[]` | | ||
| `web` | `['color/rgb']` | | ||
| `ios` | `['color/rgb', 'relative/pixelValue', 'percentage/float']` | | ||
| `android` | `['color/hex8argb', 'relative/pixelValue', 'percentage/float']` | | ||
@@ -72,11 +72,11 @@ ### Value Transforms | ||
| Name | Predicate | Description | ||
|--- | --- | --- | ||
| `color/rgb` | `prop.type === 'color'` | Convert to rgb | ||
| `color/hex` | `prop.type === 'color'` | Convert to hex | ||
| `color/hex8rgba` | `prop.type === 'color'` | Convert to hex8rgba | ||
| `color/hex8argb` | `prop.type === 'color'` | Convert to hex8argb | ||
| `percentage/float`| `/%/.test(prop.value)` | Convert a percentage to a decimal percentage | ||
| `relative/pixel` | `isRelativeSpacing` | Convert a r/em value to a pixel value | ||
| `relative/pixelValue` | `isRelativeSpacing` | Convert a r/em value to a pixel value (excluding the `px` suffix) | ||
| Name | Predicate | Description | | ||
| --------------------- | ----------------------- | ----------------------------------------------------------------- | | ||
| `color/rgb` | `prop.type === 'color'` | Convert to rgb | | ||
| `color/hex` | `prop.type === 'color'` | Convert to hex | | ||
| `color/hex8rgba` | `prop.type === 'color'` | Convert to hex8rgba | | ||
| `color/hex8argb` | `prop.type === 'color'` | Convert to hex8argb | | ||
| `percentage/float` | `/%/.test(prop.value)` | Convert a percentage to a decimal percentage | | ||
| `relative/pixel` | `isRelativeSpacing` | Convert a r/em value to a pixel value | | ||
| `relative/pixelValue` | `isRelativeSpacing` | Convert a r/em value to a pixel value (excluding the `px` suffix) | | ||
@@ -191,3 +191,3 @@ ### Custom Transforms / Value Transforms | ||
// If prop has 'comment' key, that value will go here. | ||
export const propName = 'PROP_VALUE'; | ||
export const propName = "PROP_VALUE"; | ||
``` | ||
@@ -200,3 +200,3 @@ | ||
// If prop has 'comment' key, that value will go here. | ||
propName: 'PROP_VALUE' | ||
propName: "PROP_VALUE" | ||
}; | ||
@@ -213,3 +213,3 @@ ``` | ||
let formatOptions = { | ||
type: 'html', | ||
type: "html", | ||
options: { | ||
@@ -222,34 +222,36 @@ transformPropName: name => name.toUpperCase() | ||
#### Configurable options | ||
| Option | Type | Default | Description | ||
|-- | -- | -- | --- | ||
| `transformPropName` | `function` | [`lodash/camelCase`](https://lodash.com/docs/#camelCase) | Converts `name` to camel case. | ||
| Option | Type | Default | Description | | ||
| ------------------- | ---------- | -------------------------------------------------------- | ------------------------------ | | ||
| `transformPropName` | `function` | [`lodash/camelCase`](https://lodash.com/docs/#camelCase) | Converts `name` to camel case. | | ||
#### Supported categories | ||
Tokens are grouped by category then categories are conditionally rendered under a human-friendly display name. Tokens with `category` values not in this list will still be converted and included in the generated output for all other formats. | ||
| Category | Friendly Name | ||
|-- | --- | ||
| `spacing` | Spacing | ||
| `sizing` | Sizing | ||
| `font` | Fonts | ||
| `font-style` | Font Styles | ||
| `font-weight` | Font Weights | ||
| `font-size` | Font Sizes | ||
| `line-height` | Line Heights | ||
| `font-family` | Font Families | ||
| `border-style` | Border Styles | ||
| `border-color` | Border Colors | ||
| `radius` | Radius | ||
| `border-radius` | Border Radii | ||
| `hr-color` | Horizontal Rule Colors | ||
| `background-color` | Background Colors | ||
| `gradient` | Gradients | ||
| `background-gradient` | Background Gradients | ||
| `drop-shadow` | Drop Shadows | ||
| `box-shadow` | Box Shadows | ||
| `inner-shadow` | Inner Drop Shadows | ||
| `text-color` | Text Colors | ||
| `text-shadow` | Text Shadows | ||
| `time` | Time | ||
| `media-query` | Media Queries | ||
| Category | Friendly Name | | ||
| --------------------- | ---------------------- | | ||
| `spacing` | Spacing | | ||
| `sizing` | Sizing | | ||
| `font` | Fonts | | ||
| `font-style` | Font Styles | | ||
| `font-weight` | Font Weights | | ||
| `font-size` | Font Sizes | | ||
| `line-height` | Line Heights | | ||
| `font-family` | Font Families | | ||
| `border-style` | Border Styles | | ||
| `border-color` | Border Colors | | ||
| `radius` | Radius | | ||
| `border-radius` | Border Radii | | ||
| `hr-color` | Horizontal Rule Colors | | ||
| `background-color` | Background Colors | | ||
| `gradient` | Gradients | | ||
| `background-gradient` | Background Gradients | | ||
| `drop-shadow` | Drop Shadows | | ||
| `box-shadow` | Box Shadows | | ||
| `inner-shadow` | Inner Drop Shadows | | ||
| `text-color` | Text Colors | | ||
| `text-shadow` | Text Shadows | | ||
| `time` | Time | | ||
| `media-query` | Media Queries | | ||
@@ -268,7 +270,7 @@ ### json | ||
{ | ||
"props": { | ||
"PROP_NAME": { | ||
"value": "PROP_VALUE", | ||
"type": "PROP_TYPE", | ||
"category": "PROP_CATEGORY" | ||
props: { | ||
PROP_NAME: { | ||
value: "PROP_VALUE", | ||
type: "PROP_TYPE", | ||
category: "PROP_CATEGORY" | ||
} | ||
@@ -283,8 +285,8 @@ } | ||
{ | ||
"properties": [ | ||
properties: [ | ||
{ | ||
"name": "propName", | ||
"value": "PROP_VALUE", | ||
"type": "PROP_TYPE", | ||
"category": "PROP_CATEGORY" | ||
name: "propName", | ||
value: "PROP_VALUE", | ||
type: "PROP_TYPE", | ||
category: "PROP_CATEGORY" | ||
} | ||
@@ -319,6 +321,6 @@ ] | ||
```js | ||
const theo = require('theo'); | ||
const theo = require("theo"); | ||
theo.registerFormat( | ||
'array.js', | ||
"array.js", | ||
` | ||
@@ -344,7 +346,7 @@ // Source: {{stem meta.file}} | ||
```js | ||
const camelCase = require('lodash/camelCase'); | ||
const path = require('path'); | ||
const theo = require('theo'); | ||
const camelCase = require("lodash/camelCase"); | ||
const path = require("path"); | ||
const theo = require("theo"); | ||
theo.registerFormat('array.js', result => { | ||
theo.registerFormat("array.js", result => { | ||
// "result" is an Immutable.Map | ||
@@ -354,8 +356,8 @@ // https://facebook.github.io/immutable-js/ | ||
module.exports = [ | ||
// Source: ${path.basename(result.getIn(['meta', 'file']))} | ||
// Source: ${path.basename(result.getIn(["meta", "file"]))} | ||
${result | ||
.get('props') | ||
.get("props") | ||
.map( | ||
prop => ` | ||
['${camelCase(prop.get('name'))}', '${prop.get('value')}'], | ||
['${camelCase(prop.get("name"))}', '${prop.get("value")}'], | ||
` | ||
@@ -374,3 +376,11 @@ ) | ||
transform: TransformOptions, | ||
format: FormatOptions | ||
format: FormatOptions, | ||
/* | ||
This option configures theo to resolve aliases. It is set (true) by default and | ||
currently CANNOT be disabled. | ||
*/ | ||
resolveAliases?: boolean, | ||
// This option configures theo to resolve aliases in metadata. This is off (false) by default. | ||
resolveMetaAliases?: boolean | ||
} | ||
@@ -458,7 +468,7 @@ | ||
// A map of property names and value objects | ||
"props": { | ||
"color_brand": { | ||
props: { | ||
color_brand: { | ||
// Required | ||
// Can be any valid JSON value | ||
"value": "#ff0000", | ||
value: "#ff0000", | ||
@@ -468,3 +478,3 @@ // Required | ||
// [color|number|...] | ||
"type": "color", | ||
type: "color", | ||
@@ -474,3 +484,3 @@ // Required | ||
// Often used for style guide generation | ||
"category": "background", | ||
category: "background", | ||
@@ -480,17 +490,17 @@ // Optional | ||
// but excluded during formatting | ||
"meta": { | ||
meta: { | ||
// This value might be needed for some special transform | ||
"foo": "bar" | ||
foo: "bar" | ||
} | ||
} | ||
}, | ||
// Optional | ||
// Alternatively, you can define props as an array | ||
// Useful for maintaining source order in output tokens | ||
"props": [ | ||
props: [ | ||
{ | ||
// Required | ||
"name": "color_brand", | ||
name: "color_brand" | ||
// All other properties same as above | ||
@@ -503,6 +513,6 @@ } | ||
// Values defined on a property level will take precedence | ||
"global": { | ||
"category": "some-category", | ||
"meta": { | ||
"foo": "baz" | ||
global: { | ||
category: "some-category", | ||
meta: { | ||
foo: "baz" | ||
} | ||
@@ -514,7 +524,7 @@ }, | ||
// Aliases are resolved like: {!sky} | ||
"aliases": { | ||
"sky": "blue", | ||
"grass": { | ||
"value": "green", | ||
"yourMetadata": "How grass looks" | ||
aliases: { | ||
sky: "blue", | ||
grass: { | ||
value: "green", | ||
yourMetadata: "How grass looks" | ||
} | ||
@@ -528,5 +538,5 @@ }, | ||
// "global" will already be merged into each prop | ||
// Imports resolve according to the Node.js module resolution algorithm: | ||
// Imports resolve according to the Node.js module resolution algorithm: | ||
// https://nodejs.org/api/modules.html#modules_all_together | ||
"imports": [ | ||
imports: [ | ||
// Absolute file path | ||
@@ -533,0 +543,0 @@ "/home/me/file.json", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
72597
1431
535