stitches icon indicating copy to clipboard operation
stitches copied to clipboard

Nested locally scoped variables overridden by child component

Open rafaelderolez opened this issue 2 years ago • 2 comments

Bug report

Describe the bug

When nesting 2 Stitches components that use the same locally scoped variable, the child component will override the locally scoped variable's value. I understand why it happens, but I'm wondering if anything can be done so the local variables are unique between components so they don't clash with each other.

To Reproduce

Forked from stitches-stack-demo, I've set up the following Stack layout (live version here):

<Stack direction="column" css={{ stackGap: "$4" }}>
  <PlaceHolder>Row 1</PlaceHolder>
  <Stack direction="row" css={{ stackGap: "$12" }}>
    <PlaceHolder>Row 2 A</PlaceHolder>
    <PlaceHolder>Row 2 B</PlaceHolder>
    <PlaceHolder>Row 2 C</PlaceHolder>
  </Stack>
  <PlaceHolder>Row 3</PlaceHolder>
  <PlaceHolder>Row 4</PlaceHolder>
</Stack>
image

Expected behavior

I would expect the spacing between Row 1 and Row 2 to be $4, and the spacing between Row 2A, 2B, and 2C to be $12

image

System information

  • OS: macOS
  • Browser (if applies): Brave
  • Version of Stitches: 1.1.0
  • Version of Node.js: 10.20.1 LTS (according to CodeSandBox faq)

rafaelderolez avatar Jun 05 '22 09:06 rafaelderolez

There isn't a way to create unique locally scoped variables every time a component is rendered. For your use case, looks like it would be solved if you update your gap util to apply the token to children of the stack component:

export const stackGap = (value: ScaleValue<"space">) => ({
// apply the gap to children of the component
  "> *": {
    $$gap: `$space${value}`
  }
});

Which renders: Screen Shot 2022-06-06 at 6 25 52 PM

hadihallak avatar Jun 06 '22 14:06 hadihallak

Thanks for that @hadihallak!

I changed it up a bit to maintain the responsiveness. (See below) This allows me to do gap={{"@initial": 8, "@bp3": 4}} which I think isn't really possible with the stackGap utility, right?

const childWithVariable = "> *"

export const Stack = styled("div", {
    display: "flex",
    $$gap: "initial",
    variants: {
        gap: {
            4: {
                [childWithVariable]: {
                    $$gap: "$space$4",
                },
            },
            8: {
                [childWithVariable]: {
                    $$gap: "$space$8",
                },
            },
....

rafaelderolez avatar Jun 06 '22 17:06 rafaelderolez