#reactjs #material-ui
#reactjs #материал-пользовательский интерфейс
Вопрос:
Я новичок в react js material UI design. Я хочу что-то вроде приведенного ниже.
Если я нажал на первый переключатель, его значение 1 должно отображаться внутри выбранного переключателя.
Я мог реализовать только автономный переключатель, используя следующее.
import React from 'react';
import { withStyles } from '@material-ui/core/styles';
import { green } from '@material-ui/core/colors';
import Radio from '@material-ui/core/Radio';
const GreenRadio = withStyles({
root: {
color: green[400],
'amp;$checked': {
color: green[600],
},
},
checked: {},
})((props) => <Radio color="default" {...props} />);
export default function RadioButtons() {
const [selectedValue, setSelectedValue] = React.useState('a');
const handleChange = (event) => {
setSelectedValue(event.target.value);
};
return (
<div>
<Radio
checked={selectedValue === 'a'}
onChange={handleChange}
value="a"
name="radio-button-demo"
inputProps={{ 'aria-label': 'A' }}
/>
<Radio
checked={selectedValue === 'b'}
onChange={handleChange}
value="b"
name="radio-button-demo"
inputProps={{ 'aria-label': 'B' }}
/>
<GreenRadio
checked={selectedValue === 'c'}
onChange={handleChange}
value="c"
name="radio-button-demo"
inputProps={{ 'aria-label': 'C' }}
/>
<Radio
checked={selectedValue === 'd'}
onChange={handleChange}
value="d"
color="default"
name="radio-button-demo"
inputProps={{ 'aria-label': 'D' }}
/>
<Radio
checked={selectedValue === 'e'}
onChange={handleChange}
value="e"
color="default"
name="radio-button-demo"
inputProps={{ 'aria-label': 'E' }}
size="small"
/>
</div>
);
}
Как я могу получить значение внутри выбранной кнопки?
Комментарии:
1. Я не думаю, что это возможно, потому
Radio
что компонент использует input type= «radio» собственный элемент HTML. Для того, что вы хотите, вам нужно создать компонент, который действует как радио, но отображает пользовательские элементы
Ответ №1:
Это немного взлом, но комбинация css и пользовательских элементов данных делает свое дело. Во-первых, я добавил пользовательский атрибут со значением поля к нему ( data-test
у вас, очевидно, будет лучшая идея для имени, чем у меня):
<Radio
checked={selectedValue === "e"}
onChange={handleChange}
value="e"
data-test="e"
color="default"
name="radio-button-demo"
inputProps={{ "aria-label": "E" }}
size="small"
/>
Затем я использовал этот scss:
.Mui-checked {
position: relative;
.MuiSvgIcon-root .MuiSvgIcon-root {
opacity: 0;
}
amp;::after {
content: attr(data-test);
position: absolute;
top: 4px;
}
}
Mui-checked
является ли класс MaterialUI элементом, когда он проверяется. Поскольку это a span
, он может иметь псевдоэлементы. Итак, в основном я обращаюсь к пользовательскому элементу данных и устанавливаю content
для свойства его значение. .MuiSvgIcon-root.PrivateRadioButtonIcon-layer-6
является ли селектор для получения точки по умолчанию в середине checkbox
. Это скрывается.
Вам придется немного поиграть со стилями, чтобы они соответствовали вашему варианту использования, и вы можете найти демонстрацию здесь .
РЕДАКТИРОВАТЬ: вот css, я также обновил селектор, чтобы улучшить его стабильность:
.App {
font-family: sans-serif;
text-align: center;
}
.Mui-checked {
position: relative;
}
.Mui-checked::after {
content: attr(data-test);
position: absolute;
top: 4px;
}
.MuiSvgIcon-root .MuiSvgIcon-root {
opacity: 0;
}
Комментарии:
1. как я могу реализовать css в material UI design? Можете ли вы просто проверить это, codesandbox.io/s/falling-dream-qj551?file=/src/App.tsx
2. Я добавил css к своему ответу. Ваша проблема заключалась в том, что вы добавили scss в файл css. Теперь это чистый css, который вы можете скопировать туда.
3. Но если я попытаюсь вставить этот css в сам файл App.tsx, следуя шаблону пользовательского интерфейса material, он показывает, что attr не определен. codesandbox.io/s/falling-dream-qj551?file=/src/App.tsx
4. Вы добавили
data-test
свойство в радиокомпонент?5. да, я добавил это. Вы можете увидеть это по ссылке, которую я предоставил
Ответ №2:
Вот решение, которое я придумал: я создал пользовательский компонент из ButtonBase.
Он работает нормально, но менее умен, чем @Gh05d. С другой стороны, это позволяет избежать написания глобального стиля или копания во внутренних элементах Material-UI:
const useStyle = makeStyles((theme) => ({
root: {
margin: 4,
borderRadius: "50%"
},
checked: {
height: 30,
width: 30,
backgroundColor: "#0a2",
color: "#fff",
borderRadius: "50%",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontWeight: "bold"
},
notchecked: {
height: 26,
width: 26,
borderRadius: "50%",
border: "2px solid #00000066",
color: "#ffffff00"
}
}));
function MyButton(props) {
const { children, checked, ...rest } = props;
const classes = useStyle();
return (
<ButtonBase {...rest} className={classes.root}>
<div className={clsx(checked ? classes.checked : classes.notchecked)}>
{children}
</div>
</ButtonBase>
);
}
function App() {
const [selectedValue, setSelectedValue] = React.useState("a");
const handleChange = (letter) => (event) => {
setSelectedValue(letter);
};
return (
<div>
<MyButton
checked={selectedValue === "a"}
onClick={handleChange("a")}
value="a"
>
A
</MyButton>
<MyButton
checked={selectedValue === "b"}
onClick={handleChange("b")}
value="b"
>
B
</MyButton>
<MyButton
checked={selectedValue === "c"}
onClick={handleChange("c")}
value="c"
>
C
</MyButton>
</div>
);
}
Комментарии:
1. Многие пути ведут в Рим 😉