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

Nested selectors and compiled CSS #1518

Open
yamadapc opened this issue Sep 21, 2023 · 1 comment
Open

Nested selectors and compiled CSS #1518

yamadapc opened this issue Sep 21, 2023 · 1 comment

Comments

@yamadapc
Copy link

yamadapc commented Sep 21, 2023

What is the idiomatic approach for the following types of use-cases?

Let's say I have:

<Button>
   <Icon>Icon</Icon>

   Text
</Button>

And I would want Icon to be red on hover over "Button".

This is what I'd write in CSS:

.Button:hover .Icon {
    ...
}

How would you write this with compiled?

@dddlr
Copy link
Collaborator

dddlr commented Sep 21, 2023

Hmm that's a good question - we recommend using JS to detect the hover on Button and store this in a variable, and then pass the variable value as a prop to the Icon.

To give some reasons for why we suggest this: this is a performance compromise 😅, since even though using JS (as opposed to a pure CSS solution) does incur an extra cost...

  • Having complex selectors unnecessarily increases the css stylesheet size (works against our "atomic CSS" approach)
  • Nested selectors (e.g. .Button:hover .Icon) are not as efficient as simple selectors
  • For most components, JS will be already running something else anyway (e.g. logging)
  • Using JS allows for more flexible use cases (even when two elements are not nested in the DOM)

I made a quick React example below - I'm not the best with React so the onMouseEnter/onMouseLeave could probably be optimised a bit:

const Button = styled.div({ fontSize: '25px' });
const Icon = styled.div({
    color: (prop) => prop.isHover ? 'red' : 'black',
});

const Component = () => {
  const [isHover, setIsHover] = React.useState(false);
  return <>
    <Button onMouseEnter={() => setIsHover(true)} onMouseLeave={() => setIsHover(false)}>
      <Icon isHover={isHover}>hello world</Icon>
    </Button>
  </>;
}

If you're doing something inside JFE, we recommend asking DST to see if there's any atlaskit primitives or packages suitable for the kind of button that you're creating (or migrating)

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