swordev / suid

A port of Material-UI (MUI) built with SolidJS.
https://suid.io
MIT License
676 stars 48 forks source link

Using styled components and descendant Selectors #176

Closed Bersaelor closed 1 year ago

Bersaelor commented 1 year ago

Following is the simpified situation:

const Child = styled('div')(({ theme }) => ({
  color: 'red',
}))

const Parent = styled('div')(({ theme }) => ({
  [`& ${Child}`]: {
    color: 'blue',
  }
}))

to layout

  return (<>
    <Child>
      This text should be red
    </Child>
    <Parent>
      <Child>This text should be blue</Child>
    </Parent>
  </>
  )

Unfortunately both texts are red.

How can I select a descendant?

PS: My real goal is to make a descendant appear when the main div is hovered, i.e.:

const Child = styled('div')(({ theme }) => ({
  opacity: 0,
}))

const Parent = styled('div')(({ theme }) => ({
  [`&:hover ${Child}`]: {
    opacity: 1,
  }
}))

but the colors also didn't work.

Bersaelor commented 1 year ago

I mean, we can always use static classnames like so:

const Parent = styled('div')(({ theme }) => ({
 //... 
  '& .child': {
    color: 'blue',
  }
}))

and

    <Parent>
      <Child class='child>This text should be blue</Child>
    </Parent>

but that's so unelegant and adds extra verbosity

juanrgm commented 1 year ago

The code works correctly, what is the problem?

https://stackblitz.com/edit/angular-ivi8jv?file=src%2FApp.tsx

import { styled } from '@suid/material/styles';

const Child = styled('div')(({ theme }) => ({
  color: 'red',
}));

const Parent = styled('div')(({ theme }) => ({
  [`& ${Child}`]: {
    color: 'blue',
  },
}));

export default function Example() {
  return (
    <>
      <Child>This text should be red</Child>
      <Parent>
        <Child>This text should be blue</Child>
      </Parent>
    </>
  );
}
Bersaelor commented 1 year ago

I tried it for hours and it didn't work, thank you for creating the stackblitz.com so I can safe my sanity.

I only ever tried this as a sub-component in the hierarchy of our solid app, not as a standalone app. And if I just plug the above code in anywhere, I get both texts as red.

I'm wondering whether I am importing it wrong, in our code we're doing

import styled from "@suid/system/styled";

which I copy+pasted from the suid docs.

In your answer you wrote:

import { styled } from '@suid/material/styles';

If I try the latter I always get

Module '"@suid/material/styles"' has no exported member 'styled'.

For reference, here is my package.json:

  "dependencies": {
    "@solid-primitives/script-loader": "^1.1.3",
    "@solidjs/meta": "^0.28.2",
    "@solidjs/router": "^0.6.0",
    "@suid/icons-material": "^0.5.8",
    "@suid/material": "^0.8.2",
    "@suid/styled-engine": "^0.4.1",
    "@suid/vite-plugin": "^0.1.0",
    "aws-amplify": "^5.0.8",
    "solid-js": "^1.6.6",
    "solid-transition-group": "^0.0.12"
  }
}
Bersaelor commented 1 year ago

Alright, the reason was that I was still on "@suid/material": "^0.8.2", after upgrading to "@suid/material": "^0.10.1" it works now :)