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

feat: allow transforms to be added on top of transformGroup #1120

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/pink-mangos-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'style-dictionary': patch
---

Allow transformGroup to be combined with transforms, where standalone transforms will be added after the group's transforms.
42 changes: 42 additions & 0 deletions __tests__/transform/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,47 @@ None of "barTransform", "bazTransform" match the name of a registered transform.

expect(transformConfig.bind(null, noTransformCfg, dictionary, 'test')).to.throw(err);
});

it('allows combining transformGroup with transforms', () => {
const cfg = {
transformGroup: {
foobarTransformGroup: ['fooTransform', 'barTransform'],
},
transform: {
fooTransform: {
name: 'fooTransform',
type: 'attribute',
transformer: function () {
return { foo: 'foo' };
},
},
barTransform: {
name: 'barTransform',
type: 'attribute',
transformer: function () {
return { bar: 'bar' };
},
},
quxTransform: {
name: 'quxTransform',
type: 'attribute',
transformer: function () {
return { qux: 'qux' };
},
},
},
};

const platformCfg = {
transformGroup: 'foobarTransformGroup',
transforms: ['quxTransform'],
};
const transformedCfg = transformConfig(platformCfg, cfg, 'test');
expect(transformedCfg.transforms.map((t) => t.name)).to.eql([
'fooTransform',
'barTransform',
'quxTransform',
]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* and limitations under the License.
*/
import { expect } from 'chai';
import token from '../../lib/transform/token.js';
import transformToken from '../../lib/transform/token.js';

const config = {
transforms: [
Expand Down Expand Up @@ -44,14 +44,14 @@ const config = {
describe('transform', () => {
describe('token', () => {
it('transform token and apply transforms', async () => {
const test = await token({ attributes: { baz: 'blah' } }, config, {});
const test = await transformToken({ attributes: { baz: 'blah' } }, config, {});
expect(test).to.have.nested.property('attributes.bar', 'foo');
expect(test).to.have.property('name', 'hello');
});

// This allows transformObject utility to then consider this token's transformation undefined and thus "deferred"
it('returns a token as undefined if transitive transformer dictates that the transformation has to be deferred', async () => {
const result = await token(
const result = await transformToken(
{
value: '16',
original: {
Expand Down
19 changes: 19 additions & 0 deletions docs/transform_groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ You use transformGroups in your config file under platforms > [platform] > trans
}
```

## Combining with transforms

You can also combine transforms with transformGroup:

```json
{
"source": ["tokens/**/*.json"],
"platforms": {
"android": {
"transformGroup": "android",
"transforms": ["name/cti/snake"]
}
}
}
```

The transforms that are standalone will be added **after** the ones inside the transformGroup.
If it's important to determine the order of these yourself, you can always register a custom transformGroup to have more granular control.

---

## Pre-defined Transform groups
Expand Down
12 changes: 7 additions & 5 deletions lib/transform/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,14 @@ export default function transformConfig(platformConfig, dictionary, platformName
const to_ret = { ...platformConfig }; // structuredClone not suitable due to config being able to contain Function() etc.
to_ret.log = platformConfig.log ?? dictionary.log;

// The platform can define either a transformGroup or an array
// The platform can both a transformGroup or an array
// of transforms. If given a transformGroup that doesn't exist,
// it will throw an error to make the user aware that the transformGroup doesn't
// exist. A valid case is if the user defines neither, no transforms will be
// applied.
/** @type {string[]} */
let transforms = [];
if (to_ret.transforms) {
// typecast because at this point, transforms are still strings without functions
transforms = /** @type {string[]} */ (to_ret.transforms);
} else if (to_ret.transformGroup) {
if (to_ret.transformGroup) {
if (dictionary.transformGroup[to_ret.transformGroup]) {
transforms = dictionary.transformGroup[to_ret.transformGroup];
} else {
Expand All @@ -61,6 +58,11 @@ Unknown transformGroup "${to_ret.transformGroup}" found in platform "${platformN
}
}

if (to_ret.transforms) {
// typecast because at this point, transforms are still strings without functions
transforms = transforms.concat(/** @type {string[]} */ (to_ret.transforms));
}

// Transforms are an array of strings that map to functions on
// the StyleDictionary module. We need to map the strings to
// the actual functions.
Expand Down
Loading