compiled icon indicating copy to clipboard operation
compiled copied to clipboard

Math functions, eg rounding to the nearest integer, are not supported

Open pancaspe87 opened this issue 2 years ago • 2 comments

Describe the bug code

  -webkit-line-clamp: ${({ outerExcerptHeight }) =>
    Math.floor(outerExcerptHeight / EXCERPT_LINE_HEIGHT)};

was transpiled into "--_1lqp0gv": ix(Math.floor(outerExcerptHeight / EXCERPT_LINE_HEIGHT)(outerExcerptHeight / EXCERPT_LINE_HEIGHT))

which in turn throws message: "Math.floor(...) is not a function"

Expected behavior Ability to round values and avoid browser inconsistencies.

Workaround Use inline style

const ComponentWithInlineStyle = (props) => {

  const lineClampValue = Math.floor(props.outerExcerptHeight / EXCERPT_LINE_HEIGHT);

  return (<div
    css={css`
      background-color: lightgrey;
      border: 1px solid black;
      position: absolute;
    `}
    style={{WebkitLineClamp: `${lineClampValue}` }}
  >  {props.children}</div>);
};

pancaspe87 avatar Apr 21 '22 06:04 pancaspe87

This appears to be caused by member function access.

If we change the example in the description to use a Identifier (instead of MemberExpression) as the call expression node, the functionality works:

const floor = Math.floor;

...

  -webkit-line-clamp: ${({ outerExcerptHeight }) =>
    floor(outerExcerptHeight / EXCERPT_LINE_HEIGHT)};

JakeLane avatar Apr 22 '22 02:04 JakeLane

Here's a failing test that can be added to packages/babel-plugin/src/__tests__/expression-evaluation.test.ts:

  it('should not double call a member function', () => {
    const actual = transform(`
        import '@compiled/react';
        
        function Component() {
          return (
            <span css={{ width: foo.bar() }} />
          );
        }
      `);

    expect(actual).not.toInclude('foo.bar()()');
  });

Possibly that's not the right description for the issue, but it does fail.

marcins avatar Sep 19 '22 04:09 marcins