@stylexjs/stylex 0.2.0-beta.10 → 0.2.0-beta.11

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,453 @@
1
+ "use strict";
2
+
3
+ var _stylex = require("../stylex");
4
+ /**
5
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
10
+
11
+ const mockOptions = {
12
+ customProperties: {},
13
+ viewportHeight: 600,
14
+ viewportWidth: 320
15
+ };
16
+ describe('styles', () => {
17
+ beforeEach(() => {
18
+ jest.spyOn(console, 'error');
19
+ console.error.mockImplementation(() => {});
20
+ });
21
+ afterEach(() => {
22
+ console.error.mockRestore();
23
+ });
24
+ test('background-image', () => {
25
+ const styles = _stylex.stylex.create({
26
+ root: {
27
+ backgroundImage: 'url(https://placehold.it/300/300'
28
+ }
29
+ });
30
+ _stylex.stylex.spread(styles.root, mockOptions);
31
+ expect(console.error).toHaveBeenCalled();
32
+ });
33
+ test('box-shadow', () => {
34
+ const styles = _stylex.stylex.create({
35
+ root: {
36
+ boxShadow: '1px 2px 3px 4px red'
37
+ }
38
+ });
39
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
40
+ const styles2 = _stylex.stylex.create({
41
+ root: {
42
+ boxShadow: '1px 2px 3px 4px red, 2px 3px 4px 5px blue'
43
+ }
44
+ });
45
+ _stylex.stylex.spread(styles2.root, mockOptions);
46
+ expect(console.error).toHaveBeenCalledTimes(1);
47
+ const styles3 = _stylex.stylex.create({
48
+ root: {
49
+ boxShadow: 'inset 1px 2px 3px 4px red'
50
+ }
51
+ });
52
+ _stylex.stylex.spread(styles3.root, mockOptions);
53
+ expect(console.error).toHaveBeenCalledTimes(2);
54
+ });
55
+ test('direction', () => {
56
+ const styles = _stylex.stylex.create({
57
+ root: {
58
+ direction: 'ltr'
59
+ }
60
+ });
61
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
62
+ const styles2 = _stylex.stylex.create({
63
+ root: {
64
+ direction: 'rtl'
65
+ }
66
+ });
67
+ expect(_stylex.stylex.spread(styles2.root, mockOptions)).toMatchSnapshot();
68
+ });
69
+ test('font-size', () => {
70
+ const styles = _stylex.stylex.create({
71
+ root: {
72
+ fontSize: '2.5rem'
73
+ }
74
+ });
75
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot('default');
76
+ expect(_stylex.stylex.spread(styles.root, {
77
+ ...mockOptions,
78
+ fontScale: 2
79
+ })).toMatchSnapshot('fontScale:2');
80
+ });
81
+ test('font-variant', () => {
82
+ const styles = _stylex.stylex.create({
83
+ root: {
84
+ fontVariant: 'common-ligatures small-caps'
85
+ }
86
+ });
87
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
88
+ });
89
+ test('font-weight', () => {
90
+ const styles = _stylex.stylex.create({
91
+ root: {
92
+ fontWeight: 900
93
+ }
94
+ });
95
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
96
+ const styles2 = _stylex.stylex.create({
97
+ root: {
98
+ fontWeight: 'bold'
99
+ }
100
+ });
101
+ expect(_stylex.stylex.spread(styles2.root, mockOptions)).toMatchSnapshot();
102
+ });
103
+ test('line-clamp', () => {
104
+ const styles = _stylex.stylex.create({
105
+ root: {
106
+ lineClamp: 3
107
+ }
108
+ });
109
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
110
+ });
111
+ test('object-fit', () => {
112
+ const styles = _stylex.stylex.create({
113
+ contain: {
114
+ objectFit: 'contain'
115
+ },
116
+ cover: {
117
+ objectFit: 'cover'
118
+ },
119
+ fill: {
120
+ objectFit: 'fill'
121
+ },
122
+ scaleDown: {
123
+ objectFit: 'scale-down'
124
+ },
125
+ none: {
126
+ objectFit: 'none'
127
+ }
128
+ });
129
+ expect(_stylex.stylex.spread(styles.contain, mockOptions)).toMatchSnapshot('contain');
130
+ expect(_stylex.stylex.spread(styles.cover, mockOptions)).toMatchSnapshot('contain');
131
+ expect(_stylex.stylex.spread(styles.fill, mockOptions)).toMatchSnapshot('fill');
132
+ expect(_stylex.stylex.spread(styles.scaleDown, mockOptions)).toMatchSnapshot('scaleDown');
133
+ expect(_stylex.stylex.spread(styles.none, mockOptions)).toMatchSnapshot('none');
134
+ });
135
+ test('pointer-events', () => {
136
+ const styles = _stylex.stylex.create({
137
+ root: {
138
+ pointerEvents: 'none'
139
+ }
140
+ });
141
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
142
+ });
143
+ test('position', () => {
144
+ const styles = _stylex.stylex.create({
145
+ static: {
146
+ position: 'static'
147
+ },
148
+ relative: {
149
+ position: 'relative'
150
+ },
151
+ absolute: {
152
+ position: 'absolute'
153
+ },
154
+ fixed: {
155
+ position: 'fixed'
156
+ },
157
+ sticky: {
158
+ position: 'sticky'
159
+ }
160
+ });
161
+ expect(console.error).toHaveBeenCalledTimes(2);
162
+ expect(_stylex.stylex.spread(styles.static, mockOptions)).toMatchSnapshot('static');
163
+ expect(_stylex.stylex.spread(styles.relative, mockOptions)).toMatchSnapshot('relative');
164
+ expect(_stylex.stylex.spread(styles.absolute, mockOptions)).toMatchSnapshot('absolute');
165
+ expect(_stylex.stylex.spread(styles.fixed, mockOptions)).toMatchSnapshot('fixed');
166
+ expect(_stylex.stylex.spread(styles.sticky, mockOptions)).toMatchSnapshot('sticky');
167
+ });
168
+ test('text-shadow', () => {
169
+ const styles = _stylex.stylex.create({
170
+ root: {
171
+ textShadow: '1px 2px 3px red'
172
+ }
173
+ });
174
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
175
+ const styles2 = _stylex.stylex.create({
176
+ root: {
177
+ textShadow: '1px 2px 3px red, 2px 3px 4px blue'
178
+ }
179
+ });
180
+ expect(_stylex.stylex.spread(styles2.root, mockOptions)).toMatchSnapshot();
181
+ expect(console.error).toHaveBeenCalledTimes(1);
182
+ });
183
+ test('transform', () => {
184
+ const styles = _stylex.stylex.create({
185
+ none: {
186
+ transform: 'none'
187
+ },
188
+ matrix: {
189
+ transform: 'matrix(0.1, 1, -0.3, 1, 0, 0)'
190
+ },
191
+ perspective: {
192
+ transform: 'perspective(10px)'
193
+ },
194
+ rotate: {
195
+ transform: 'rotate(10deg) rotateX(20deg) rotateY(30deg) rotateZ(40deg) rotate3d(0, 0.5, 1, 90deg)'
196
+ },
197
+ scale: {
198
+ transform: 'scale(1, 2) scaleX(1) scaleY(2) scaleZ(3) scale3d(1, 2, 3)'
199
+ },
200
+ skew: {
201
+ transform: 'skew(10deg, 15deg) skewX(20deg) skewY(30deg)'
202
+ },
203
+ translate: {
204
+ transform: 'translate(10px, 20px) translateX(11px) translateY(12px) translateZ(13px) translate3d(20px, 30px, 40px)'
205
+ },
206
+ mixed: {
207
+ transform: `
208
+ rotateX(1deg) rotateY(2deg) rotateZ(3deg) rotate3d(1deg, 2deg, 3deg)
209
+ scale(1) scaleX(2) scaleY(3) scaleZ(4) scale3d(1,2,3)
210
+ translateX(1px) translateY(1em) translateZ(1rem) translate3d(1px, 1em, 1rem)
211
+ `
212
+ }
213
+ });
214
+ expect(_stylex.stylex.spread(styles.none, mockOptions)).toMatchSnapshot('none');
215
+ expect(_stylex.stylex.spread(styles.matrix, mockOptions)).toMatchSnapshot('matrix');
216
+ expect(_stylex.stylex.spread(styles.perspective, mockOptions)).toMatchSnapshot('perspective');
217
+ expect(_stylex.stylex.spread(styles.rotate, mockOptions)).toMatchSnapshot('rotate');
218
+ expect(_stylex.stylex.spread(styles.scale, mockOptions)).toMatchSnapshot('scale');
219
+ expect(_stylex.stylex.spread(styles.skew, mockOptions)).toMatchSnapshot('skew');
220
+ expect(_stylex.stylex.spread(styles.translate, mockOptions)).toMatchSnapshot('translate');
221
+ expect(_stylex.stylex.spread(styles.rotate, mockOptions)).toMatchSnapshot('rotate');
222
+ expect(_stylex.stylex.spread(styles.mixed, mockOptions)).toMatchSnapshot('mixed');
223
+ });
224
+ test('user-select', () => {
225
+ const styles = _stylex.stylex.create({
226
+ root: {
227
+ userSelect: 'none'
228
+ }
229
+ });
230
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
231
+ });
232
+ test('vertical-align', () => {
233
+ const styles = _stylex.stylex.create({
234
+ middle: {
235
+ verticalAlign: 'middle'
236
+ },
237
+ top: {
238
+ verticalAlign: 'top'
239
+ }
240
+ });
241
+ expect(_stylex.stylex.spread(styles.middle, mockOptions)).toMatchSnapshot('middle');
242
+ expect(_stylex.stylex.spread(styles.top, mockOptions)).toMatchSnapshot('top');
243
+ });
244
+ test.skip('logical border short-forms', () => {
245
+ const styles = _stylex.stylex.create({
246
+ root: {}
247
+ });
248
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
249
+ });
250
+ test.skip('logical border long-forms', () => {
251
+ const styles = _stylex.stylex.create({
252
+ root: {}
253
+ });
254
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
255
+ });
256
+ test.skip('logical inset short-forms', () => {
257
+ const styles = _stylex.stylex.create({
258
+ root: {
259
+ insetBlock: 5,
260
+ insetInline: 10
261
+ }
262
+ });
263
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
264
+ });
265
+ test.skip('logical text alignment', () => {
266
+ const styles = _stylex.stylex.create({
267
+ root: {
268
+ textAlign: 'start'
269
+ }
270
+ });
271
+ expect(_stylex.stylex.spread(styles.root, mockOptions)).toMatchSnapshot();
272
+ });
273
+ });
274
+ describe('length units', () => {
275
+ const unitsToTest = ['em', 'px', 'rem', 'vh', 'vmax', 'vmin', 'vw'];
276
+ const value = 10;
277
+ for (const unitToTest of unitsToTest) {
278
+ test(`${value} "${unitToTest}" units are resolved to pixels`, () => {
279
+ const styles = _stylex.stylex.create({
280
+ underTest: {
281
+ width: `${value}${unitToTest}`
282
+ }
283
+ });
284
+ expect(_stylex.stylex.spread(styles.underTest, mockOptions)).toMatchSnapshot();
285
+ });
286
+ }
287
+ test(`${value} "em" units based on inherited font-size`, () => {
288
+ const styles = _stylex.stylex.create({
289
+ underTest: {
290
+ width: `${value}em`
291
+ }
292
+ });
293
+ expect(_stylex.stylex.spread(styles.underTest, {
294
+ ...mockOptions,
295
+ inheritedFontSize: 12
296
+ })).toMatchSnapshot();
297
+ });
298
+ });
299
+ describe('custom properties', () => {
300
+ beforeEach(() => {
301
+ jest.spyOn(console, 'error');
302
+ console.error.mockImplementation(() => {});
303
+ });
304
+ afterEach(() => {
305
+ console.error.mockRestore();
306
+ });
307
+ test('filters out the property and emits a warning when encountering a variable name which has not been provided', () => {
308
+ const {
309
+ underTest
310
+ } = _stylex.stylex.create({
311
+ underTest: {
312
+ width: 'var(--unprovided)'
313
+ }
314
+ });
315
+ expect(_stylex.stylex.spread(underTest, mockOptions)).toMatchSnapshot();
316
+ expect(console.error).toHaveBeenCalledWith('stylex: Unrecognized custom property "--unprovided"');
317
+ });
318
+ test("resolves custom properties' values", () => {
319
+ const {
320
+ underTest
321
+ } = _stylex.stylex.create({
322
+ underTest: {
323
+ color: 'var(--slightly-darker-black)',
324
+ width: 'var(--the-best-width)'
325
+ }
326
+ });
327
+ expect(_stylex.stylex.spread(underTest, {
328
+ ...mockOptions,
329
+ customProperties: {
330
+ slightlyDarkerBlack: '#333',
331
+ theBestWidth: 42
332
+ }
333
+ })).toMatchSnapshot();
334
+ });
335
+ });
336
+ expect.extend({
337
+ toMatchWindowDimensions(query, windowSize) {
338
+ const {
339
+ height,
340
+ width
341
+ } = windowSize;
342
+ const EXPECTED_MATCHED_VALUE = 500;
343
+ const {
344
+ underTest
345
+ } = _stylex.stylex.create({
346
+ underTest: {
347
+ [`@media ${query}`]: {
348
+ width: EXPECTED_MATCHED_VALUE
349
+ }
350
+ }
351
+ });
352
+ const props = _stylex.stylex.spread(underTest, {
353
+ viewportHeight: height,
354
+ viewportWidth: width
355
+ });
356
+ const actualValue = props.style.width;
357
+ if (actualValue === EXPECTED_MATCHED_VALUE) {
358
+ return {
359
+ pass: true,
360
+ message: () => `expected media query ${query} not to match in a window of width ${width} and height ${height}`
361
+ };
362
+ } else {
363
+ return {
364
+ pass: false,
365
+ message: () => `expected media query ${query} to match in a window of width ${width} and height ${height}`
366
+ };
367
+ }
368
+ }
369
+ });
370
+ describe('media queries', () => {
371
+ test('matches a "min-width" query', () => {
372
+ expect('(min-width: 400px)').toMatchWindowDimensions({
373
+ width: 450,
374
+ height: 0
375
+ });
376
+ expect('(min-width: 400px)').not.toMatchWindowDimensions({
377
+ width: 350,
378
+ height: 0
379
+ });
380
+ });
381
+ test('matches a "max-width" query', () => {
382
+ expect('(max-width: 400px)').toMatchWindowDimensions({
383
+ width: 350,
384
+ height: 0
385
+ });
386
+ expect('(max-width: 400px)').not.toMatchWindowDimensions({
387
+ width: 450,
388
+ height: 0
389
+ });
390
+ });
391
+ test('matches a "min-height" query', () => {
392
+ expect('(min-height: 400px)').toMatchWindowDimensions({
393
+ width: 0,
394
+ height: 450
395
+ });
396
+ expect('(min-height: 400px)').not.toMatchWindowDimensions({
397
+ width: 0,
398
+ height: 350
399
+ });
400
+ });
401
+ test('matches a "max-height" query', () => {
402
+ expect('(max-height: 400px)').toMatchWindowDimensions({
403
+ width: 0,
404
+ height: 350
405
+ });
406
+ expect('(max-height: 400px)').not.toMatchWindowDimensions({
407
+ width: 0,
408
+ height: 450
409
+ });
410
+ });
411
+ });
412
+ describe('unsupported style values', () => {
413
+ beforeEach(() => {
414
+ jest.spyOn(console, 'error');
415
+ console.error.mockImplementation(() => {});
416
+ });
417
+ afterEach(() => {
418
+ console.error.mockRestore();
419
+ });
420
+ test('calc', () => {
421
+ const {
422
+ underTest
423
+ } = _stylex.stylex.create({
424
+ underTest: {
425
+ width: 'calc(2 * 1rem)'
426
+ }
427
+ });
428
+ expect(_stylex.stylex.spread(underTest, mockOptions)).toMatchSnapshot();
429
+ expect(console.error).toHaveBeenCalled();
430
+ });
431
+ test('inherit', () => {
432
+ const {
433
+ underTest
434
+ } = _stylex.stylex.create({
435
+ underTest: {
436
+ fontSize: 'inherit'
437
+ }
438
+ });
439
+ expect(_stylex.stylex.spread(underTest, mockOptions)).toMatchSnapshot();
440
+ expect(console.error).toHaveBeenCalled();
441
+ });
442
+ test('initial', () => {
443
+ const {
444
+ underTest
445
+ } = _stylex.stylex.create({
446
+ underTest: {
447
+ fontSize: 'initial'
448
+ }
449
+ });
450
+ expect(_stylex.stylex.spread(underTest, mockOptions)).toMatchSnapshot();
451
+ expect(console.error).toHaveBeenCalled();
452
+ });
453
+ });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.errorMsg = errorMsg;
7
+ /**
8
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
9
+ *
10
+ * This source code is licensed under the MIT license found in the
11
+ * LICENSE file in the root directory of this source tree.
12
+ *
13
+ *
14
+ */
15
+
16
+ function errorMsg(msg) {
17
+ console.error(`stylex: ${msg}`);
18
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.flattenStyle = flattenStyle;
7
+ /**
8
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
9
+ *
10
+ * This source code is licensed under the MIT license found in the
11
+ * LICENSE file in the root directory of this source tree.
12
+ *
13
+ *
14
+ */
15
+
16
+ function flattenStyle() {
17
+ for (var _len = arguments.length, styles = new Array(_len), _key = 0; _key < _len; _key++) {
18
+ styles[_key] = arguments[_key];
19
+ }
20
+ const flatArray = styles.flat(Infinity);
21
+ const result = {};
22
+ for (let i = 0; i < flatArray.length; i++) {
23
+ const style = flatArray[i];
24
+ if (style != null && typeof style === 'object') {
25
+ // $FlowFixMe
26
+ Object.assign(result, style);
27
+ }
28
+ }
29
+ return result;
30
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parseShadow = parseShadow;
7
+ /**
8
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
9
+ *
10
+ * This source code is licensed under the MIT license found in the
11
+ * LICENSE file in the root directory of this source tree.
12
+ *
13
+ *
14
+ */
15
+
16
+ const VALUES_REG = /,(?![^(]*\))/;
17
+ const PARTS_REG = /\s(?![^(]*\))/;
18
+ const LENGTH_REG = /^[0-9]+[a-zA-Z%]+?$/;
19
+ function isLength(v) {
20
+ return v === '0' || LENGTH_REG.test(v);
21
+ }
22
+ function toMaybeNum(v) {
23
+ if (!/px$/.test(v) && v !== '0') return v;
24
+ const n = parseFloat(v);
25
+ return !isNaN(n) ? n : v;
26
+ }
27
+ function parseValue(str) {
28
+ const parts = str.split(PARTS_REG);
29
+ const inset = parts.includes('inset');
30
+ const last = parts.slice(-1)[0];
31
+ const color = !isLength(last) ? last : null;
32
+ const nums = parts.filter(n => n !== 'inset').filter(n => n !== color).map(toMaybeNum);
33
+ const [offsetX, offsetY, blurRadius, spreadRadius] = nums;
34
+ return {
35
+ inset,
36
+ offsetX,
37
+ offsetY,
38
+ blurRadius,
39
+ spreadRadius,
40
+ color
41
+ };
42
+ }
43
+ function parseShadow(str) {
44
+ return str.split(VALUES_REG).map(s => s.trim()).map(parseValue);
45
+ }