facebook / facebook/stylex

Corrupted class names including string "null" generated from dynamic style with media query conditions

Open
#1,702 0 comments 1 reaction 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
10.3k
Forks
481
Avg merge
3d 8h
Merged PRs (30d)
13

Description

### Describe the issue

When using `stylex.create()` with dynamic style functions having a media query condition evaluating to `null`, StyleX generates class names that incorrectly include the raw string "null" in them leading to corrputed name, like `"nullxafpxz5"`. This corrupted class name results respective style getting completely ignored. According to the StyleX documentation, null values should be ignored and not included in the generated class names.

### Expected behavior

Conditional media query styles that return `null` should be ignored.

### Steps to reproduce

Following component should have `background-color: tomato` when viewport is wider than 600px:

```jsx
import * as stylex from "@stylexjs/stylex";

const styles = stylex.create({
highlightAt: (small, large) => ({
backgroundColor: {
default: null,
"@media (max-width: 599px)": small ? "red" : null,
"@media (min-width: 600px)": large ? "red" : null,
},
}),
});

const MyComponent = () => (


I should be red when viewport width is more than 600px

);
```

- **StyleX version**: 0.18.3
- **Plugins**: @stylexjs/babel-plugin, @stylexjs/postcss-plugin
- **Environments tested**: Astro.js dev server and production builds, Storybook

### Test case

Reproduction steps work as deterministic test case.

### Additional comments

Behavior is likely due to transpilation issue that can be reduced to very minimal Node.js program when standard stylex dependencies (@babel/core @babel/preset-react @stylexjs/babel-plugin) are in place. Self-contained reproduction repository: https://github.com/joonaojapalo/stylex-dynamic-mediaquery-repro

```js
// repro.js
const babel = require("@babel/core");

const input = `
import * as stylex from '@stylexjs/stylex';

const styles = stylex.create({
highlightAt: (small, large) => ({
backgroundColor: {
"@media (max-width: 599px)": small ? "red" : null,
"@media (min-width: 600px)": large ? "red" : null,
},
}),
});


`;

const output = babel.transformSync(input, {
presets: [["@babel/preset-react"]],
plugins: [["@stylexjs/babel-plugin"]],
});

console.log(output.code);
```

This outputs transpiled code with following essential part:

```js
// ... redacted ..
highlightAt: (small, large) => [{
kWkggS: (
(small ? "red" : null) != null
? "xkcfsz0 "
: small
? "red"
: null
) + //

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.