@stylexjs/babel-plugin 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,440 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ jest.autoMockOff();
11
+
12
+ const { transformSync } = require('@babel/core');
13
+ const stylexPlugin = require('../src/index');
14
+
15
+ function transform(source, opts = {}) {
16
+ return transformSync(source, {
17
+ filename: opts.filename,
18
+ parserOpts: {
19
+ flow: {
20
+ all: true,
21
+ },
22
+ },
23
+ plugins: [[stylexPlugin, opts]],
24
+ }).code;
25
+ }
26
+
27
+ describe('@stylexjs/babel-plugin', () => {
28
+ /**
29
+ * CSS logical values transform
30
+ */
31
+
32
+ describe('[transform] CSS logical values', () => {
33
+ // TODO: Add support for 'background-position-x: x-start' logical values
34
+ // once spec stabilizes.
35
+ // https://drafts.csswg.org/css-backgrounds-4/#the-background-position
36
+
37
+ test('value "inline-end" for "clear" property', () => {
38
+ expect(
39
+ transform(`
40
+ import stylex from 'stylex';
41
+ const styles = stylex.create({ x: { clear: 'inline-end' } });
42
+ const classnames = stylex(styles.x);
43
+ `)
44
+ ).toMatchInlineSnapshot(`
45
+ "import stylex from 'stylex';
46
+ stylex.inject(".xof8tvn{clear:inline-end}", 1);
47
+ const classnames = "xof8tvn";"
48
+ `);
49
+ });
50
+
51
+ test('value "inline-start" for "clear" property', () => {
52
+ expect(
53
+ transform(`
54
+ import stylex from 'stylex';
55
+ const styles = stylex.create({ x: { clear: 'inline-start' } });
56
+ const classnames = stylex(styles.x);
57
+ `)
58
+ ).toMatchInlineSnapshot(`
59
+ "import stylex from 'stylex';
60
+ stylex.inject(".x18lmvvi{clear:inline-start}", 1);
61
+ const classnames = "x18lmvvi";"
62
+ `);
63
+ });
64
+
65
+ test('value "inline-end" for "float" property', () => {
66
+ expect(
67
+ transform(`
68
+ import stylex from 'stylex';
69
+ const styles = stylex.create({ x: { float: 'inline-end' } });
70
+ const classnames = stylex(styles.x);
71
+ `)
72
+ ).toMatchInlineSnapshot(`
73
+ "import stylex from 'stylex';
74
+ stylex.inject(".x1h0q493{float:inline-end}", 1);
75
+ const classnames = "x1h0q493";"
76
+ `);
77
+ });
78
+
79
+ test('value "inline-start" for "float" property', () => {
80
+ expect(
81
+ transform(`
82
+ import stylex from 'stylex';
83
+ const styles = stylex.create({ x: { float: 'inline-start' } });
84
+ const classnames = stylex(styles.x);
85
+ `)
86
+ ).toMatchInlineSnapshot(`
87
+ "import stylex from 'stylex';
88
+ stylex.inject(".x1kmio9f{float:inline-start}", 1);
89
+ const classnames = "x1kmio9f";"
90
+ `);
91
+ });
92
+
93
+ test('value "end" for "textAlign" property', () => {
94
+ expect(
95
+ transform(`
96
+ import stylex from 'stylex';
97
+ const styles = stylex.create({ x: { textAlign: 'end' } });
98
+ const classnames = stylex(styles.x);
99
+ `)
100
+ ).toMatchInlineSnapshot(`
101
+ "import stylex from 'stylex';
102
+ stylex.inject(".xp4054r{text-align:right}", 1, ".xp4054r{text-align:left}");
103
+ const classnames = "xp4054r";"
104
+ `);
105
+ });
106
+
107
+ test('value "start" for "textAlign" property', () => {
108
+ expect(
109
+ transform(`
110
+ import stylex from 'stylex';
111
+ const styles = stylex.create({ x: { textAlign: 'start' } });
112
+ const classnames = stylex(styles.x);
113
+ `)
114
+ ).toMatchInlineSnapshot(`
115
+ "import stylex from 'stylex';
116
+ stylex.inject(".x1yc453h{text-align:left}", 1, ".x1yc453h{text-align:right}");
117
+ const classnames = "x1yc453h";"
118
+ `);
119
+ });
120
+
121
+ /**
122
+ * Non-standard values
123
+ */
124
+
125
+ test('[non-standard] value "end" (aka "inlineEnd") for "clear" property', () => {
126
+ expect(
127
+ transform(`
128
+ import stylex from 'stylex';
129
+ const styles = stylex.create({ x: { clear: 'end' } });
130
+ const classnames = stylex(styles.x);
131
+ `)
132
+ ).toMatchInlineSnapshot(`
133
+ "import stylex from 'stylex';
134
+ stylex.inject(".xodj72a{clear:right}", 1, ".xodj72a{clear:left}");
135
+ const classnames = "xodj72a";"
136
+ `);
137
+ });
138
+
139
+ test('[non-standard] value "start" (aka "inlineStart") for "clear" property', () => {
140
+ expect(
141
+ transform(`
142
+ import stylex from 'stylex';
143
+ const styles = stylex.create({ x: { clear: 'start' } });
144
+ const classnames = stylex(styles.x);
145
+ `)
146
+ ).toMatchInlineSnapshot(`
147
+ "import stylex from 'stylex';
148
+ stylex.inject(".x390i0x{clear:left}", 1, ".x390i0x{clear:right}");
149
+ const classnames = "x390i0x";"
150
+ `);
151
+ });
152
+
153
+ test('[non-standard] value "end" (aka "inlineEnd") for "float" property', () => {
154
+ expect(
155
+ transform(`
156
+ import stylex from 'stylex';
157
+ const styles = stylex.create({ x: { float: 'end' } });
158
+ const classnames = stylex(styles.x);
159
+ `)
160
+ ).toMatchInlineSnapshot(`
161
+ "import stylex from 'stylex';
162
+ stylex.inject(".x1guec7k{float:right}", 1, ".x1guec7k{float:left}");
163
+ const classnames = "x1guec7k";"
164
+ `);
165
+ });
166
+
167
+ test('[non-standard] value "start" (aka "inlineStart") for "float" property', () => {
168
+ expect(
169
+ transform(`
170
+ import stylex from 'stylex';
171
+ const styles = stylex.create({ x: { float: 'start' } });
172
+ const classnames = stylex(styles.x);
173
+ `)
174
+ ).toMatchInlineSnapshot(`
175
+ "import stylex from 'stylex';
176
+ stylex.inject(".xrbpyxo{float:left}", 1, ".xrbpyxo{float:right}");
177
+ const classnames = "xrbpyxo";"
178
+ `);
179
+ });
180
+
181
+ /**
182
+ * Non-standard bidi transforms
183
+ */
184
+
185
+ test('[legacy] value "e-resize" for "cursor" property', () => {
186
+ expect(
187
+ transform(`
188
+ import stylex from 'stylex';
189
+ const styles = stylex.create({ x: { cursor: 'e-resize' } });
190
+ const classnames = stylex(styles.x);
191
+ `)
192
+ ).toMatchInlineSnapshot(`
193
+ "import stylex from 'stylex';
194
+ stylex.inject(".x14mnfz1{cursor:e-resize}", 1, ".x14mnfz1{cursor:w-resize}");
195
+ const classnames = "x14mnfz1";"
196
+ `);
197
+ });
198
+
199
+ test('[legacy] value "w-resize" for "cursor" property', () => {
200
+ expect(
201
+ transform(`
202
+ import stylex from 'stylex';
203
+ const styles = stylex.create({ x: { cursor: 'w-resize' } });
204
+ const classnames = stylex(styles.x);
205
+ `)
206
+ ).toMatchInlineSnapshot(`
207
+ "import stylex from 'stylex';
208
+ stylex.inject(".x14isd7o{cursor:w-resize}", 1, ".x14isd7o{cursor:e-resize}");
209
+ const classnames = "x14isd7o";"
210
+ `);
211
+ });
212
+
213
+ test('[legacy] value "ne-resize" for "cursor" property', () => {
214
+ expect(
215
+ transform(`
216
+ import stylex from 'stylex';
217
+ const styles = stylex.create({ x: { cursor: 'ne-resize' } });
218
+ const classnames = stylex(styles.x);
219
+ `)
220
+ ).toMatchInlineSnapshot(`
221
+ "import stylex from 'stylex';
222
+ stylex.inject(".xc7edbc{cursor:ne-resize}", 1, ".xc7edbc{cursor:nw-resize}");
223
+ const classnames = "xc7edbc";"
224
+ `);
225
+ });
226
+
227
+ test('[legacy] value "nw-resize" for "cursor" property', () => {
228
+ expect(
229
+ transform(`
230
+ import stylex from 'stylex';
231
+ const styles = stylex.create({ x: { cursor: 'nw-resize' } });
232
+ const classnames = stylex(styles.x);
233
+ `)
234
+ ).toMatchInlineSnapshot(`
235
+ "import stylex from 'stylex';
236
+ stylex.inject(".xrpsa6j{cursor:nw-resize}", 1, ".xrpsa6j{cursor:ne-resize}");
237
+ const classnames = "xrpsa6j";"
238
+ `);
239
+ });
240
+
241
+ test('[legacy] value "se-resize" for "cursor" property', () => {
242
+ expect(
243
+ transform(`
244
+ import stylex from 'stylex';
245
+ const styles = stylex.create({ x: { cursor: 'se-resize' } });
246
+ const classnames = stylex(styles.x);
247
+ `)
248
+ ).toMatchInlineSnapshot(`
249
+ "import stylex from 'stylex';
250
+ stylex.inject(".xp35lg9{cursor:se-resize}", 1, ".xp35lg9{cursor:sw-resize}");
251
+ const classnames = "xp35lg9";"
252
+ `);
253
+ });
254
+
255
+ test('[legacy] value "sw-resize" for "cursor" property', () => {
256
+ expect(
257
+ transform(`
258
+ import stylex from 'stylex';
259
+ const styles = stylex.create({ x: { cursor: 'sw-resize' } });
260
+ const classnames = stylex(styles.x);
261
+ `)
262
+ ).toMatchInlineSnapshot(`
263
+ "import stylex from 'stylex';
264
+ stylex.inject(".x1egwzy8{cursor:sw-resize}", 1, ".x1egwzy8{cursor:se-resize}");
265
+ const classnames = "x1egwzy8";"
266
+ `);
267
+ });
268
+
269
+ /**
270
+ * Legacy transforms
271
+ * TODO(#33): Remove once support for multi-sided values is removed from shortforms.
272
+ */
273
+
274
+ test('[legacy] value of "animationName" property', () => {
275
+ expect(
276
+ transform(`
277
+ import stylex from 'stylex';
278
+ const styles = stylex.create({ x: { animationName: 'ignore' } });
279
+ const classnames = stylex(styles.x);
280
+ `)
281
+ ).toMatchInlineSnapshot(`
282
+ "import stylex from 'stylex';
283
+ stylex.inject(".x13xdq3h{animation-name:ignore}", 1);
284
+ const classnames = "x13xdq3h";"
285
+ `);
286
+ });
287
+
288
+ test('[legacy] value of "backgroundPosition" property', () => {
289
+ expect(
290
+ transform(`
291
+ import stylex from 'stylex';
292
+ const styles = stylex.create({ x: { backgroundPosition: 'top end' } });
293
+ const classnames = stylex(styles.x);
294
+ `)
295
+ ).toMatchInlineSnapshot(`
296
+ "import stylex from 'stylex';
297
+ stylex.inject(".xl0ducr{background-position:top right}", 1, ".xl0ducr{background-position:top left}");
298
+ const classnames = "xl0ducr";"
299
+ `);
300
+ expect(
301
+ transform(`
302
+ import stylex from 'stylex';
303
+ const styles = stylex.create({ x: { backgroundPosition: 'top start' } });
304
+ const classnames = stylex(styles.x);
305
+ `)
306
+ ).toMatchInlineSnapshot(`
307
+ "import stylex from 'stylex';
308
+ stylex.inject(".xgg80n4{background-position:top left}", 1, ".xgg80n4{background-position:top right}");
309
+ const classnames = "xgg80n4";"
310
+ `);
311
+ });
312
+
313
+ test('[legacy] value of "boxShadow" property', () => {
314
+ expect(
315
+ transform(`
316
+ import stylex from 'stylex';
317
+ const styles = stylex.create({ x: { boxShadow: 'none' } });
318
+ const classnames = stylex(styles.x);
319
+ `)
320
+ ).toMatchInlineSnapshot(`
321
+ "import stylex from 'stylex';
322
+ stylex.inject(".x1gnnqk1{box-shadow:none}", 1);
323
+ const classnames = "x1gnnqk1";"
324
+ `);
325
+ expect(
326
+ transform(`
327
+ import stylex from 'stylex';
328
+ const styles = stylex.create({ x: { boxShadow: '1px 1px #000' } });
329
+ const classnames = stylex(styles.x);
330
+ `)
331
+ ).toMatchInlineSnapshot(`
332
+ "import stylex from 'stylex';
333
+ stylex.inject(".xtgyqtp{box-shadow:1px 1px #000}", 1, ".xtgyqtp{box-shadow:-1px 1px #000}");
334
+ const classnames = "xtgyqtp";"
335
+ `);
336
+ expect(
337
+ transform(`
338
+ import stylex from 'stylex';
339
+ const styles = stylex.create({ x: { boxShadow: '-1px -1px #000' } });
340
+ const classnames = stylex(styles.x);
341
+ `)
342
+ ).toMatchInlineSnapshot(`
343
+ "import stylex from 'stylex';
344
+ stylex.inject(".x1d2r41h{box-shadow:-1px -1px #000}", 1, ".x1d2r41h{box-shadow:1px -1px #000}");
345
+ const classnames = "x1d2r41h";"
346
+ `);
347
+ expect(
348
+ transform(`
349
+ import stylex from 'stylex';
350
+ const styles = stylex.create({ x: { boxShadow: 'inset 1px 1px #000' } });
351
+ const classnames = stylex(styles.x);
352
+ `)
353
+ ).toMatchInlineSnapshot(`
354
+ "import stylex from 'stylex';
355
+ stylex.inject(".x1x0mpz7{box-shadow:inset 1px 1px #000}", 1, ".x1x0mpz7{box-shadow:inset -1px 1px #000}");
356
+ const classnames = "x1x0mpz7";"
357
+ `);
358
+ expect(
359
+ transform(`
360
+ import stylex from 'stylex';
361
+ const styles = stylex.create({ x: { boxShadow: '1px 1px 1px 1px #000' } });
362
+ const classnames = stylex(styles.x);
363
+ `)
364
+ ).toMatchInlineSnapshot(`
365
+ "import stylex from 'stylex';
366
+ stylex.inject(".x1fumi7f{box-shadow:1px 1px 1px 1px #000}", 1, ".x1fumi7f{box-shadow:-1px 1px 1px 1px #000}");
367
+ const classnames = "x1fumi7f";"
368
+ `);
369
+ expect(
370
+ transform(`
371
+ import stylex from 'stylex';
372
+ const styles = stylex.create({ x: { boxShadow: 'inset 1px 1px 1px 1px #000' } });
373
+ const classnames = stylex(styles.x);
374
+ `)
375
+ ).toMatchInlineSnapshot(`
376
+ "import stylex from 'stylex';
377
+ stylex.inject(".x1fs23zf{box-shadow:inset 1px 1px 1px 1px #000}", 1, ".x1fs23zf{box-shadow:inset -1px 1px 1px 1px #000}");
378
+ const classnames = "x1fs23zf";"
379
+ `);
380
+ expect(
381
+ transform(`
382
+ import stylex from 'stylex';
383
+ const styles = stylex.create({ x: { boxShadow: '2px 2px 2px 2px red, inset 1px 1px 1px 1px #000' } });
384
+ const classnames = stylex(styles.x);
385
+ `)
386
+ ).toMatchInlineSnapshot(`
387
+ "import stylex from 'stylex';
388
+ stylex.inject(".xtgmjod{box-shadow:2px 2px 2px 2px red,inset 1px 1px 1px 1px #000}", 1, ".xtgmjod{box-shadow:-2px 2px 2px 2px red, inset -1px 1px 1px 1px #000}");
389
+ const classnames = "xtgmjod";"
390
+ `);
391
+ });
392
+
393
+ test('[legacy] value of "textShadow" property', () => {
394
+ expect(
395
+ transform(`
396
+ import stylex from 'stylex';
397
+ const styles = stylex.create({ x: { textShadow: 'none' } });
398
+ const classnames = stylex(styles.x);
399
+ `)
400
+ ).toMatchInlineSnapshot(`
401
+ "import stylex from 'stylex';
402
+ stylex.inject(".x19pm5ym{text-shadow:none}", 1);
403
+ const classnames = "x19pm5ym";"
404
+ `);
405
+ expect(
406
+ transform(`
407
+ import stylex from 'stylex';
408
+ const styles = stylex.create({ x: { textShadow: '1px 1px #000' } });
409
+ const classnames = stylex(styles.x);
410
+ `)
411
+ ).toMatchInlineSnapshot(`
412
+ "import stylex from 'stylex';
413
+ stylex.inject(".x12y90mb{text-shadow:1px 1px #000}", 1, ".x12y90mb{text-shadow:-1px 1px #000}");
414
+ const classnames = "x12y90mb";"
415
+ `);
416
+ expect(
417
+ transform(`
418
+ import stylex from 'stylex';
419
+ const styles = stylex.create({ x: { textShadow: '-1px -1px #000' } });
420
+ const classnames = stylex(styles.x);
421
+ `)
422
+ ).toMatchInlineSnapshot(`
423
+ "import stylex from 'stylex';
424
+ stylex.inject(".x1l3mtsg{text-shadow:-1px -1px #000}", 1, ".x1l3mtsg{text-shadow:1px -1px #000}");
425
+ const classnames = "x1l3mtsg";"
426
+ `);
427
+ expect(
428
+ transform(`
429
+ import stylex from 'stylex';
430
+ const styles = stylex.create({ x: { textShadow: '1px 1px 1px #000' } });
431
+ const classnames = stylex(styles.x);
432
+ `)
433
+ ).toMatchInlineSnapshot(`
434
+ "import stylex from 'stylex';
435
+ stylex.inject(".x67hq7l{text-shadow:1px 1px 1px #000}", 1, ".x67hq7l{text-shadow:-1px 1px 1px #000}");
436
+ const classnames = "x67hq7l";"
437
+ `);
438
+ });
439
+ });
440
+ });
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ jest.autoMockOff();
11
+
12
+ const { transformSync } = require('@babel/core');
13
+ const stylexPlugin = require('../src/index');
14
+
15
+ function transform(source, opts = {}) {
16
+ return transformSync(source, {
17
+ filename: opts.filename,
18
+ parserOpts: {
19
+ flow: {
20
+ all: true,
21
+ },
22
+ },
23
+ plugins: [[stylexPlugin, opts]],
24
+ }).code;
25
+ }
26
+
27
+ describe('@stylexjs/babel-plugin', () => {
28
+ /**
29
+ * CSS polyfills
30
+ */
31
+
32
+ describe.skip('[transform] stylex polyfills', () => {
33
+ test('lineClamp', () => {
34
+ expect(
35
+ transform(`
36
+ import stylex from 'stylex';
37
+ const styles = stylex.create({ x: { lineClamp: 3 } });
38
+ `)
39
+ ).toMatchInlineSnapshot();
40
+ });
41
+
42
+ test('pointerEvents', () => {
43
+ expect(
44
+ transform(`
45
+ import stylex from 'stylex';
46
+ const styles = stylex.create({
47
+ a: { pointerEvents: 'auto' },
48
+ b: { pointerEvents: 'box-none' },
49
+ c: { pointerEvents: 'box-only' },
50
+ d: { pointerEvents: 'none' }
51
+ });
52
+ `)
53
+ ).toMatchInlineSnapshot();
54
+ });
55
+
56
+ test('scrollbarWidth', () => {
57
+ expect(
58
+ transform(`
59
+ import stylex from 'stylex';
60
+ const styles = stylex.create({ x: { scrollbarWidth: 'none' } });
61
+ `)
62
+ ).toMatchInlineSnapshot();
63
+ });
64
+ });
65
+ });