JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="app"></div>
SASS
$blue: #00aaff
$blue--dark: #0a8ccd
body
display: flex
justify-content: center
align-items: center
height: 100vh
background: $blue
.c-switch
display: inline-flex
position: relative
padding: 3px
border-radius: 50px
background: $blue--dark
&__highlight
position: absolute
top: 3px
left: 0
bottom: 3px
background: $blue
border-radius: 50px
transition: .3s
button
position: relative
padding: 0.875em 1.75em
font-weight: bold
font-size: 1rem
color: rgba(white, .6)
background: none
border-radius: 50px
border: 0
outline: none
transition: .3s
cursor: pointer
&:hover,
&:focus,
&.is-active
color: white
Babel + JSX
function Switch({ options, value, onChange }) {
const highlight = React.useRef();
React.useEffect(() => {
const activeButton = highlight.current
.closest('.c-switch')
.querySelector('.is-active') || {};
const w = activeButton.offsetWidth || 0;
const x = activeButton.offsetLeft || 0;
highlight.current.style.width = `${w}px`;
highlight.current.style.transform = `translateX(${x}px)`;
}, [ value ]);
return (
<div className="c-switch">
<div className="c-switch__highlight" ref={highlight}></div>
{options.map(n => (
<button
key={n.value}
className={n.value === value ? 'is-active' : ''}
onClick={() => onChange(n.value)}
>{n.text}</button>
))}
</div>
);
}
function App() {
const options = React.useMemo(() => [
{ value: 1, text: 'самый первый' },
{ value: 2, text: 'второй' },
{ value: 3, text: '№ 3' },
{ value: 4, text: 'последний' },
], []);
const [ selected, setSelected ] = React.useState();
return (
<div>
<Switch options={options} value={selected} onChange={setSelected} />
<div>
{options.map(n => (
<div>
<button
key={n.value}
onClick={() => setSelected(n.value)}
>выбрать "{n.text}"</button>
</div>
))}
</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('app'));