0xC0DED00D
0xC0DED00D

Reputation: 20368

Hiding child component on hover state of parent using styled-component

I have a react component like this -

const MyComponent = () => (
    <ContainerSection>
        <DeleteButtonContainer>
            <Button
                theme="plain"
                autoWidth
                onClick={() => {
                    onDeleteClick();
                }}
            >
                Delete
            </Button>
        </DeleteButtonContainer>
    </ContainerSection>
);

I want to show the DeleteButtonContainer only when the user hovers over ContainerSection. Both of them are styled-components. I couldn't find any way to do it using just css (using hover state of parent inside child), so I used something like this using state -

const MyComponent = ()=>{
    const [isHoveredState, setHoveredState] = useState<boolean>(false);
    return (<ContainerSection onMouseEnter={() => setHoveredState(true)} onMouseLeave={() => setHoveredState(false)}>
        <DeleteButtonContainer style={{ display: isHoveredState ? 'block' : 'none' }}>
            <Button
                theme="plain"
                autoWidth
                disabled={!isHoveredState}
                onClick={() => {
                    onDeleteClick();
                }}
            >
                Delete
            </Button>
        </DeleteButtonContainer>
    </ContainerSection>)
};

Now I want to always show DeleteButtonContainer when it's on mobile device since it doesn't have hover. I know I can always right more JS to achieve this, but I want to do it using CSS and if possible I want to remove state completely.

So is there a way to achieve this using just styled component and not writing custom JS?

Upvotes: 0

Views: 1773

Answers (1)

Ori Drori
Ori Drori

Reputation: 193248

You can reference one component in another, and use media queries to enable the rule for non mobile resolutions.

Hover the the golden bar to see the button, and shrink the width to disable the hover rule.

const DeleteButtonContainer = styled.div``;

const ContainerSection = styled.div`
  height: 2em;
  background: gold;
  
  @media (min-width: 640px) { // when resolution is above 640px
    &:not(:hover) ${DeleteButtonContainer} { // if DeleteButtonContainer is not under an hovered ContainerSection
      display: none;
    }
  }
`;

const Button = styled.button``;

const MyComponent = () => (
<ContainerSection>
  <DeleteButtonContainer>
    <Button>
      Delete
    </Button>
  </DeleteButtonContainer>
</ContainerSection>
);

ReactDOM.render(
  <MyComponent />,
  root
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/styled-components/4.4.0/styled-components.js"></script>

<div id="root"></div>

Upvotes: 3

Related Questions