How can I add Adornment inside MUI InputBase? - reactjs

I am trying to place MUI Adornment inside of MUI InputBase, but so far I can only get it to render outside of the input:
<InputField
id={id}
ref={ref}
error={error}
type={type}
multiline={multiline}
minRows={minRows}
inputProps={inputProps}
endAdornment={
<InputAdornment position="end">adornment</InputAdornment>
}
{...props}
/>
https://codesandbox.io/s/ecstatic-pond-yvi19?file=/src/CustomTextField.js:1320-1956

Just move below styles to InputContainer instead of InputField:
box-shadow: 0 1px 2px 0 rgba(184, 200, 224, 0.22);
border: 1px solid
${(props) => (props.error ? props.theme.palette.error.dark : "#d8e0f0")};
border-radius: 14px;
So, based on mentioned description, you have:
export const InputField = styled(InputBase)`
& > .MuiInputBase-input {
font-family: Raleway;
padding: 10px 16px;
}
`;
export const InputContainer = styled("div")`
display: flex;
flex-direction: column;
box-shadow: 0 1px 2px 0 rgba(184, 200, 224, 0.22);
border: 1px solid
${(props) => (props.error ? props.theme.palette.error.dark : "#d8e0f0")};
border-radius: 14px;
`;

`const useStyles = makeStyles((theme) => ({
inputfield: {
"& .MuiInputBase-root": {
borderRadius: 4,
backgroundColor: "#FCFCFC",
border: "1px solid #D4DEF5",
fontSize: 16,
padding: "10px 12px",
boxSizing: "border-box",
width: 280,
height: 35,
"&:hover": {
borderColor: "#1565c0",
},
},
"&.Mui-focused": {
boxShadow: `${alpha(theme.palette.primary.main, 0.25)} 0 0 0 0.2rem`,
borderColor: theme.palette.primary.main,
},
},
}));
<div className={classes.inputfield}>
<InputBase
startAdornment={
<InputAdornment position="start">
<CalendarIcon />
</InputAdornment>
}
/>
</div>`
style to MuiInputBase-root not MuiInputBase-input

Related

How to add a label to a border in mui?

