babel-plugin-styled-components icon indicating copy to clipboard operation
babel-plugin-styled-components copied to clipboard

When a jsx element is dynamically defined in the function and using css prop you get `is not defined` error

Open emattias opened this issue 5 years ago • 2 comments

Reproduction

https://codesandbox.io/s/beautiful-nash-0llyo

Steps to reproduce

Use css prop and have a dynamic component variable, like the As variable here:

import React from "react";
import "styled-components/macro";

export default function ({ As = "div" }) {
  return (
    <As
      css={`
        color: papayawhip;
        background: palevioletred;
      `}
    >
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </As>
  );
}

It will result in a As is not defined error.

If you move the As variable definition out of the function it works:

import React from "react";
import "styled-components/macro";

const As = "div";

export const Works1 = function () {
  return (
    <As
      css={`
        color: papayawhip;
        background: palevioletred;
      `}
    >
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </As>
  );
};

Expected Behavior

To be able to have dynamic component variable like you can when not using the css prop

Actual Behavior

CleanShot 2020-10-12 at 16 22 13@2x

emattias avatar Oct 12 '20 14:10 emattias

This was introduced on 4.3.2 – https://github.com/styled-components/styled-components/compare/v4.3.1..v4.3.2

cusspvz avatar Nov 20 '20 18:11 cusspvz

This issue should've been opened on babel-plugin-styled-components probably 😅 Currently, the plugin doesn't support dynamic inputs of components, so it'll attemp to convert this:

function YourComponent({ As = "div" }) {
  return (
    <As
      css={`
        color: papayawhip;
        background: palevioletred;
      `}
    >
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </As>
  );
}

to this:

const StyledAs = styled(As)`
  color: papayawhip;
  background: palevioletred;
`;

function YourComponent({ As = "div" }) {
  return (
    <StyledAs>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </As>
  );
}

Which doesn't work, since As isn't defined at the module-scope. So, it should likely generate this instead:

const StyledAs = styled.div`
  color: papayawhip;
  background: palevioletred;
`;

function YourComponent({ As = "div" }) {
  return (
    <StyledAs as={As}>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </As>
  );
}

kitten avatar Aug 09 '21 17:08 kitten