fix: mode not display correctly due to clash API change

for https://github.com/haishanh/yacd/issues/491
This commit is contained in:
Haishan 2020-06-07 18:15:07 +08:00
parent 201f6904c2
commit e864feb401
3 changed files with 56 additions and 34 deletions

View file

@ -27,15 +27,15 @@ const propsList = [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }];
const optionsRule = [
{
label: 'Global',
value: 'Global',
value: 'global',
},
{
label: 'Rule',
value: 'Rule',
value: 'rule',
},
{
label: 'Direct',
value: 'Direct',
value: 'direct',
},
];
@ -220,7 +220,7 @@ function ConfigImpl({
<ToggleSwitch
options={optionsRule}
name="mode"
value={configState.mode}
value={configState.mode && configState.mode.toLowerCase()}
onChange={handleInputOnChange}
/>
</div>

View file

@ -1,4 +1,4 @@
import React, { useMemo } from 'react';
import React, { useMemo, useCallback } from 'react';
import PropTypes from 'prop-types';
import s0 from './ToggleSwitch.module.css';
@ -8,35 +8,53 @@ function ToggleSwitch({ options, value, name, onChange }) {
() => options.map((o) => o.value).indexOf(value),
[options, value]
);
const w = (100 / options.length).toPrecision(3);
const getPortionPercentage = useCallback(
(idx) => {
const w = Math.floor(100 / options.length);
if (idx === options.length - 1) {
return 100 - options.length * w + w;
} else if (idx > -1) {
return w;
}
},
[options]
);
const sliderStyle = useMemo(() => {
return {
width: getPortionPercentage(idxSelected) + '%',
left: idxSelected * getPortionPercentage(0) + '%',
};
}, [idxSelected, getPortionPercentage]);
return (
<div>
<div className={s0.ToggleSwitch}>
<div
className={s0.slider}
style={{
width: w + '%',
left: idxSelected * w + '%',
}}
/>
{options.map((o, idx) => {
const id = `${name}-${o.label}`;
const className = idx === 0 ? '' : 'border-left';
return (
<label htmlFor={id} key={id} className={className}>
<input
id={id}
name={name}
type="radio"
value={o.value}
checked={value === o.value}
onChange={onChange}
/>
<div>{o.label}</div>
</label>
);
})}
</div>
<div className={s0.ToggleSwitch}>
<div className={s0.slider} style={sliderStyle} />
{options.map((o, idx) => {
const id = `${name}-${o.label}`;
const className = idx === 0 ? '' : 'border-left';
return (
<label
htmlFor={id}
key={id}
className={className}
style={{
width: getPortionPercentage(idx) + '%',
}}
>
<input
id={id}
name={name}
type="radio"
value={o.value}
checked={value === o.value}
onChange={onChange}
/>
<div>{o.label}</div>
</label>
);
})}
</div>
);
}

View file

@ -5,6 +5,11 @@
background: var(--color-toggle-bg);
display: flex;
position: relative;
outline: none;
&:focus {
border-color: var(--color-focus-blue);
}
input {
position: absolute;
@ -13,7 +18,6 @@
}
label {
flex: 1;
z-index: 2;
display: flex;
align-items: center;