I would like to have a list wrapped in a border which looks and behaves the same as a textfield border:
Example textfield and list which should have both same border.
In the image, the border around the list looks similar than the one around the textfield but most notably, the label is missing. How can I add the label and how would I set up the focus listeners to get the same hover and selection behaviour?
The typescript code for the list:
<List dense sx={{ borderRadius: 1, border: 1, borderColor: 'grey.600'}}>
<ListItem secondaryAction={<IconButton edge="end" aria-label="delete"><DeleteIcon /></IconButton>}>
<ListItemText primary="primary" secondary="group id"/>
</ListItem>
</List>
I am also open for alternative approaches. Thanks for the help.
Here is my answer using React and Mui (only for icon).
It relies on flex.
We have a main container that only draws its left, bottom and right borders.
Then we have a header container in charge of drawing the top border in two parts (before and after) and a section with an icon and title.
You can either pass an icon and a title, just a title, just an icon, or nothing at all.
borderedSection.js:
import React from "react";
import SvgIcon from "#mui/material/SvgIcon";
import styles from "./borderedSection.module.scss";
function BorderedSection({ icon, title, children }) {
return (
<div className={styles.mainContainer}>
<div className={styles.header}>
<div className={styles.headerBorderBefore}></div>
{(icon || title) && (
<div className={styles.headerTitle}>
{icon && <SvgIcon component={icon} />}
{title && <span className={styles.title}>{title}</span>}
</div>
)}
<div className={styles.headerBorderAfter}></div>
</div>
<div className={styles.childrenContainer}>{children}</div>
</div>
);
}
export default BorderedSection;
borderedSection.module.scss:
$border-color: #b2b2b2;
.mainContainer {
display: flex;
flex-direction: column;
max-width: 100%;
border-left: 1px solid $border-color;
border-bottom: 1px solid $border-color;
border-right: 1px solid $border-color;
border-radius: 5px;
margin: 1em;
.childrenContainer {
padding: 1em;
}
.header {
display: flex;
flex-direction: row;
width: 100% !important;
.headerBorderBefore {
border-top: 1px solid $border-color;
width: 1em;
border-top-left-radius: 5px;
}
.headerTitle {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
gap: 0.25em;
width: fit-content;
height: 2em;
margin: -1em 0.5em 0em 0.5em;
overflow: hidden;
text-overflow: ellipsis;
font-size: 1em;
font-weight: 600;
}
.headerBorderAfter {
border-top: 1px solid $border-color;
width: 1em;
flex-grow: 2;
border-top-right-radius: 5px;
}
}
}
usage:
import React from "react";
import BorderedSection from "./borderedSection";
import InfoIcon from "#mui/icons-material/Info";
function Example() {
return (
<div style={{ padding: "2em" }}>
<BorderedSection icon={InfoIcon} title="Icon and title">
<div>a first child with quite a long text</div>
<div>a second child</div>
</BorderedSection>
<BorderedSection title="Title only">
<div>a first child with quite a long text</div>
<div>a second child</div>
</BorderedSection>
<BorderedSection icon={InfoIcon} >
<div>Icon only</div>
<div>a second child with quite a long text</div>
</BorderedSection>
<BorderedSection >
<div>No icon and no title</div>
<div>a second child with quite a long text</div>
</BorderedSection>
</div>
);
}
Here is how it looks:
I hope it helps
I now managed to hack a solution which looks the same. I do still hope though that there is a clean way to do this: result.
<FormLabel style={{marginLeft: "0.71em", marginTop: "-0.71em", paddingLeft: "0.44em", zIndex: 2, width: "4.2em", backgroundColor: "#383838", position: "absolute", fontSize: "0.75em"}}>Damage</FormLabel>
<List dense sx={{ borderRadius: 1, border: 1, borderColor: 'grey.600', "&:hover": { borderColor: 'grey.200' }}}>
<ListItem secondaryAction={<IconButton edge="end" aria-label="delete"><DeleteIcon /></IconButton>}>
<ListItemText primary="primary" secondary="group id"/>
</ListItem>
</List>
I needed the same thing. As I was poking around I noticed that MUI accomplished this by using the fieldset tag. I created a quick and dirty component (OutlinedBox) to get this effect:
import React from "react";
import {Box, FormLabel} from "#mui/material";
const OutlinedBox = (props) => {
const {
label,
children
} = props;
return (
<Box>
<FormLabel
sx={{
marginLeft: "0.71em",
marginTop: "-0.71em",
paddingLeft: "0.44em",
paddingRight: '0.44em',
zIndex: 2,
backgroundColor: (theme) => theme.palette.background.default,
position: "absolute",
fontSize: "0.75em",
width: 'auto',
}}>{label}</FormLabel>
<Box
sx={{
position: 'relative',
borderRadius: theme => theme.shape.borderRadius + 'px',
fontSize: '0.875rem',
}}
>
<Box
sx={{
padding: (theme) => theme.spacing(1),
display: 'flex',
gap: (theme) => theme.spacing(1),
flexWrap: 'wrap',
overflow: 'auto'
}}
>
{children}
</Box>
<fieldset aria-hidden={"true"} style={{
textAlign: 'left',
position: 'absolute',
bottom: 0,
right: 0,
top: '-5px',
left: 0,
margin: 0,
padding: '0 8px',
pointerEvents: 'none',
borderRadius: 'inherit',
borderStyle: 'solid',
borderWidth: '1px',
overflow: 'hidden',
minWidth: '0%',
borderColor: 'rgba(255, 255, 255, 0.23)',
}}
>
<legend style={{
float: 'unset',
overflow: 'hidden',
display: 'block',
width: 'auto',
padding: 0,
height: '11px',
fontSize: '0.75em',
visibility: 'hidden',
maxWidth: '100%',
'-webkit-transition': 'max-width 100ms cubic-bezier(0.0, 0, 0.2, 1) 50ms',
transition: 'max-width 100ms cubic-bezier(0.0, 0, 0.2, 1) 50ms',
whiteSpace: 'nowrap',
}}><span>{label}</span></legend>
</fieldset>
</Box>
</Box>
);
}
export { OutlinedBox };
// Example usage: <OutlinedBox label="Test">Some content here</OutlinedBox>
I figured I'd post it here in case anyone needs the same thing and comes across this question. All the styling stuff was copied from the styles MUI was using. There may be a better way to read some of this off of the theme, so if anyone decides to use this you may want to tweak it some.

Odd containers appearing when I click on any element on my page. React/SCSS/React-Hook-Form

