Current behavior:
When I add a the style <div css={{ width: 'stackWidth' }} />, the app crashes in an infinite loop and the error
RangeError: Maximum call stack size exceeded
To reproduce:
Expected behavior:
The (incorrect) CSS width: stackWidth; should be applied to the element without throwing an error.
Environment information:
react version: v16.8.6 but seems to happen with all React versions@emotion/react version: v11.1.1More info to bug:
The infinite loop is caused by the stylis prefixer. The prefix function is called with the value width:stackWidth; and length 5 which results in the hashed value 8116. In the switch statement in the case of 8116 the prefix function is called again, causing an infinite recursion.
Background:
The issue came up while testing a component using (a yet unreleased version of) Theme UI.
The Theme UI library uses Emotion behind the scene and allows to use styles like <div sx={{ width: 'stackWidth' }} /> where the CSS value for the width will be resolved through a theme put into the Emotion context, so that Emotion receives <div css={{ width: 560 }} />.
The bug came up in a test where a component using Theme UI was rendered. This component was not wrapped in a theme provider, so the value 'stackWidth' could not be resolved and Emotion received <div css={{ width: 'stackWidth' }} />.
Thank you for the detailed repro case! I will forward this issue to Stylis - not yet sure how to best handle this given the Stylis generally assumes valid CSS and it cares about its bundlesize greatly.
Thank you! 馃檹鉂わ笍
Also just for documentation purposes: The current workaround is to wrap components using Theme UI that get into an infinite recursion in a ThemeProvider.
The fix for this issue has just been released in [email protected]
stylis still have the issue some how..
PrettyFormatPluginError: Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
at Array.forEach (
import React from 'react';
import { createSerializer } from '@emotion/jest';
import renderer from 'react-test-renderer';
import { Box } from '../Box';
expect.addSnapshotSerializer(createSerializer());
describe('Box renders', () => {
test('Box renders correctly', () => {
expect(
renderer
.create(
.toJSON()
).toMatchSnapshot();
});
import styled from '@emotion/styled';
import {
alignItems,
alignSelf,
color, display,
flex,
flexBasis,
fontSize,
justifyContent,
order,
space,
width,
minHeight,
} from 'styled-system';
export const Box = styled('div')({
boxSizing: 'border-box',
}, width, space, flex, fontSize, minHeight, color, order, alignItems, justifyContent, alignSelf, flexBasis, display, (props) => props.css);
package.json
"@emotion/babel-plugin": "^11.2.0",
"@emotion/css": "11.1.3",
"@emotion/eslint-plugin": "11.2.0",
"@emotion/jest": "11.2.0",
"@emotion/react": "11.1.5",
"@emotion/styled": "11.1.5",
"react-test-renderer": "17.0.1",
"react": "17.0.1",
Please always try to share a repro case in a runnable form - either by providing a git repository to clone or a codesandbox. OSS maintainers usually can't afford the time to set up the repro, even if exact steps are given.
I also have something strange that i get duplicated css lines in a snapshot
Please always try to share a repro case in a runnable form - either by providing a git repository to clone or a codesandbox. OSS maintainers usually can't afford the time to set up the repro, even if exact steps are given.