Skip to content

Commit ddafafe

Browse files
Merge pull request #1030 from amzn/v3-fixes-port
V3 fixes port
2 parents dab4161 + c1dd5ec commit ddafafe

File tree

5 files changed

+434
-87
lines changed

5 files changed

+434
-87
lines changed

.changeset/bright-timers-shout.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'style-dictionary': patch
3+
---
4+
5+
Allow overriding CSS formatting with commentStyle and commentPosition props.
6+
For commentStyle, options are 'short' or 'long'.
7+
For commentPosition, options are 'above' or 'inline'.
8+
9+
We also ensure that the right defaults are picked for CSS, SASS/SCSS, Stylus and Less.
10+
11+
This also contains a fix for ensuring that multi-line comments are automatically put "above" rather than "inline".

.changeset/nice-ears-shop.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'style-dictionary': patch
3+
---
4+
5+
Allow outputReferences to work on non-string values.

__tests__/common/formatHelpers/createPropertyFormatter.test.js

+300-26
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ const dictionary = createDictionary({
3030
value: '5px',
3131
type: 'spacing',
3232
},
33-
bar: {
33+
ref: {
3434
original: {
3535
value: '{tokens.foo}',
3636
type: 'spacing',
3737
},
3838
attributes: {
3939
category: 'tokens',
40-
type: 'bar',
40+
type: 'ref',
4141
},
42-
name: 'tokens-bar',
43-
path: ['tokens', 'bar'],
42+
name: 'tokens-ref',
43+
path: ['tokens', 'ref'],
4444
value: '5px',
4545
type: 'spacing',
4646
},
@@ -65,9 +65,79 @@ const transformedDictionary = createDictionary({
6565
value: '5px',
6666
type: 'spacing',
6767
},
68-
bar: {
68+
ref: {
69+
original: {
70+
value: '{tokens.foo}',
71+
type: 'spacing',
72+
},
73+
attributes: {
74+
category: 'tokens',
75+
type: 'ref',
76+
},
77+
name: 'tokens-ref',
78+
path: ['tokens', 'ref'],
79+
value: 'changed by transitive transform',
80+
type: 'spacing',
81+
},
82+
},
83+
},
84+
});
85+
86+
const numberDictionary = createDictionary({
87+
properties: {
88+
tokens: {
89+
foo: {
90+
original: {
91+
value: 10,
92+
type: 'dimension',
93+
},
94+
attributes: {
95+
category: 'tokens',
96+
type: 'foo',
97+
},
98+
name: 'tokens-foo',
99+
path: ['tokens', 'foo'],
100+
value: 10,
101+
type: 'dimension',
102+
},
103+
ref: {
69104
original: {
70105
value: '{tokens.foo}',
106+
type: 'dimension',
107+
},
108+
attributes: {
109+
category: 'tokens',
110+
type: 'ref',
111+
},
112+
name: 'tokens-ref',
113+
path: ['tokens', 'ref'],
114+
value: 10,
115+
type: 'dimension',
116+
},
117+
},
118+
},
119+
});
120+
121+
const multiDictionary = createDictionary({
122+
properties: {
123+
tokens: {
124+
foo: {
125+
original: {
126+
value: '10px',
127+
type: 'spacing',
128+
},
129+
attributes: {
130+
category: 'tokens',
131+
type: 'foo',
132+
},
133+
name: 'tokens-foo',
134+
path: ['tokens', 'foo'],
135+
value: '10px',
136+
type: 'spacing',
137+
},
138+
bar: {
139+
original: {
140+
value: '15px',
71141
type: 'spacing',
72142
},
73143
attributes: {
@@ -76,40 +146,244 @@ const transformedDictionary = createDictionary({
76146
},
77147
name: 'tokens-bar',
78148
path: ['tokens', 'bar'],
79-
value: 'changed by transitive transform',
149+
value: '15px',
150+
type: 'spacing',
151+
},
152+
ref: {
153+
original: {
154+
value: '{tokens.foo} 5px {tokens.bar}',
155+
type: 'spacing',
156+
},
157+
attributes: {
158+
category: 'tokens',
159+
type: 'ref',
160+
},
161+
name: 'tokens-ref',
162+
path: ['tokens', 'ref'],
163+
value: '10px 5px 15px',
80164
type: 'spacing',
81165
},
82166
},
83167
},
84168
});
85169

170+
const objectDictionary = createDictionary({
171+
properties: {
172+
tokens: {
173+
foo: {
174+
original: {
175+
value: '5px',
176+
type: 'spacing',
177+
},
178+
attributes: {
179+
category: 'tokens',
180+
type: 'foo',
181+
},
182+
name: 'tokens-foo',
183+
path: ['tokens', 'foo'],
184+
value: '5px',
185+
type: 'spacing',
186+
},
187+
ref: {
188+
original: {
189+
value: {
190+
width: '{tokens.foo}',
191+
style: 'dashed',
192+
color: '#FF00FF',
193+
},
194+
type: 'border',
195+
},
196+
attributes: {
197+
category: 'tokens',
198+
type: 'ref',
199+
},
200+
name: 'tokens-ref',
201+
path: ['tokens', 'ref'],
202+
value: '5px dashed #FF00FF',
203+
type: 'border',
204+
},
205+
},
206+
},
207+
});
208+
86209
describe('common', () => {
87210
describe('formatHelpers', () => {
88211
describe('createPropertyFormatter', () => {
89-
it('should support outputReferences', () => {
90-
const propFormatter = createPropertyFormatter({
91-
outputReferences: true,
92-
dictionary,
93-
format: 'css',
212+
describe('outputReferences', () => {
213+
it('should support outputReferences', () => {
214+
const propFormatter = createPropertyFormatter({
215+
outputReferences: true,
216+
dictionary,
217+
format: 'css',
218+
});
219+
expect(propFormatter(dictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 5px;');
220+
expect(propFormatter(dictionary.tokens.tokens.ref)).toEqual(
221+
' --tokens-ref: var(--tokens-foo);',
222+
);
223+
});
224+
225+
it('should support outputReferences when values are transformed by (transitive) "value" transforms', () => {
226+
const propFormatter = createPropertyFormatter({
227+
outputReferences: true,
228+
dictionary: transformedDictionary,
229+
format: 'css',
230+
});
231+
expect(propFormatter(transformedDictionary.tokens.tokens.foo)).toEqual(
232+
' --tokens-foo: 5px;',
233+
);
234+
expect(propFormatter(transformedDictionary.tokens.tokens.ref)).toEqual(
235+
' --tokens-ref: var(--tokens-foo);',
236+
);
237+
});
238+
239+
it('should support number values for outputReferences', () => {
240+
const propFormatter = createPropertyFormatter({
241+
outputReferences: true,
242+
dictionary: numberDictionary,
243+
format: 'css',
244+
});
245+
expect(propFormatter(numberDictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 10;');
246+
expect(propFormatter(numberDictionary.tokens.tokens.ref)).toEqual(
247+
' --tokens-ref: var(--tokens-foo);',
248+
);
249+
});
250+
251+
it('should support multiple references for outputReferences', () => {
252+
const propFormatter = createPropertyFormatter({
253+
outputReferences: true,
254+
dictionary: multiDictionary,
255+
format: 'css',
256+
});
257+
expect(propFormatter(multiDictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 10px;');
258+
expect(propFormatter(multiDictionary.tokens.tokens.bar)).toEqual(' --tokens-bar: 15px;');
259+
expect(propFormatter(multiDictionary.tokens.tokens.ref)).toEqual(
260+
' --tokens-ref: var(--tokens-foo) 5px var(--tokens-bar);',
261+
);
262+
});
263+
264+
it('should support object value references for outputReferences', () => {
265+
// The ref is an object type value, which means there will usually be some kind of transform (e.g. a CSS shorthand transform)
266+
// to change it from an object to a string. In our example, we use a border CSS shorthand for border token.
267+
// In this case, since it is an object value, we will run the transformation on the transformed (string) value.
268+
const propFormatter = createPropertyFormatter({
269+
outputReferences: true,
270+
dictionary: objectDictionary,
271+
format: 'css',
272+
});
273+
expect(propFormatter(objectDictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 5px;');
274+
expect(propFormatter(objectDictionary.tokens.tokens.ref)).toEqual(
275+
' --tokens-ref: var(--tokens-foo) dashed #FF00FF;',
276+
);
94277
});
95-
expect(propFormatter(dictionary.tokens.tokens.foo)).toEqual(' --tokens-foo: 5px;');
96-
expect(propFormatter(dictionary.tokens.tokens.bar)).toEqual(
97-
' --tokens-bar: var(--tokens-foo);',
98-
);
99278
});
100279

101-
it('should support outputReferences when values are transformed by (transitive) "value" transforms', () => {
102-
const propFormatter = createPropertyFormatter({
103-
outputReferences: true,
104-
dictionary,
105-
format: 'css',
280+
describe('commentStyle', () => {
281+
const commentProperties = {
282+
color: {
283+
red: {
284+
name: 'color-red',
285+
value: '#FF0000',
286+
comment: 'Foo bar qux',
287+
attributes: {
288+
category: 'color',
289+
type: 'red',
290+
},
291+
path: ['color', 'red'],
292+
},
293+
blue: {
294+
name: 'color-blue',
295+
value: '#0000FF',
296+
comment: 'Foo\nbar\nqux',
297+
attributes: {
298+
category: 'color',
299+
type: 'blue',
300+
},
301+
path: ['color', 'blue'],
302+
},
303+
green: {
304+
name: 'color-green',
305+
value: '#00FF00',
306+
comment: 'Foo bar qux',
307+
attributes: {
308+
category: 'color',
309+
type: 'green',
310+
},
311+
path: ['color', 'green'],
312+
},
313+
},
314+
};
315+
316+
const commentDictionary = createDictionary({
317+
properties: commentProperties,
318+
});
319+
320+
it('should default to putting comment next to the output value', () => {
321+
// long commentStyle
322+
const cssFormatter = createPropertyFormatter({
323+
format: 'css',
324+
commentDictionary,
325+
});
326+
// short commentStyle
327+
const sassFormatter = createPropertyFormatter({
328+
format: 'sass',
329+
commentDictionary,
330+
});
331+
332+
// red = single-line comment, blue = multi-line comment
333+
const cssRed = cssFormatter(commentDictionary.tokens.color.red);
334+
const cssBlue = cssFormatter(commentDictionary.tokens.color.blue);
335+
const sassRed = sassFormatter(commentDictionary.tokens.color.red);
336+
const sassBlue = sassFormatter(commentDictionary.tokens.color.blue);
337+
338+
// Note that since CSS puts it inside a selector, there is an indentation of 2 spaces as well
339+
// CSS also has commentStyle long, whereas sass uses short
340+
expect(cssRed).toMatchInlineSnapshot(`" --color-red: #FF0000; /* Foo bar qux */"`);
341+
342+
expect(cssBlue).toMatchInlineSnapshot(`
343+
" /**
344+
* Foo
345+
* bar
346+
* qux
347+
*/
348+
--color-blue: #0000FF;"
349+
`);
350+
351+
expect(sassRed).toMatchInlineSnapshot(`"$color-red: #FF0000; // Foo bar qux"`);
352+
expect(sassBlue).toMatchInlineSnapshot(`
353+
"// Foo
354+
// bar
355+
// qux
356+
$color-blue: #0000FF;"
357+
`);
358+
});
359+
360+
it('allows overriding formatting commentStyle', () => {
361+
// long commentStyle
362+
const cssFormatter = createPropertyFormatter({
363+
format: 'css',
364+
commentDictionary,
365+
formatting: { commentStyle: 'long', commentPosition: 'above' },
366+
});
367+
// short commentStyle
368+
const sassFormatter = createPropertyFormatter({
369+
format: 'sass',
370+
commentDictionary,
371+
formatting: { commentStyle: 'short', commentPosition: 'above' },
372+
});
373+
374+
const cssRed = cssFormatter(commentDictionary.tokens.color.green);
375+
const sassRed = sassFormatter(commentDictionary.tokens.color.green);
376+
377+
expect(cssRed).toMatchInlineSnapshot(`
378+
" /* Foo bar qux */
379+
--color-green: #00FF00;"
380+
`);
381+
382+
expect(sassRed).toMatchInlineSnapshot(`
383+
"// Foo bar qux
384+
$color-green: #00FF00;"
385+
`);
106386
});
107-
expect(propFormatter(transformedDictionary.tokens.tokens.foo)).toEqual(
108-
' --tokens-foo: 5px;',
109-
);
110-
expect(propFormatter(transformedDictionary.tokens.tokens.bar)).toEqual(
111-
' --tokens-bar: var(--tokens-foo);',
112-
);
113387
});
114388
});
115389
});

0 commit comments

Comments
 (0)