I just implemented a simple login form. Whenever I click on any of the elements on the form, there is a weird unidentified container appearing in the background. It's odd because it seems to have the same glassmorphism effect as my login container. But the unidentified container size is just random and varies depending on what element I am clicking on.
I am using React with SCSS and using React-Hook-Forms for the login.
Login.jsx
const LoginForm = ({ login }) => {
const [focused, setfocused] = useState("");
const { register, handleSubmit } = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<h1>Login</h1>
<motion.input
className="text-input"
name="email"
placeholder="Email"
ref={register}
></motion.input>
<motion.input
className="text-input"
name="password"
type="password"
placeholder="Password"
ref={register}
></motion.input>
<motion.input className="submit-button" type="submit" value="Login" />
<h3>
New student?{" "}
<Link className="register-link" to="/register">
Register here!
</Link>
</h3>
</form>
);
};
export default LoginForm;
form {
#include flex(flex-start, center, column);
height: auto;
min-width: 450px;
padding: 100px 50px;
background: rgba(255, 255, 255, 0.25);
box-shadow: 0 8px 32px 0 rgba(218, 216, 216, 0.37);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.15);
h1 {
#include primary-font($headerSize, $headerWeight);
color: $faintWhite;
margin-bottom: 30px;
&:after {
content: "";
display: block;
margin: auto;
height: 5px;
width: 100%;
background: $faintWhite;
border-radius: 10px;
}
}
.text-input {
padding: 10px 15px;
margin-bottom: 20px;
width: 100%;
color: $faintWhite;
#include primary-font(1rem, 500);
background: rgba(255, 255, 255, 0.25);
box-shadow: 0 8px 32px 0 rgba(218, 216, 216, 0.37);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.15);
&::placeholder {
color: $faintWhite;
#include primary-font(1rem, 500);
}
}
.submit-button {
#include primary-font(1.4rem, 600);
color: #505050;
padding: 10px 30px;
border-radius: 30px;
margin: 5px 0 30px 0;
cursor: pointer;
background: white;
box-shadow: 0 5px 32px 0 rgba(255, 255, 255, 0.5);
border: none;
}
h3 {
#include primary-font(1rem, 500);
color: $faintWhite;
.register-link {
#include primary-font(1rem, 600);
color: $faintWhite;
}
}
}
Above is SCSS
Eliminating backdrop-filter solved the issue.
"The backdrop-filter CSS property lets you apply graphical effects such as blurring or color shifting to the area behind an element."
I suppose this had something to do with the issue.

Cleaner/better way to add props to a styled JSS object/component [Material UI, React, JSS]

Is there a "cleaner" way to add props to a styled() object in Material UI? IMO the formatting/syntax is not very elegant especially with typescript. The Material UI docs gives the following example for adding props:
(Javascript)
const MyButton = styled(({ color, ...other }) => <Button {...other} />)({
background: (props) =>
props.color === 'red'
? 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)'
: 'linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)',
border: 0,
borderRadius: 3,
boxShadow: (props) =>
props.color === 'red'
? '0 3px 5px 2px rgba(255, 105, 135, .3)'
: '0 3px 5px 2px rgba(33, 203, 243, .3)',
color: 'white',
height: 48,
padding: '0 30px',
margin: 8,
});
(Typescript)
interface MyButtonProps {
color: 'red' | 'blue';
}
const MyButton = styled(
({ color, ...other }: MyButtonProps & Omit<ButtonProps, keyof MyButtonProps>) => (
<Button {...other} />
),
)({
background: (props: MyButtonProps) =>
props.color === 'red'
? 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)'
: 'linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)',
border: 0,
borderRadius: 3,
boxShadow: (props: MyButtonProps) =>
props.color === 'red'
? '0 3px 5px 2px rgba(255, 105, 135, .3)'
: '0 3px 5px 2px rgba(33, 203, 243, .3)',
color: 'white',
height: 48,
padding: '0 30px',
margin: 8,
});
Is there a way to write it like:
(Typescript)
const MyButton = styled(
(props: {
color: string,
}) => (
<div />
),
)(props => ({
background: props.color === 'red' ? 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)' : 'linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)',
border: 0,
borderRadius: 3,
boxShadow: props.color === 'red' ? '0 3px 5px 2px rgba(255, 105, 135, .3)' : '0 3px 5px 2px rgba(33, 203, 243, .3)',
color: 'white',
height: 48,
padding: '0 30px',
margin: 8,
}));
The "proposed syntax" that I'm giving doesn't reuse the MyButtonProps interface multiple times and the props object is passed into the whole object (similar to the way a "theme" object would get passed in).

