Corrupted class names including string "null" generated from dynamic style with media query conditions
- 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
Assessment
This issue has not been assessed yet.