DEV Community

taiseen
taiseen

Posted on • Edited on

radio toggle button in react

this small component consist by data, jsx & css...

Data:-

// data.js

import girl from '../assets/girl.webp';
import boy from '../assets/boy.webp';

export const gender = [
    {
        data: "Boy",
        icon: boy,
    },
    {
        data: "Girl",
        icon: girl,
    }
]
Enter fullscreen mode Exit fullscreen mode

Jsx:-

// App.jsx

import { gender } from './constants/data';
import { useState } from 'react';

const App = () => {

  const [switchToggle, setSwitchToggle] = useState(true);

  const handleClick = (data) => {
    setSwitchToggle(pre => !pre);
    console.log(data);
  }

  return (
    <div className="radioBtnContainer">
      {
        gender.map(({ data, icon }) => (
          <label htmlFor={data} >
            <input
              id={data}
              type="radio"
              value={data}
              name="value"
              onChange={() => handleClick(data)}
            />
            <img src={icon} alt={data} /> {data}
          </label>
        ))
      }
      <span 
        className={`switch ${switchToggle ? 'activeSwitch' : ''}`}
      >
      </span>
    </div>
  )
}

export default App;
Enter fullscreen mode Exit fullscreen mode

CSS:-

/* style.css */

* {
    margin : 0;
    padding: 0;
}

body {
    width          : 100%;
    height         : 100vh;
    display        : flex;
    align-items    : center;
    justify-content: center;
}

.radioBtnContainer{
    background-color: white;
    width           : 500px;
    display         : flex;
    align-items     : center;
    border-radius   : 25px;
    border          : 1px solid skyblue;
    position        : relative;
}

label {
    cursor       : pointer;
    display      : flex;
    align-items  : center;
    width        : 50%;
    height       : 30px;
    border-radius: 25px;
    position     : relative;
    z-index      : 1;
}

.switch {
    position        : absolute;
    top             : 0;
    left            : 0;
    bottom          : 0;
    background-color: rgb(194, 222, 255, .5);
    border          : 1px solid skyblue;
    width           : 50%;
    border-radius   : 25px;
    transition      : left .3s;
}

.activeSwitch {
    left: 50%;
}

input {
    margin    : 0 8px;
    appearance: none;
    outline   : none;
}

img {
    margin-right: 10px;
    width       : 16px;
}
Enter fullscreen mode Exit fullscreen mode

Top comments (4)

Collapse
 
corners2wall profile image
Corners 2 Wall

Keep going, don't give up, dude. You can improve your code if you want this.

Collapse
 
taiseen profile image
taiseen

"You can improve your code if you want this"... yes sure... I love to learn from you... if you can help me to improve this code block... & Thank for so much for your feedback... 💖

Collapse
 
corners2wall profile image
Corners 2 Wall • Edited

I can't describe my view correctly but:

  1. use key prop for list item;
  2. pass function prop instead of () => {};
  3. don't use tag in your css files, you can avoid this in most case; 4.use reset css for this appearance: none; Your solution not bad, but what do you do if customer want add more gender? I understand than sound crazy, but your logic with handle option will broken :(

I rewrite your solution, if you want you can check this

Thread Thread
 
taiseen profile image
taiseen

Thank you so much 🤗 for your improved code suggestions, I really loved to learn from you this new approach. Thank you again for your effort. 💖