Transform function not working in styled components

I am trying to change the styled of "IconRadioButtonRound" component based on the "HiddenCheckBox" value.I am able to change the bakcground of "IconRadioButtonRound" with same prop i.e."checked" but not able to transform it. Please help me solve this!
Styled components:
export const HiddenCheckbox = styled.input.attrs({ type: 'checkbox' })`
transform: scale(8);
position: relative;
top: 40px;
left: 20px;
opacity: 0;
`;
export const IconRadioButtonRound = styled.button`
width: 63px;
height: 62px;
display: flex;
flex-direction: column;
justify-content: space-between;
border: ${props =>
props.checked ? '4px solid #daa520' : '1px solid #daa520'};
box-sizing: border-box;
border-radius: 50%;
transition: transform 500ms linear;
background: ${props => (props.checked ? 'rgba(66, 226, 248, 0.3)' : 'white')};
transform: translateY(${props => (props.checked ? '-15px' : '0')});
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
`;
Component where I am using it
<IconCheckBoxRoundButton>
<HiddenCheckbox
key={index}
name={item.itemName}
value={item.itemName}
onChange={e => handleAddOnItemChange(e)}
/>
<IconCheckBoxRound checked={item.isChecked}>
<CheckBoxIcon src={item.itemIconURL} />
</IconCheckBoxRound>
<InputLabel
for={item.itemName}
style={{ marginTop: '15px' }}
lineHeight="18px"
>
<CheckBoxIconName>
<PTSansText fontSize="18px" lineHeight="18px">
{item.itemName}
</PTSansText>
</CheckBoxIconName>
<CheckBoxIconName>
<PTSansText fontSize="16px">
<span>Rs. </span>
{item.itemPrice}
</PTSansText>
</CheckBoxIconName>
</InputLabel>
</IconCheckBoxRoundButton>

Material-UI <Radio /> with a <Button />-like appearance

