Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when passing props to the css attribute in solid/stitches #829

Open
benash opened this issue Aug 18, 2023 · 3 comments
Open

Error when passing props to the css attribute in solid/stitches #829

benash opened this issue Aug 18, 2023 · 3 comments

Comments

@benash
Copy link

benash commented Aug 18, 2023

When using the SolidJS integration, the following results in Uncaught ReferenceError: props is not defined in the browser:

const BrokenInput = (props: InputProps) => (
  <input
    css={{
      ...tw`border`,
      ...(props.hasHover && tw`hover:border-red-600`),
    }}
  />
)

On the other hand, this works fine:

const WorkingInput = styled.input((props: InputProps) => ({
  ...tw`border`,
  ...(props.hasHover && tw`hover:border-red-600`),
}))
@ben-rogerson
Copy link
Owner

ben-rogerson commented Aug 18, 2023

Thanks for posting this bug, I've seen the issue too and I haven't settled on a good solution yet.

Here's the broken transformation:

const BrokenInput = (props) => (
  <input css={{ ...(props.hasHover && tw`block`) }} /> // < Any conditionals like `props` here will lose their reference
)

// ↓ ↓ ↓ ↓ ↓ ↓

import { styled } from "solid-styled-components";

const TwComponent = styled("input")({
  ...(props.hasHover && { "display": "block" }) // < `props` reference is lost
});

const BrokenInput = props => <TwComponent />; // < `props` isn't passed to the component

The css prop doesn't exist in solid-styled-components so twin converts the element into a styled component.
The problem is that during that process all the variables used in the conditional are severed and rather than chasing a complex solution in babel I'm looking into adding a new conversion type instead.

The new conversion for the css prop would use the css import from solid-styled-components:

const BrokenInput = (props) => (
  <input css={{ ...(props.hasHover && tw`block`) }} />
)

// ↓ ↓ ↓ ↓ ↓ ↓

import { css } from "solid-styled-components";

const BrokenInput = props => (
  <input class={css({ ...(props.hasHover && { display: "block" }) })} />
)

This option would simplify the conversion and the conditionals wouldn't be affected.

One issue is that if there's already a class on the element then a merge needs to happen - perhaps something as simple as this would work:

<input class="box" css={{ ... }} />
// ↓ ↓ ↓ ↓ ↓ ↓
<input class={"box " + css({ ... }) } />

and if css is defined before the class attribute:

<input css={{ ... }} class="box" />
// ↓ ↓ ↓ ↓ ↓ ↓
<input class={css({ ... }) + " box" } />

@ben-rogerson ben-rogerson changed the title Using conditional styles in SolidJS JSX is broken Error when passing props to the css attribute in solid/stitches Aug 19, 2023
@benash
Copy link
Author

benash commented Aug 21, 2023

Thanks for the explanation. Would Solid's classList help with that merge?

<div classList={{ ...{ [css`color: rebeccapurple;`]: true }, ...{ myClass: true, otherClass: false } }}>My text</div>

@chaozwn
Copy link

chaozwn commented Nov 2, 2023

mark. same problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants