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

dynamic css property name can't generate expected css #20

Closed
await-ovo opened this issue Oct 27, 2023 · 6 comments
Closed

dynamic css property name can't generate expected css #20

await-ovo opened this issue Oct 27, 2023 · 6 comments

Comments

@await-ovo
Copy link

await-ovo commented Oct 27, 2023

Let's say we have a styled component like following:

const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: #BF4F74;
  ${'height'}: 40px;
`;

it seems that it will generate css uncorrectly:

.page_yak_0__p1crE {
    font-size: 1.5em;
    text-align: center;
    color: #BF4F74;
}

.page_yak_0__p1crE {
    : 40px; }

I'm not sure if this usage is supported(It's true that this usage should be relatively rare), in styled-components it's ok

@jantimon
Copy link
Owner

jantimon commented Oct 27, 2023

hey @await-ovo

thanks for your feedback!

right now dynamic property values are using css variables under the hood.

so for example

const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: #BF4F74;
  height: ${someValue}
`;

is compiled to the following static css:

.generated-class-name {
  font-size: 1.5em;
  text-align: center;
  color: #BF4F74;
  height: var(--some-value);
}

Unfortunately css does allows dynamic properties only for values but not for names.
Therefore such a feature is also for next-yak very hard to achieve.

So for now the only work around is:

const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: #BF4F74;
  ${property === "height" ? css`height: 40px` : css`width: 40px`}
`;

@jantimon
Copy link
Owner

jantimon commented Nov 7, 2023

@await-ovo we might add a way to allow this feature - could you please give a more realistic example? :)

@await-ovo
Copy link
Author

Sorry, I don't have a real use case for this at the moment, I was just curious if next-yak could support this pattern.

But I do have a real use case that may not be related to the above ( whick is called component selector in styled components.):

onst Link = styled.a`
  display: flex;
  align-items: center;
  padding: 5px 10px;
  background: papayawhip;
  color: #BF4F74;
`;

const Icon = styled.svg`
  flex: none;
  transition: fill 0.25s;
  width: 48px;
  height: 48px;

  ${Link}:hover & {
    fill: rebeccapurple;
  }
`;

const Label = styled.span`
  display: flex;
  align-items: center;
  line-height: 1.2;

  &::before {
    content: '◀';
    margin: 0 10px;
  }
`;

render(
  <Link href="#">
    <Icon viewBox="0 0 20 20">
      <path d="M10 15h8c1 0 2-1 2-2V3c0-1-1-2-2-2H2C1 1 0 2 0 3v10c0 1 1 2 2 2h4v4l4-4zM5 7h2v2H5V7zm4 0h2v2H9V7zm4 0h2v2h-2V7z"/>
    </Icon>
    <Label>Hovering my parent changes my style!</Label>
  </Link>
);

@jantimon
Copy link
Owner

jantimon commented Nov 20, 2023

apologies for the delay in getting back to you!

first off, thanks for bringing up a real use case :)

one approach you can consider is using unique identifiers or class names for your components and then targeting them in your yak styles. panda actually recommends this way

however, we understand that this might not be the most developer-friendly experience. in fact, we weren't completely satisfied with this approach, so we ventured into finding an alternative solution

good news: we managed to allow targeting components inside the same file - see pr #33.
this enhancement will enable you to write code exactly like the example you provided

cross-file targeting is a bit trickier due to module resolution, side effects, and barrel files so we excluded it (at least for now).
but there is a workaround which helps to solve at least some cases:

import { Link } from "./some/other/file";

const CustomLink = styled(Link)``;

const Icon = styled.svg`
  flex: none;
  transition: fill 0.25s;
  width: 48px;
  height: 48px;

  ${CustomLink}:hover & {
    fill: rebeccapurple;
  }
`;

export const Demo = () => (
  <CustomLink>
    <Icon />
  </CustomLink>
);

if you have more questions or if there's anything else we can help you with let us know :)

@await-ovo
Copy link
Author

Thank you for such a detailed response, this looks fantastic!

@jantimon
Copy link
Owner

Released with next-yak 0.0.17

https://stackblitz.com/edit/stackblitz-starters-m1vwbv?file=app%2FLogo.tsx
shot-lC1UZOXb

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

No branches or pull requests

2 participants