Skip to content

Commit

Permalink
Merge pull request #1030 from amzn/v3-fixes-port
Browse files Browse the repository at this point in the history
V3 fixes port
  • Loading branch information
jorenbroekema authored Oct 24, 2023
2 parents dab4161 + c1dd5ec commit ddafafe
Show file tree
Hide file tree
Showing 5 changed files with 434 additions and 87 deletions.
11 changes: 11 additions & 0 deletions .changeset/bright-timers-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'style-dictionary': patch
---

Allow overriding CSS formatting with commentStyle and commentPosition props.
For commentStyle, options are 'short' or 'long'.
For commentPosition, options are 'above' or 'inline'.

We also ensure that the right defaults are picked for CSS, SASS/SCSS, Stylus and Less.

This also contains a fix for ensuring that multi-line comments are automatically put "above" rather than "inline".
5 changes: 5 additions & 0 deletions .changeset/nice-ears-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'style-dictionary': patch
---

Allow outputReferences to work on non-string values.
326 changes: 300 additions & 26 deletions __tests__/common/formatHelpers/createPropertyFormatter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ const dictionary = createDictionary({
value: '5px',
type: 'spacing',
},
bar: {
ref: {
original: {
value: '{tokens.foo}',
type: 'spacing',
},
attributes: {
category: 'tokens',
type: 'bar',
type: 'ref',
},
name: 'tokens-bar',
path: ['tokens', 'bar'],
name: 'tokens-ref',
path: ['tokens', 'ref'],
value: '5px',
type: 'spacing',
},
Expand All @@ -65,9 +65,79 @@ const transformedDictionary = createDictionary({
value: '5px',
type: 'spacing',
},
bar: {
ref: {
original: {
value: '{tokens.foo}',
type: 'spacing',
},
attributes: {
category: 'tokens',
type: 'ref',
},
name: 'tokens-ref',
path: ['tokens', 'ref'],
value: 'changed by transitive transform',
type: 'spacing',
},
},
},
});

const numberDictionary = createDictionary({
properties: {
tokens: {
foo: {
original: {
value: 10,
type: 'dimension',
},
attributes: {
category: 'tokens',
type: 'foo',
},
name: 'tokens-foo',
path: ['tokens', 'foo'],
value: 10,
type: 'dimension',
},
ref: {
original: {
value: '{tokens.foo}',
type: 'dimension',
},
attributes: {
category: 'tokens',
type: 'ref',
},
name: 'tokens-ref',
path: ['tokens', 'ref'],
value: 10,
type: 'dimension',
},
},
},
});

const multiDictionary = createDictionary({
properties: {
tokens: {
foo: {
original: {
value: '10px',
type: 'spacing',
},
attributes: {
category: 'tokens',
type: 'foo',
},
name: 'tokens-foo',
path: ['tokens', 'foo'],
value: '10px',
type: 'spacing',
},
bar: {
original: {
value: '15px',
type: 'spacing',
},
attributes: {
Expand All @@ -76,40 +146,244 @@ const transformedDictionary = createDictionary({
},
name: 'tokens-bar',
path: ['tokens', 'bar'],
value: 'changed by transitive transform',
value: '15px',
type: 'spacing',
},
ref: {
original: {
value: '{tokens.foo} 5px {tokens.bar}',
type: 'spacing',
},
attributes: {
category: 'tokens',
type: 'ref',
},
name: 'tokens-ref',
path: ['tokens', 'ref'],
value: '10px 5px 15px',
type: 'spacing',
},
},
},
});

const objectDictionary = createDictionary({
properties: {
tokens: {
foo: {
original: {
value: '5px',
type: 'spacing',
},
attributes: {
category: 'tokens',
type: 'foo',
},
name: 'tokens-foo',
path: ['tokens', 'foo'],
value: '5px',
type: 'spacing',
},
ref: {
original: {
value: {
width: '{tokens.foo}',
style: 'dashed',
color: '#FF00FF',
},
type: 'border',
},
attributes: {
category: 'tokens',
type: 'ref',
},
name: 'tokens-ref',
path: ['tokens', 'ref'],
value: '5px dashed #FF00FF',
type: 'border',
},
},
},
});

describe('common', () => {
describe('formatHelpers', () => {
describe('createPropertyFormatter', () => {
it('should support outputReferences', () => {
const propFormatter = createPropertyFormatter({
outputReferences: true,
dictionary,
format: 'css',
describe('outputReferences', () => {
it('should support outputReferences', () => {
const propFormatter = createPropertyFormatter({
outputReferences: true,
dictionary,
format: 'css',
});
expect(propFormatter(dictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 5px;');
expect(propFormatter(dictionary.tokens.tokens.ref)).toEqual(
' --tokens-ref: var(--tokens-foo);',
);
});

it('should support outputReferences when values are transformed by (transitive) "value" transforms', () => {
const propFormatter = createPropertyFormatter({
outputReferences: true,
dictionary: transformedDictionary,
format: 'css',
});
expect(propFormatter(transformedDictionary.tokens.tokens.foo)).toEqual(
' --tokens-foo: 5px;',
);
expect(propFormatter(transformedDictionary.tokens.tokens.ref)).toEqual(
' --tokens-ref: var(--tokens-foo);',
);
});

it('should support number values for outputReferences', () => {
const propFormatter = createPropertyFormatter({
outputReferences: true,
dictionary: numberDictionary,
format: 'css',
});
expect(propFormatter(numberDictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 10;');
expect(propFormatter(numberDictionary.tokens.tokens.ref)).toEqual(
' --tokens-ref: var(--tokens-foo);',
);
});

it('should support multiple references for outputReferences', () => {
const propFormatter = createPropertyFormatter({
outputReferences: true,
dictionary: multiDictionary,
format: 'css',
});
expect(propFormatter(multiDictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 10px;');
expect(propFormatter(multiDictionary.tokens.tokens.bar)).toEqual(' --tokens-bar: 15px;');
expect(propFormatter(multiDictionary.tokens.tokens.ref)).toEqual(
' --tokens-ref: var(--tokens-foo) 5px var(--tokens-bar);',
);
});

it('should support object value references for outputReferences', () => {
// The ref is an object type value, which means there will usually be some kind of transform (e.g. a CSS shorthand transform)
// to change it from an object to a string. In our example, we use a border CSS shorthand for border token.
// In this case, since it is an object value, we will run the transformation on the transformed (string) value.
const propFormatter = createPropertyFormatter({
outputReferences: true,
dictionary: objectDictionary,
format: 'css',
});
expect(propFormatter(objectDictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 5px;');
expect(propFormatter(objectDictionary.tokens.tokens.ref)).toEqual(
' --tokens-ref: var(--tokens-foo) dashed #FF00FF;',
);
});
expect(propFormatter(dictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 5px;');
expect(propFormatter(dictionary.tokens.tokens.bar)).toEqual(
' --tokens-bar: var(--tokens-foo);',
);
});

it('should support outputReferences when values are transformed by (transitive) "value" transforms', () => {
const propFormatter = createPropertyFormatter({
outputReferences: true,
dictionary,
format: 'css',
describe('commentStyle', () => {
const commentProperties = {
color: {
red: {
name: 'color-red',
value: '#FF0000',
comment: 'Foo bar qux',
attributes: {
category: 'color',
type: 'red',
},
path: ['color', 'red'],
},
blue: {
name: 'color-blue',
value: '#0000FF',
comment: 'Foo\nbar\nqux',
attributes: {
category: 'color',
type: 'blue',
},
path: ['color', 'blue'],
},
green: {
name: 'color-green',
value: '#00FF00',
comment: 'Foo bar qux',
attributes: {
category: 'color',
type: 'green',
},
path: ['color', 'green'],
},
},
};

const commentDictionary = createDictionary({
properties: commentProperties,
});

it('should default to putting comment next to the output value', () => {
// long commentStyle
const cssFormatter = createPropertyFormatter({
format: 'css',
commentDictionary,
});
// short commentStyle
const sassFormatter = createPropertyFormatter({
format: 'sass',
commentDictionary,
});

// red = single-line comment, blue = multi-line comment
const cssRed = cssFormatter(commentDictionary.tokens.color.red);
const cssBlue = cssFormatter(commentDictionary.tokens.color.blue);
const sassRed = sassFormatter(commentDictionary.tokens.color.red);
const sassBlue = sassFormatter(commentDictionary.tokens.color.blue);

// Note that since CSS puts it inside a selector, there is an indentation of 2 spaces as well
// CSS also has commentStyle long, whereas sass uses short
expect(cssRed).toMatchInlineSnapshot(`" --color-red: #FF0000; /* Foo bar qux */"`);

expect(cssBlue).toMatchInlineSnapshot(`
" /**
* Foo
* bar
* qux
*/
--color-blue: #0000FF;"
`);

expect(sassRed).toMatchInlineSnapshot(`"$color-red: #FF0000; // Foo bar qux"`);
expect(sassBlue).toMatchInlineSnapshot(`
"// Foo
// bar
// qux
$color-blue: #0000FF;"
`);
});

it('allows overriding formatting commentStyle', () => {
// long commentStyle
const cssFormatter = createPropertyFormatter({
format: 'css',
commentDictionary,
formatting: { commentStyle: 'long', commentPosition: 'above' },
});
// short commentStyle
const sassFormatter = createPropertyFormatter({
format: 'sass',
commentDictionary,
formatting: { commentStyle: 'short', commentPosition: 'above' },
});

const cssRed = cssFormatter(commentDictionary.tokens.color.green);
const sassRed = sassFormatter(commentDictionary.tokens.color.green);

expect(cssRed).toMatchInlineSnapshot(`
" /* Foo bar qux */
--color-green: #00FF00;"
`);

expect(sassRed).toMatchInlineSnapshot(`
"// Foo bar qux
$color-green: #00FF00;"
`);
});
expect(propFormatter(transformedDictionary.tokens.tokens.foo)).toEqual(
' --tokens-foo: 5px;',
);
expect(propFormatter(transformedDictionary.tokens.tokens.bar)).toEqual(
' --tokens-bar: var(--tokens-foo);',
);
});
});
});
Expand Down
Loading

0 comments on commit ddafafe

Please sign in to comment.