tailwindcss-export-config
Advanced tools
Comparing version 2.1.0 to 2.2.0
@@ -5,2 +5,8 @@ # Changelog | ||
### [2.2.0](https://github.com/dobromir-hristov/tailwindcss-export-config/compare/v2.1.0...v2.2.0) (2020-07-01) | ||
### Features | ||
* enable converting deeply nested maps ([046f8d5](https://github.com/dobromir-hristov/tailwindcss-export-config/commit/046f8d5)) | ||
## [2.1.0](https://github.com/dobromir-hristov/tailwindcss-export-config/compare/v2.0.2...v2.1.0) (2020-06-23) | ||
@@ -7,0 +13,0 @@ |
@@ -51,2 +51,7 @@ #!/usr/bin/env node | ||
}) | ||
.option('flatten-maps-after', { | ||
describe: 'After which level, should deeply nested maps be flattened out. Defaults to -1 (always)', | ||
type: 'number', /* array | boolean | string */ | ||
nargs: 1 | ||
}) | ||
.argv | ||
@@ -61,3 +66,4 @@ | ||
flat: argv.flat, | ||
quotedKeys: argv['quoted-keys'] | ||
quotedKeys: argv['quoted-keys'], | ||
flattenMapsAfter: argv['flatten-maps-after'] | ||
}) | ||
@@ -64,0 +70,0 @@ converter.writeToFile() |
@@ -7,3 +7,2 @@ 'use strict'; | ||
var path = _interopDefault(require('path')); | ||
var reduce = _interopDefault(require('lodash.reduce')); | ||
var TWResolveConfig = _interopDefault(require('tailwindcss/resolveConfig')); | ||
@@ -29,2 +28,9 @@ | ||
} | ||
/** | ||
* Resolves a config. | ||
* If passed a string, imports it first. | ||
* @param {String | Object} config | ||
* @return {Object} | ||
*/ | ||
function resolveConfig(config) { | ||
@@ -41,2 +47,3 @@ if (typeof config === 'string') { | ||
const INDENT_BY = 2; | ||
/** | ||
@@ -51,3 +58,3 @@ * General converter class. To be extended by any specific format converter. | ||
/** @type {object} - tailwind configurations */ | ||
/** @type {object} - tailwind specific configurations */ | ||
@@ -60,2 +67,4 @@ /** @type {string} - the symbol that starts a map */ | ||
/** @type {number} - should try to flatten deep maps after N level */ | ||
/** | ||
@@ -67,2 +76,3 @@ * @param opts | ||
* @param {Boolean} [opts.quotedKeys] - Should map keys be quoted | ||
* @param {Number} [opts.flattenMapsAfter] - Should flatten maps after N level | ||
*/ | ||
@@ -82,2 +92,4 @@ constructor(opts) { | ||
_defineProperty(this, "flattenMapsAfter", -1); | ||
const { | ||
@@ -91,3 +103,4 @@ theme, | ||
this.prefix = opts.prefix || ''; | ||
this.quotedKeys = opts.quotedKeys || false; | ||
if (opts.quotedKeys) this.quotedKeys = opts.quotedKeys; | ||
if (typeof opts.flattenMapsAfter !== 'undefined') this.flattenMapsAfter = opts.flattenMapsAfter; | ||
} | ||
@@ -112,12 +125,12 @@ /** | ||
_convertObjectToVar(prop, data) { | ||
return reduce(data, (all, value, metric) => { | ||
if (isObject(value)) { | ||
return all + Object.entries(value).map(([propKey, propValue]) => { | ||
return this._buildVar(this._propertyNameSanitizer(prop, `${metric}-${propKey}`), this._sanitizePropValue(propValue)); | ||
}).join(''); | ||
} else { | ||
return all + this._buildVar(this._propertyNameSanitizer(prop, metric), this._sanitizePropValue(value)); | ||
} | ||
}, ''); | ||
return this._walkFlatRecursively(data, prop).join(''); | ||
} | ||
_walkFlatRecursively(value, parentPropertyName) { | ||
return Object.entries(value).reduce((all, [propertyName, propertyValue]) => { | ||
const property = [parentPropertyName, propertyName].filter(Boolean).join('-'); | ||
const val = isObject(propertyValue) ? this._walkFlatRecursively(propertyValue, property) : this._buildVar(this._propertyNameSanitizer(property), this._sanitizePropValue(propertyValue)); | ||
return all.concat(val); | ||
}, []); | ||
} | ||
/** | ||
@@ -147,3 +160,3 @@ * Converts the supplied data to a list of nested map objects | ||
return [`${this.mapOpener}`, // loop over each element | ||
...Object.entries(data).map(([metric, value], index) => { | ||
...Object.entries(data).filter(([metric]) => !!metric).map(([metric, value], index) => { | ||
return this._buildMapData(metric, value, indent, index); | ||
@@ -168,9 +181,21 @@ }), // close map | ||
return this._buildObjectEntry(metric, value, indent, metricIndex); | ||
} | ||
const nestLevel = indent / INDENT_BY; // should deeply nested maps be flattened out, or resolved deeply | ||
if (nestLevel <= this.flattenMapsAfter) { | ||
return this._buildObjectEntry(metric, this._buildMap(value, indent + INDENT_BY), indent, metricIndex); | ||
} // its an object so we need to flatten it out | ||
return Object.entries(value).map(([propertyName, propertyValue], index) => { | ||
return this._buildObjectEntry(`${metric}-${propertyName}`, propertyValue, indent, index, metricIndex); | ||
}).join(''); | ||
return this._walkRecursively(value, metric, indent, metricIndex).join(''); | ||
} | ||
_walkRecursively(value, parentPropertyName, indent, metricIndex) { | ||
return Object.entries(value).reduce((all, [propertyName, propertyValue], index) => { | ||
const property = [parentPropertyName, propertyName].filter(Boolean).join('-'); | ||
const val = isObject(propertyValue) ? this._walkRecursively(propertyValue, property, indent, metricIndex) : this._buildObjectEntry(property, propertyValue, indent, index, metricIndex); | ||
return all.concat(val); | ||
}, []); | ||
} | ||
/** | ||
@@ -189,3 +214,3 @@ * Creates a single map entry | ||
_buildObjectEntry(key, value, indent, index = 0, metricIndex) { | ||
return indentWith(`${this._objectEntryKeySanitizer(key)}: ${this._sanitizePropValue(value)},\n`, indent + 2); | ||
return indentWith(`${this._objectEntryKeySanitizer(key)}: ${this._sanitizePropValue(value)},\n`, indent + INDENT_BY); | ||
} | ||
@@ -238,3 +263,6 @@ /** | ||
if (Array.isArray(value)) return `(${value})`.replace(/\\"/g, '"'); | ||
if (typeof value === 'string' && value.includes(',')) return `(${value})`; | ||
if ( // if its a string | ||
typeof value === 'string' // and has comma's in it | ||
&& value.includes(',') // but is not a concatenated map | ||
&& !value.startsWith(this.mapOpener)) return `(${value})`; | ||
return value; | ||
@@ -246,3 +274,2 @@ } | ||
* @param {string} property - the property (colors, backgroundColors) | ||
* @param {string} [metric] - the property's metric (purple, red, 1/4, 24 etc..) | ||
* @return {string} | ||
@@ -253,8 +280,5 @@ * @private | ||
_propertyNameSanitizer(property, metric = '') { | ||
if (metric) { | ||
metric = metric.replace('/', '\\/'); | ||
} | ||
return [this.prefix, property, metric].filter(v => v).join('-'); | ||
_propertyNameSanitizer(property) { | ||
property = property.replace('/', '\\/'); | ||
return [this.prefix, property].filter(v => v).join('-'); | ||
} | ||
@@ -385,6 +409,7 @@ /** | ||
* @param {String} [options.prefix] - Variable prefix | ||
* @param {String} options.destination - Output destination | ||
* @param {String} [options.destination] - Output destination | ||
* @param {Boolean} [options.flat] - Whether the variables should be nested maps or flat level variables | ||
* @param {String} options.format - The desired format | ||
* @param {Boolean} options.quotedSassKeys - Whether SASS keys should be quoted. Both for Sass and SCSS. | ||
* @param {Boolean} [options.quotedKeys] - Whether SASS keys should be quoted. Both for Sass and SCSS. | ||
* @param {Number} [options.flattenMapsAfter] - After what nest level, do we want to flatten out nested maps. | ||
*/ | ||
@@ -391,0 +416,0 @@ constructor(options) { |
{ | ||
"name": "tailwindcss-export-config", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "Export Tailwindcss config options to SASS, SCSS, LESS and Stylus", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -78,2 +78,3 @@ <p align="center"> | ||
quoted-keys|Boolean|false| (`quotedKeys` in the Node API) - Whether keys in maps should be quoted or not. We recommend to have this set to `true`. Defaults to `false`. | ||
flatten-maps-after|Number|false| (`flattenMapsAfter` in the Node API) - After what level should it start flattening deeply nested maps. Defaults to `-1` (always flatten). | ||
@@ -239,2 +240,59 @@ ## Example export | ||
### Flattening deep maps | ||
If your tailwind config has a deeply nested object, it can be converted to a deeply nested map, in SASS or Stylus, or a flattened, single level map. | ||
Given the object below: | ||
```js | ||
module.exports = { | ||
theme: { | ||
customForms: { | ||
colors: { | ||
blue: 'blue', | ||
green: 'green', | ||
}, | ||
somethingElse: { | ||
level1: { | ||
color: 'pink', | ||
arrayValue: ['a', 'b', 'c'], | ||
} | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
By default it will convert to: | ||
```scss | ||
$customForms: ( | ||
colors-blue: blue, | ||
colors-green: green, | ||
somethingElse-level1-color: pink, | ||
somethingElse-level1-arrayValue: (a,b,c), | ||
); | ||
``` | ||
If we want to keep the nested structure, similar to the tailwind config, we can set a high number for the `flattenMapsAfter` parameter. | ||
```bash | ||
tailwindcss-export-config --config=tailwind.config.js --destination=tailwind-variables --format=scss --flatten-maps-after=10 | ||
``` | ||
```scss | ||
$customForms: ( | ||
colors: ( | ||
blue: blue, | ||
green: green, | ||
), | ||
somethingElse: ( | ||
level1: ( | ||
color: pink, | ||
arrayValue: (a,b,c), | ||
), | ||
), | ||
); | ||
``` | ||
## Notice | ||
@@ -241,0 +299,0 @@ |
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
26950
444
303