0

I have put together a radio select component with React Hooks that toggles between two options which works. How do I add a class to the outlining box when the radio button is selected? I want the background to change from white to grey. I'm using styled components and tried to do this using only CSS but wasn't successful. How can I use hooks to accomplish this? Working sample here: https://codesandbox.io/embed/react-styled-components-radio-button-qpxul?fontsize=14

const { useState } = React;

const App = () => {
  const [select, setSelect] = useState("optionA");

  const handleSelectChange = event => {
    const value = event.target.value;
    setSelect(value);
  };
  return (
    <Wrapper>
      <Item>
        <RadioButton
          type="radio"
          name="radio"
          value="optionA"
          checked={select === "optionA"}
          onChange={event => handleSelectChange(event)}
        />
        <RadioButtonLabel />
        <div>Choose Pickup</div>
      </Item>
      <Item>
        <RadioButton
          type="radio"
          name="radio"
          value="optionB"
          checked={select === "optionB"}
          onChange={event => handleSelectChange(event)}
        />
        <RadioButtonLabel />
        <div>Choose Delivery</div>
      </Item>
    </Wrapper>
  );
};

const Wrapper = styled.div`
  height: auto;
  width: 100%;
  padding: 0px 16px 24px 16px;
  box-sizing: border-box;
`;

const Item = styled.div`
  display: flex;
  align-items: center;
  height: 48px;
  position: relative;
  border: 1px solid #ccc;
  box-sizing: border-box;
  border-radius: 2px;
  margin-bottom: 10px;
`;

const RadioButtonLabel = styled.label`
  position: absolute;
  top: 25%;
  left: 4px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: white;
  border: 1px solid #ccc;
`;
const RadioButton = styled.input`
  opacity: 0;
  z-index: 1;
  cursor: pointer;
  width: 25px;
  height: 25px;
  margin-right: 10px;
  &:hover ~ ${RadioButtonLabel} {
    background: #ccc;
    &::after {
      content: "\f005";
      font-family: "FontAwesome";
      display: block;
      color: white;
      width: 12px;
      height: 12px;
      margin: 4px;
    }
  }
  &:checked + ${Item} {
    background: yellowgreen;
    border: 2px solid yellowgreen;
  }
  &:checked + ${RadioButtonLabel} {
    background: yellowgreen;
    border: 1px solid yellowgreen;
    &::after {
      content: "\f005";
      font-family: "FontAwesome";
      display: block;
      color: white;
      width: 12px;
      height: 12px;
      margin: 4px;
    }
  }
`;

1 Answer 1

2

In CSS there is no parent selector so you cannot target a parent element from the checkbox.

But you can either add a class based on the selected state of the radio

<Item className={select === "optionA" ? 'active-radio' : null}>

or if you want to do it through styled components you could use

<Item active={select === "optionA"}>

combined with

const Item = styled.div`
  display: flex;
  align-items: center;
  height: 48px;
  position: relative;
  border: 1px solid #ccc;
  box-sizing: border-box;
  border-radius: 2px;
  margin-bottom: 10px;
  ${props => props.active && (`
    box-shadow: 0 0 10px -4px black;
  `)}
`;

Demo at https://codesandbox.io/s/react-styled-components-radio-button-f5zpe

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.