Using only Material-UI, is there any way to style <Radio /> objects with a <Button /> type of appearance? If not, what would be the most simple alternative?
After spending the past few days reading documentation and experimenting, I don't feel any closer to a solution. Thanks to anyone who can lend some guidance.
Here's my starting point (without the <Button /> experiments) in case anyone would like to use what I'm working with:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import RadioGroup from '#material-ui/core/RadioGroup';
import Radio from '#material-ui/core/Radio';
import Button from '#material-ui/core/Button';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import FormControl from '#material-ui/core/FormControl';
const styles = theme => ({
textField: {
marginLeft: theme.spacing.unit,
marginRight: theme.spacing.unit,
width: '100%',
},
formControl: {
display: 'flex',
flexBasis: '100%',
alignItems: 'center',
}
});
class QRadios extends React.PureComponent {
constructor(props, context) {
super(props, context);
this.state = {
value: this.props.value,
};
}
handleChange = event => {
this.setState({
value: event.target.value,
},
this.props.onChange(event));
};
render() {
const { classes } = this.props;
return (
<FormControl component="ul" className={classes.formControl} required>
<RadioGroup
row={true}
id={this.props.id}
name={this.props.name}
value={this.state.value}
onChange={this.handleChange}
>
<FormControlLabel
htmlFor={this.props.id}
value="good"
control={<Radio />}
/>
<FormControlLabel
htmlFor={this.props.id}
value="okay"
control={<Radio />}
/>
<FormControlLabel
htmlFor={this.props.id}
value="bad"
control={<Radio />}
/>
<FormControlLabel
htmlFor={this.props.id}
value="na"
control={<Radio />}
/>
</RadioGroup>
</FormControl>
);
}
}
QRadios.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(QRadios);
Update:
For anyone who is using an older version of Material-UI that lacks the built-in solution as per the answer below, you'll have to create your own CSS for the buttons. If you need help, this is how I implemented it:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import green from '#material-ui/core/colors/green';
import yellow from '#material-ui/core/colors/yellow';
import red from '#material-ui/core/colors/red';
import grey from '#material-ui/core/colors/grey';
import RadioGroup from '#material-ui/core/RadioGroup';
import Radio from '#material-ui/core/Radio';
import FormControl from '#material-ui/core/FormControl';
import InputLabel from '#material-ui/core/InputLabel';
const styles = theme => ({
formControl: {
display: 'flex',
flexBasis: '100%',
alignItems: 'stretch',
margin: theme.spacing.unit * 3 / 2
},
formGroup: {
alignItems: 'stretch',
justifyContent: 'space-around',
flexWrap: 'nowrap'
},
radioFlex: {
flex: '1 1 auto',
margin: '0 5px'
},
greenButtonRoot: {
backgroundColor: '#00000004',
borderRadius: 5,
border: '1px solid',
color: green.A700,
fontFamily: 'monospace',
fontSize: '180%',
height: 32,
'&$checked': {
backgroundColor: green.A700,
color: 'white'
},
'&:not($checked):hover': {
backgroundColor: green['50']
},
transition: 'background-color 250ms'
},
yellowButtonRoot: {
backgroundColor: '#00000004',
borderRadius: 5,
border: '1px solid',
color: yellow['700'],
fontFamily: 'monospace',
fontSize: '200%',
height: 32,
'&$checked': {
backgroundColor: yellow.A700,
color: 'white'
},
'&:not($checked):hover': {
backgroundColor: yellow['100']
},
transition: 'background-color 250ms'
},
redButtonRoot: {
backgroundColor: '#00000004',
borderRadius: 5,
border: '1px solid',
color: red.A700,
fontFamily: 'monospace',
fontSize: '160%',
height: 32,
'&$checked': {
backgroundColor: red.A700,
color: 'white'
},
'&:not($checked):hover': {
backgroundColor: red['50']
},
transition: 'background-color 250ms'
},
greyButtonRoot: {
backgroundColor: '#00000004',
borderRadius: 5,
border: '1px solid',
color: grey['700'],
fontFamily: 'monospace',
fontSize: '180%',
height: 32,
'&$checked': {
backgroundColor: grey['700'],
color: 'white'
},
'&:not($checked):hover': {
backgroundColor: grey['200']
},
transition: 'background-color 250ms'
},
disabled: {
backgroundColor: '#00000004'
},
checked: {}
});
function QRadios(props) {
const {
classes,
error,
required,
id,
label,
name,
binaryChoice,
value,
onChange,
onBlur
} = props;
return (
<FormControl className={classes.formControl} required={required}>
<InputLabel
error={error}
required={required}
shrink
style={{
position: 'relative',
marginBottom: '10px'
}}
>
{label}
</InputLabel>
<RadioGroup
className={classes.formGroup}
row
id={id}
name={name}
value={value}
onChange={onChange}
onBlur={onBlur}
>
<Radio
htmlFor={id}
className={classes.radioFlex}
value="good"
classes={{
root: classes.greenButtonRoot,
checked: classes.checked
}}
icon="〇"
checkedIcon="〇"
/>
<Radio
htmlFor={id}
className={classes.radioFlex}
value="okay"
classes={{
root: classes.yellowButtonRoot,
checked: classes.checked,
disabled: classes.disabled
}}
icon="△"
checkedIcon="△"
disabled={binaryChoice}
/>
<Radio
htmlFor={id}
className={classes.radioFlex}
value="bad"
classes={{
root: classes.redButtonRoot,
checked: classes.checked
}}
icon="✕"
checkedIcon="✕"
/>
<Radio
htmlFor={id}
className={classes.radioFlex}
value="na"
classes={{
root: classes.greyButtonRoot,
checked: classes.checked
}}
icon="-"
checkedIcon="-"
/>
</RadioGroup>
</FormControl>
);
}
QRadios.propTypes = {
classes: PropTypes.object.isRequired,
required: PropTypes.bool,
error: PropTypes.bool,
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
binaryChoice: PropTypes.bool,
value: PropTypes.string,
onChange: PropTypes.func.isRequired,
onBlur: PropTypes.func
};
QRadios.defaultProps = {
required: false,
binaryChoice: false,
error: false,
onBlur: null,
value: ''
};
export default withStyles(styles)(QRadios);
Usage...
<QRadios
error={!whateverThing.isValid}
id="whateverThing"
name="whateverThing"
label="What's your judgement of whateverThing?"
value={whateverThing.value}
onChange={this.someHandlerFunc}
onBlur={this.someCheckFunc}
/>
Have you looked into https://material-ui.com/components/toggle-button/ or https://material-ui.com/api/toggle-button-group/? I think it's a relatively new addition (i.e. didn't exist when you resolved this), but it might be helpful for anyone who finds this question later.
The ToggleButtonGroup will control the selected state of its child buttons when given its own value prop.
Here's the example given on that page:
<ToggleButtonGroup
value={alignment}
exclusive
onChange={handleAlignment}
aria-label="text alignment"
>
<ToggleButton value="left" aria-label="left aligned">
<FormatAlignLeftIcon />
</ToggleButton>
<ToggleButton value="center" aria-label="centered">
<FormatAlignCenterIcon />
</ToggleButton>
<ToggleButton value="right" aria-label="right aligned">
<FormatAlignRightIcon />
</ToggleButton>
<ToggleButton value="justify" aria-label="justified" disabled>
<FormatAlignJustifyIcon />
</ToggleButton>
</ToggleButtonGroup>
This was you can make a radio button have a button like, i have created a pen for this please check https://codepen.io/praveen-rao-chavan/pen/JBpgLX
<section>
<h1>Simple material design CSS only radio button example</h1>
<div>
<ul class="donate-now">
<li class="md-radio">
<input id="1" type="radio" name="g" checked>
<label for="1">Option 1</label>
</li>
<li class="md-radio">
<input id="2" type="radio" name="g">
<label for="2">Option 2</label>
</li>
</ul>
</div>
</section>
CSS
#import url(https://fonts.googleapis.com/css?family=Roboto);
$md-radio-checked-color: rgb(51, 122, 183);
$md-radio-border-color: rgba(0, 0, 0, 0.54);
$md-radio-size: 20px;
$md-radio-checked-size: 10px;
$md-radio-ripple-size: 15px;
#keyframes ripple {
0% {
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.0);
}
50% {
box-shadow: 0px 0px 0px $md-radio-ripple-size rgba(0, 0, 0, 0.1);
}
100% {
box-shadow: 0px 0px 0px $md-radio-ripple-size rgba(0, 0, 0, 0);
}
}
.md-radio {
margin: 16px 0;
&.md-radio-inline {
display: inline-block;
}
input[type="radio"] {
display: none;
&:checked + label:before {
--border-color: $md-radio-checked-color;
--animation: ripple 0.2s linear forwards;
}
&:checked + label:after {
--transform: scale(1);
}
}
label {
display: inline-block;
height:$md-radio-size;
position: relative;
padding: 0 ($md-radio-size + 10px);
margin-bottom: 0;
cursor: pointer;
vertical-align: bottom;
&:before, &:after {
position: absolute;
content: '';
border-radius: 50%;
transition: all .3s ease;
transition-property: transform, border-color;
}
&:before {
left: 0;
top: 0;
width: $md-radio-size;
height: $md-radio-size;
border: 2px solid $md-radio-border-color;
}
&:after {
top: $md-radio-size / 2 - $md-radio-checked-size / 2;
left: $md-radio-size / 2 - $md-radio-checked-size / 2;
width:$md-radio-checked-size;
height:$md-radio-checked-size;
transform: scale(0);
background:$md-radio-checked-color;
}
}
}
// *************************************
// *************************************
*, *:before, *:after {
box-sizing: border-box;
}
body {
background:#f0f0f0;
position: absolute;
width:100%;
padding:0;
margin:0;
font-family: "Roboto", sans-serif;
color: #333;
}
section {
background:white;
margin:0 auto;
padding: 4em;
max-width: 800px;
h1 {
margin: 0 0 2em;
}
}
.donate-now {
list-style-type:none;
margin:25px 0 0 0;
padding:0;
}
.donate-now li {
float:left;
margin:0 5px 0 0;
width:100px;
height:40px;
position:relative;
}
.donate-now label, .donate-now input {
display:block;
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
}
.donate-now input[type="radio"] {
opacity:0.011;
z-index:100;
}
.donate-now input[type="radio"]:checked + label {
background:yellow;
}
.donate-now label {
padding:5px;
border:1px solid #CCC;
cursor:pointer;
z-index:90;
}
.donate-now label:hover {
background:#DDD;
}
You can customize it to your styles.
I use MUi5 toggle button and overwrite their style to become button-like
check my codesandbox link

Resources