I have created MyComponent( called 'InnerContainer' ) by using MUI system; styled-component. But onClick under the styled component is not working. It is working outside 'InnerContainer' but not working inside 'InnerContainer'. Don't know the reason.. please help me why it's not working.
import { useSortable } from "#dnd-kit/sortable";
import { CSS } from "#dnd-kit/utilities";
import { styled } from "#mui/system";
// import styled from '#emotion/styled'
import DeleteIcon from "#mui/icons-material/Delete";
function DraggableBox(props) {
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id: props.id });
// console.log("props", props);
const outerContainer = {
transform: CSS.Transform.toString(transform),
transition,
backgroundColor: props.color,
width: "20%",
height: "25%",
display: "inline-block",
};
const InnerContainer = styled("div")({
width: "100%",
height: "100%",
display: "flex",
justifyContent: "space-between",
alignItems: "end",
fontWeight: "600",
"&:hover svg": {
color: "white",
transform: "scale(1.3)",
transition: "0.5s",
},
" .inBoxName": {
marginLeft: "0.5rem",
},
" .inBoxTrash": {
marginRight: "0.5rem",
},
});
return (
<div style={outerContainer} ref={setNodeRef} {...attributes} {...listeners}>
<InnerContainer>
<div className="inBoxName">{props.name}</div>
<div className="inBoxTrash">
<DeleteIcon onClick={() => props.removeColorBox(props.id)} />
</div>
</InnerContainer>
</div>
);
}
export default DraggableBox;
Related
I'm trying to migrate my project from Material-UI v4 to MUI v5 using this How to customize guide from the official website but can't wrap my head how can I rewrite this component with the new guidelines:
...
const useStyles = makeStyles(() => ({
root: {
backgroundColor: "rgba(255, 255, 255, 0.36)",
display: "flex",
height: "100%",
position: "absolute",
textAlign: "center",
top: 0,
width: "100%",
justifyContent: "center",
alignItems: "center",
},
visible: {
visibility: "visible",
},
hidden: {
visibility: "hidden",
},
holder: {
height: 60,
width: 60,
},
}));
interface ILoaderBlockProps {
isLoading: boolean;
className?: string;
testId?: string;
}
type Props = ILoaderBlockProps;
const LoaderBlock: FunctionComponent<Props> = (props: Props) => {
const classes = useStyles({});
const { isLoading, className } = props;
const rootClasses = clsx(
classes.root,
isLoading ? classes.visible : classes.hidden,
className
);
return (
<div className={rootClasses}>
<div className={classes.holder}>
<CircularProgress color={"primary"}/>
</div>
</div>
);
};
...
Since makeStyles is deprecated and I have additional difficulties in MUI v5, I'm trying to stop using it but can't wrap my head around new styling yet.
How could these <div>s be rewritten in new, v5-way since makeStyles is no longer an option?
It seems the only way to do it is to introduce SCSS/CSS file with styles for root and holder.
Here's what I came up with (thanks #morganney for suggestion!):
...
const LoaderBlockRoot = styled("div")(() => ({
backgroundColor: "rgba(255, 255, 255, 0.36)",
display: "flex",
height: "100%",
position: "absolute",
textAlign: "center",
top: 0,
width: "100%",
justifyContent: "center",
alignItems: "center",
}));
const Holder = styled("div")(() => ({
height: 64,
width: 64
}));
const LoaderBlock: FunctionComponent<Props> = (props: Props) => {
const { isLoading } = props;
return (
<LoaderBlockRoot sx={{ visibility: isLoading ? "visible" : "hidden" }}>
<Holder>
<CircularProgress color={"primary"} />
</Holder>
</LoaderBlockRoot>
);
};
...
A bit clumsy for my taste compared to withStyles practices though, I wonder if this could be improved.
Also, I still don't know what to do if I want to override style of component (previously, it was doable by passing prop.className into component).
While the preferred way of styling in v5 is through styled or the sx prop, makeStyles still works. (Why do you say it's deprecated; it's in the v5 docs. You can even get rid of clsx by passing in the props directly into useStyles as shown in the docs example.) The code below works fine for me in v5.
As for overriding, it's still doable even with styled or sx prop. Just target the classname by using the component-slot class name convention (docs)
import { FC, useEffect, useState } from 'react'
import clsx from 'clsx'
import { makeStyles } from '#mui/styles'
import { CircularProgress } from '#mui/material'
const useStyles = makeStyles({
root: {
backgroundColor: 'rgba(255, 255, 255, 0.36)',
display: 'flex',
height: '100%',
position: 'absolute',
textAlign: 'center',
top: 0,
width: '100%',
justifyContent: 'center',
alignItems: 'center',
},
visible: {
visibility: 'visible',
},
hidden: {
visibility: 'hidden',
},
holder: {
height: 60,
width: 60,
},
})
export const UseStyles: FC = () => {
const [loading, setLoading] = useState(true)
const classes = useStyles()
useEffect(() => {
setTimeout(() => setLoading(false), 3000)
}, [])
const rootClasses = clsx(
classes.root,
loading ? classes.visible : classes.hidden,
)
return (
<div className={rootClasses}>
<div className={classes.holder}>
<CircularProgress color={'primary'} />
</div>
</div>
)
}
I implementing TabsBar in my Appbar for my React Desktop Application.
But I really have a hard time stylizing the Tabs part. If anyone can help me with clear explanations, that would be great. I want to add Icons to the right of the text. Change the color of the tab indicator and put it on top as on the picture example. I'm a beginner. I searched for 4 days but the I ask because I block
We have two colors :(#738889) & (#006F85) for actived Tab.
AppBar with Tabs Designed
Voici Mon code actuel ci-dessous :
import React from 'react';
import PropTypes from 'prop-types';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Tabs from '#material-ui/core/Tabs';
import Tab from '#material-ui/core/Tab';
import Button from '#material-ui/core/Button';
import IconButton from '#material-ui/core/IconButton';
import SearchIcon from '#material-ui/icons/Search';
import InputBase from '#material-ui/core/InputBase';
import Icon from '#material-ui/core/Icon';
import { fade, makeStyles } from '#material-ui/core/styles';
import { withStyles } from '#material-ui/core/styles';
import { ReactComponent as BrandLogo } from '../Assets//PriceWanted/BrandLogo.svg';
import { ReactComponent as Icon_MicroPhone } from '../Icons/Icon_MicroPhone.svg';
import { ReactComponent as Icon_Separation } from '../Icons/Icon_Separation.svg';
import { ReactComponent as Icon_Global } from '../Icons/Icon_Global.svg';
import { ReactComponent as Icon_Lightning } from '../Icons/Icon_Lightning.svg';
import { ReactComponent as Icon_Shipment_Boat } from '../Icons/Icon_Shipment_Boat.svg';
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
width: '100%',
backgroundColor: theme.palette.background.paper,
},
Tabs: {
marginLeft: 50,
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
transition: theme.transitions.create('backgroundColor'),
marginRight: 10,
width: '100%',
backgroundColor: fade(theme.palette.common.black, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.black, 0.70),
boxShadow: '0 3px 5px 2px rgba(25, 1, 12, .2)',
},
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(3),
width: 'auto',
},
},
inputRoot: {
color: '#2F6164',
'&:hover': {
color: '#b2ebf2',
},
},
inputInput: {
padding: theme.spacing(1),
paddingLeft: `calc(1em + ${theme.spacing(2.5)}px)`,
paddingRight: `calc(1em + ${theme.spacing(2.5)}px)`,
transition: theme.transitions.create('width'),
width: '90%',
flex: 1,
[theme.breakpoints.up('sm')]: {
borderColor: 'grey',
'&:focus': {
borderColor: 'green',
},
width: '35ch',
'&:focus': {
width: '50ch',
},
},
},
searchIcon: {
padding: theme.spacing(0, 1),
color: '#889FA0',
height: '100%',
position: 'absolute',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
iconButton: {
padding:5,
marginRight: 6,
marginLeft: 6,
},
Toolbar: {
alignItems:'center'
},
}));
TabPanel.propTypes = {children: PropTypes.node,index: PropTypes.any.isRequired,value: PropTypes.any.isRequired,};
function TabPanel(props) {const { children, value, index, ...other } = props;}
function a11yProps(index) {return{id: `simple-tab-${index}`,'aria-controls': `simple-tabpanel-${index}`,};}
export default function SimpleTabs() {
const classes = useStyles();
const StyledButton = withStyles({
root : {background: 'linear-gradient(270deg,#00DBFF 0%, #021118 61.57%, #000000 100%)',
'&:hover': {background:'linear-gradient(90deg, #00DBFF 0%, #000000 100%)',},
position: 'relative',
borderRadius: 4,
border: 1,
color: 'White',
height: 35,
padding: '10 5px',
boxShadow: '0 3px 5px 2px rgba(0px 4px 4px #CBCBCB)',
marginLeft: 1,
justifyContent:'center'},
textTransform: 'capitalize',})(Button);
const [value, setValue] = React.useState(0);
const handleChange = (event,newValue) => {setValue(newValue);};
return (
<div className={classes.grow}>
<AppBar position="static">
<AppBar style={{background: '#FFFFFF'}}>
<Toolbar>
<BrandLogo/>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase placeholder="Marque,Modèle..."classes={{ root: classes.inputRoot,input: classes.inputInput,}}
inputProps={{ 'aria-label': 'search' }}/>
<IconButton className={classes.iconButton} aria-label="menu">
<Icon_MicroPhone/>
</IconButton>
</div>
<Icon_Separation style={{ flex: 1 }}/>
<Tabs
value={value}
onChange={handleChange}
variant="fullWidth"
indicatorColor="secondary"
textColor="secondary"
aria-label="icon label tabs example">
<Tab label="LIVE DEALS" {...a11yProps(0)} icon={<Icon_Lightning />}/>
<Tab label="GLOBAL STOCK" {...a11yProps(1)} icon={<Icon_Global/>}/>
<Tab label="TRANSPORT" {...a11yProps(2)} icon={<Icon_Shipment_Boat/>}/>
</Tabs>
<StyledButton
variant="contained"
color="primary"
className={classes.StyledButton}
endIcon={<Icon>power_settings_new&style</Icon>}>
CONNEXION
</StyledButton>
</Toolbar>
</AppBar>
</AppBar>
</div>);}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I'm doing an implementation of material-ui steppers more specifically the "small dot stepper" and the challenge I'm facing at the moment is connecting the dots with a line. I tried by setting the StepConnector position to absolute but it does not behave that well when changing screens, does anyone know a solution to this?
sandbox: https://op1l9.csb.app/
Link to stepper in question:
https://material-ui.com/components/steppers/
Most of this code is already in the link I provided
import styles from "./styles";
import {
Paper,
Grid,
Typography,
Stepper,
Step,
StepLabel,
StepContent,
StepConnector,
makeStyles,
withStyles,
} from "#material-ui/core";
import { MoreHoriz } from '#material-ui/icons'
import PropTypes from "prop-types";
import React from "react";
const useQontoStepIconStyles = makeStyles({
root: {
color: '#2e5bff',
display: 'flex',
height: 28,
marginLeft: 8,
alignItems: 'center',
},
active: {
color: '#2e5bff',
},
circle: {
zIndex: 2,
width: 8,
height: 8,
borderRadius: '50%',
backgroundColor: 'currentColor',
},
completed: {
color: '#2e5bff',
zIndex: 1,
fontSize: 18,
},
});
function QontoStepIcon(props) {
const classes = useQontoStepIconStyles();
return (
<div
className={classes.root}
>
<div style={{color: props.color}} className={classes.circle} />
</div>
);
}
QontoStepIcon.propTypes = {
active: PropTypes.bool,
completed: PropTypes.bool,
};
const QontoConnector = withStyles({
alternativeLabel: {
top: 10,
left: 'calc(-50% + 16px)',
right: 'calc(50% + 16px)',
},
lineVertical: {
height: 20
},
active: {
'& $line': {
borderColor: '#2e5bff',
},
},
completed: {
'& $line': {
borderColor: '#2e5bff',
},
},
line: {
borderColor: '#eaeaf0',
borderTopWidth: 3,
borderRadius: 1,
},
})(StepConnector);
<Stepper orientation="vertical" connector={<QontoConnector />}>
{steps.map((step, index) => (
<Step key={step.label}>
<StepLabel
optional={<Typography className={classes.description}>{step.description}</Typography>}
StepIconComponent={() => <QontoStepIcon color={step.color}/>}
>
<Typography className={classes.title}>
{step.title}
</Typography>
</StepLabel>
</Step>
))}
</Stepper>
I solved this with pseudo elements playing with ::after and ::before. It is not responsive but works for my needs.
I am trying to populate ListItems( ListItemIcon and ListItemText) on Material UI mini Drawer in vertical align mode. Some how my ListItemText not aligning properly to the ListItemIcons.
Here is my styles:
link: {
textDecoration: "none",
"&:hover, &:focus": {
backgroundColor: theme.palette.background.yellow
}
},
linkActive: {
backgroundColor: theme.palette.background.light
},
linkIcon: {
marginRight: theme.spacing(1),
marginBottom: theme.spacing(4),
color: theme.palette.text.secondary + "99",
transition: theme.transitions.create("color"),
width: 24,
display: "flex",
justifyContent: "center"
},
linkText: {
marginTop: theme.spacing(1),
color: theme.palette.text.secondary + "CC",
transition: theme.transitions.create(["opacity", "color"]),
fontSize: 13,
display: "flex",
justifyContent: "flex-end"
}
Component
import React from "react";
import {
ListItem,
ListItemIcon,
ListItemText,
} from "#material-ui/core";
import { Link } from "react-router-dom";
import classnames from "classnames";
// styles
import useStyles from "./styles";
export default function SidebarLink({
link,
icon,
label,
location,
}) {
var classes = useStyles();
var isLinkActive =
link &&
(location.pathname === link || location.pathname.indexOf(link) !== -1);
return (
<ListItem
button
component={link && Link}
to={link}
className={classes.link}
>
<ListItemIcon
className={classnames(classes.linkIcon, {
[classes.linkIconActive]: isLinkActive
})}
>
{icon}
</ListItemIcon>
<ListItemText
classes={{
primary: classnames(classes.linkText, {
[classes.linkIconActive]: isLinkActive
})
}}
primary={label}
></ListItemText>
</ListItem>
);
}
How to align ListItems in vertical mode properly? I tried adding textAlign and alignItems to center to linkText css class but not them worked.
Any Help is Appreciated
Thanks,
react-router-dom Link uses html < a > tag under the hood.
< a > children will be displayed in column as default.
You just need to style your link properly:
link: {
display: 'flex',
flexDirection: 'row',
textDecoration: "none",
"&:hover, &:focus": {
backgroundColor: theme.palette.background.yellow
}
},
I am using React ROuter and CSS in JS for style.
I'd like to change the background color and border color for the active links child divs (navIndicator and innerIndicator)
import { css, StyleSheet } from 'aphrodite/no-important';
export default ({ task, selectedLocal, selectedScenarioId, taskId }: ITaskNavItem) => {
const isActiveNav = (match: any, location: object) => match;
const theme = getTheme();
const styles = StyleSheet.create({
navLink: {
display: 'flex',
fontSize: '12px',
textDecoration: 'none',
color: theme.palette.neutralPrimary
},
navLinkActive: {
color: theme.palette.neutralPrimary,
fontWeight: 'bold',
'.navIndicator': {
borderColor: theme.palette.themePrimary
},
'.innerIndicator': {
backgroundColor: theme.palette.themePrimary
}
},
navTitle: {
width: '100px',
textAlign: 'center',
wordBreak: 'break-word',
wordSpacing: '100px'
},
linkText: {
display: 'flex',
flexFlow: 'column',
'align-items': 'center'
},
navIndicator: {
borderRadius: '50%',
margin: '10px 0 0 0',
backgroundColor: theme.palette.white,
width: '30px',
height: '30px',
border: '2px solid',
borderColor: theme.palette.neutralPrimary,
position: 'relative'
},
innerIndicator: {
position: 'absolute',
borderRadius: '50%',
width: '20px',
height: '20px',
backgroundColor: theme.palette.neutralPrimary,
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
}
});
return (
<div className={css(styles.navLink)}>
<NavLink
exact
isActive={isActiveNav}
className={css(styles.navLink)}
activeClassName={css(styles.navLinkActive)}
to={`/selectedLocal/${selectedLocal}/scenarios/${selectedScenarioId}/tasks/${taskId}`}
>
<div className={css(styles.linkText)}>
<div className={css(styles.navTitle)}> {task.title}</div>
<div className={css(styles.navIndicator)}>
<div className={css(styles.innerIndicator)} />
</div>
</div>
</NavLink>
</div>
);
};
However, the navIndicator and innerIndicator colors doesn't change when nav link is active.
Wondering how to get the style working for active link?
NavLink element does not indicate to its children if it active. So I may suggest to get currecnt route from BrowserRouter component (your component should be child of BrowserRouter so NavLink works), compare path and set local isActive variable to indicate if specific route is active.
For example (not tested, just sample):
const StyledLinks: React.FunctionComponent<RouteComponentProps & ITaskNavItem> = ({ task, selectedLocal, selectedScenarioId, taskId, location }) => {
const to = '/selectedLocal/${selectedLocal}/scenarios/${selectedScenarioId}/tasks/${taskId}';
const isActive = to === location.pathname;
const styles = StyleSheet.create({
// ...
navIndicatorActive: {
borderColor: theme.palette.themePrimary
},
// ...
return (
<div className={css(styles.navLink)}>
<NavLink
exact
className={css(styles.navLink)}
activeClassName={css(styles.navLinkActive)}
to={to}
>
<div className={css(styles.linkText)}>
<div className={css(styles.navTitle)}> {task.title}</div>
<div className={isActive ? css([styles.navIndicator, styles.navIndicatorActive]) : css(styles.navIndicator)}>
<div className={css(styles.innerIndicator)} />
</div>
</div>
</NavLink>
</div>
);
}
// Wrap your component withRouter to get location prop
export default withRouter(StyledLinks);