React: How to combine multiple external makestyle using material ui? - reactjs

I have multiple external makestyle that I want to combine. So, I can organize the style per component. The single makestyle is also good but the length of the file is too much.
I saw this on material ui documentation but it's not working
Makestyle
import useStyles from '../styles/style';
import useAddTaskStyles from '../styles/addTaskStyle';
const classes = useStyles();
const classesAddTask = useAddTaskStyles();
const className = clsx(classes, classesAddTask);
<Modal
className={className.modalContainer}
open={showAddTask}
onClose={handleCloseAddTask}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={showAddTask}>
<Tasks ref={useRef} />
</Fade>
</Modal>

import useStyles from '../styles/style';
import useAddTaskStyles from '../styles/addTaskStyle';
const classes = useStyles();
const classesAddTask = useAddTaskStyles();
<Modal
className={`${classes.modalContainer} ${classesAddTask.modalContainer}`}
open={showAddTask}
onClose={handleCloseAddTask}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={showAddTask}>
<Tasks ref={useRef} />
</Fade>
</Modal>;

You may combine it like this
const className = { ...classes, ...classesAddTask }
Codesandbox => https://codesandbox.io/s/nice-fire-xgvz2?file=/src/App.js
For Example (creating a useStyle hook that combines all style hooks)
import { makeStyles } from "#material-ui/styles";
const useStyles1 = makeStyles({
red: {
backgroundColor: "red"
}
});
const useStyles2 = makeStyles({
blue: {
backgroundColor: "blue"
}
});
const useStyles = () => {
const classes = useStyles1();
const classes2 = useStyles2();
return { ...classes, ...classes2 };
};
export default function App() {
const classes = useStyles();
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div className={classes.blue} style={{ width: "200px", height: "200px" }}>
blue box
</div>
<div className={classes.red} style={{ width: "200px", height: "200px" }}>
red box
</div>
</div>
);
}

Related

How to access values from context in a separate functional component

I'm trying to build a simple light mode/dark mode into my app I saw this example on Material UI for light/dark mode but I'm not sure how I can get access to the value for when the user clicks toggleColorMode in my Header component if it's being set in toggleColorMode function?
I guess my question is how can I get access to the value of light/dark mode of the context in my Header component if it's in a different function?
Here is my code.
import React, { useState, useEffect } from "react";
import MoreVertIcon from "#mui/icons-material/MoreVert";
import DarkModeIcon from "#mui/icons-material/DarkMode";
import LightModeIcon from "#mui/icons-material/LightMode";
import Paper from "#mui/material/Paper";
import { useTheme, ThemeProvider, createTheme } from "#mui/material/styles";
import IconButton from "#mui/material/IconButton";
import Navigation from "../Navigation/Navigation";
const ColorModeContext = React.createContext({ toggleColorMode: () => {} });
export const Header = (props) => {
const { mode } = props;
const theme = useTheme();
const colorMode = React.useContext(ColorModeContext);
console.log("mode is...", mode);
return (
<div className="header-container">
<Paper
elevation={3}
style={{ backgroundColor: "#1F1F1F", padding: "15px" }}
>
<div
className="header-contents"
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<div
className="logo"
style={{ display: "flex", alignItems: "center" }}
>
<img
src="/images/header-logo.png"
alt="URL Logo Shortener"
width={"50px"}
/>
<h1 style={{ color: "#ea80fc", paddingLeft: "20px" }}>
URL Shortener
</h1>
</div>
<div className="settings">
<IconButton
sx={{ ml: 1 }}
onClick={colorMode.toggleColorMode}
color="inherit"
aria-label="dark/light mode"
>
{theme.palette.mode === "dark" ? (
<DarkModeIcon
style={{
cursor: "pointer",
marginRight: "10px",
}}
/>
) : (
<LightModeIcon
style={{
cursor: "pointer",
marginRight: "10px",
}}
/>
)}
</IconButton>
<IconButton aria-label="settings">
<MoreVertIcon style={{ color: "#fff", cursor: "pointer" }} />
</IconButton>
</div>
</div>
</Paper>
{/* Navigation */}
<Navigation />
</div>
);
};
export default function ToggleColorMode() {
const [mode, setMode] = React.useState("light");
const colorMode = React.useMemo(
() => ({
toggleColorMode: () => {
setMode((prevMode) => (prevMode === "light" ? "dark" : "light"));
},
}),
[]
);
const theme = React.useMemo(
() =>
createTheme({
palette: {
mode,
},
}),
[mode]
);
return (
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<Header mode={mode} />
</ThemeProvider>
</ColorModeContext.Provider>
);
}
Read the documentation: createContext, useContext. You need to render a ContextProvider in your parent (or top-level) component, then you can get the data in any component in the tree like const { theme } = useContext(ColorModeContext);.
You don't need to pass the mode as props, put it as one of the values in the context and access it.
Here's how you would render it in your example:
<ColorModeContext.Provider value={{colorMode, theme}}>
<Header />
</ColorModeContext.Provider>
You can pass an object inside the value in the context provider, in other word you can pass the toggle function inside your value to be consumed in the childern. thus you gain an access to change your mode state.
Note that the way changes are determined can cause some issues when passing objects as value, this might trigger unnecessary rerendering see Caveats for more info. or refer to the useContext docs
<ColorModeContext.Provider
value={{ colorMode: colorMode, toggleColorMode: toggleColorMode }}
>
<ThemeProvider theme={theme}>
<Header />
</ThemeProvider>
</ColorModeContext.Provider>

Material UI pagination - How Can I use custom style for number of pages?

I'm quite new to material-ui. I'm trying to build this component.
I was able to do the style for the next and previous buttons the same as in the picture.
The normal style shows the number of pages as a numbered group besides each other like this:
Are there any properties that I can pass for the pagination component, in which I can change the style?
Here is the code:
import Pagination from "#material-ui/lab/Pagination";
import useStyles from "./styles";
const ReviewsPagination = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<Pagination count={8} />
</div>
);
};
export default ReviewsPagination;
and the style file:
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles({
root: {
"& .MuiPagination-ul": {
"& > li:first-child": {
"& button": {
borderRadius: "50%",
border: "1px solid black",
width: "48px",
height: "48px",
},
},
"& > li:last-child": {
"& button": {
borderRadius: "50%",
border: "1px solid black",
width: "48px",
height: "48px",
},
},
},
},
});
export default useStyles;
Thank you!
you can use the usePagination hook to customize the pagination component. Like below:
export default function UsePagination() {
const classes = useStyles();
const { items } = usePagination({
count: 10,
});
return (
<nav>
<ul className={classes.ul}>
{items.map(({ page, type, selected, ...item }, index) => {
let children = null;
if (type === 'next' || type === 'previous') {
children = (
<button type="button" {...item}>
{type}
</button>
);
}else if(selected){
children = <div>{`${page}/10`}</div>
}
return <li key={index}>{children}</li>;
})}
</ul>
</nav>
);
}

What is the "TransitionProps" param in Material-ui?

I'm learning how to use Material-ui for ReactJS, I don't understand what is the "TransitionProps" in this example code below:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Popper from '#material-ui/core/Popper';
import Fade from '#material-ui/core/Fade';
const useStyles = makeStyles((theme) => ({
paper: {
border: '1px solid',
padding: theme.spacing(1),
backgroundColor: theme.palette.background.paper,
},
}));
export default function TransitionsPopper() {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(anchorEl ? null : event.currentTarget);
};
const open = Boolean(anchorEl);
const id = open ? 'transitions-popper' : undefined;
return (
<div>
<button aria-describedby={id} type="button" onClick={handleClick}>
Toggle Popper
</button>
<Popper id={id} open={open} anchorEl={anchorEl} transition>
{({ TransitionProps }) => (
<Fade {...TransitionProps} timeout={350}>
<div className={classes.paper}>The content of the Popper.</div>
</Fade>
)}
</Popper>
</div>
);
}
What will be passed into "TransitionProps"?
Here is the source code on Codesandbox
Hoping someone will explain some more on this syntax.
Thanks.

How can I make this modal close onMouseLeave in my Reactjs application, styled with Material UI

I have a modal that opens onMouseEnter which works great, however, I'm having trouble closing it onMouseLeave when the user stops hovering over the button.
Here is my component:
I've tried adding an event listener, onMouseLeave to the button tag, but it does not work correctly. Any ideas?
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Modal from '#material-ui/core/Modal';
import Backdrop from '#material-ui/core/Backdrop';
import Fade from '#material-ui/core/Fade';
const useStyles = makeStyles(theme => ({
modal: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
paper: {
backgroundColor: theme.palette.background.paper,
border: '2px solid #000',
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3),
},
}));
const DistributionLineOverflow = props => {
const classes = useStyles();
const [open, setOpen] = React.useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<button type="button" onMouseEnter={handleOpen}>
i
</button>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
className={classes.modal}
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={open}>
<div className={classes.paper}>
<p id="transition-modal-description">
Service Dates: {props.serviceDates}
</p>
</div>
</Fade>
</Modal>
</div>
);
};
export default DistributionLineOverflow;
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button
onMouseEnter={() => handleOpen()}
onMouseLeave={() => handleClose()}
>
i
</button>
<div
style={{
width: 500,
height: 500,
backgroundColor: "blue",
display: open ? "block" : "none"
}}
/>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Try calling your methods like this instead.
I created a code sandbox with similar behaviour: https://codesandbox.io/s/crazy-meninsky-7fl2o
I updated the codesandbox link, but it seems that codesandbox is having some problem running it for me so I have posted the whole code here as well.

How to change grayscale using hooks in react?

I want to change on the image slider used with UI material when I drag on the slider, but it changes only grayscale but nothing happens on the slider, why?
I will try to do function but I don't have idea how to do? somebody have?
import React, { useState, useEffect } from 'react';
import logo from '../logo.svg';
import defaultImage from '../Image/sen.jpg';
import Typography from "#material-ui/core/Typography";
import Slider from "#material-ui/lab/Slider";
function ImageSlider ({ value, max, onChange, children }) {
return (
<>
<Typography id="label">
{children}
</Typography>
<Slider className="slider"
min={0}
max={max}
value={value}
aria-labelledby="label"
step={1}
onChange={onChange}
/>
</>
)
}
export default function Hooks () {
const [name, setName] = useState('Franek!');
const [contrast, setContrast] = useState('100%');
const [brightness, setBrightness] = useState('100%');
const [invert, setInvert] = useState("0%");
const [hue, setHue] = useState("0deg");
const [saturate, setSaturate] = useState("100%");
const [sepia, setSepia] = useState("0%");
const [grayscale, setGrayscale] = useState('0%');
const [rotation, setRotation] = useState("0deg");
const [width, setWidth] = useState('0');
const [height, setHeight] = useState('0');
const [color, setColor] = useState('black');
const container = {
display: 'grid',
gridTemplateColumns: 'auto auto auto',
gridTemplateRows: '80px 200px',
gridGap: '200px',
padding: '10px'
}
const settings = {
width: '200px',
maxHeight: '1000px'
}
const buttonStyle = {
height: '50px',
width: '200px'
}
const parametersStyle = {
height: '50px',
width: '100px',
marginBlockEnd: '0',
marginBlockStart: '0',
backgroundColor: 'rgba(46, 56, 79, 0.85)',
padding: '1em'
}
const imgStyle = {
width: '300px',
height: '300px',
transform: `rotate(${rotation})`,
filter: `sepia(${sepia}) grayscale(${grayscale}) hue-rotate(${hue}) saturate(${saturate}) invert(${invert}) contrast(${contrast}) brightness(${brightness})`,
color: color
}
const elementChangingStyle = {
maxWidth: '600px',
maxHeight: '600px'
}
const headerTitle = {
color: '#ffffff',
fontSize: '40px',
padding: '1em'
}
// thiw function but they are get only 50 and see
function onGrayscale (e, grayscale) {
let newGrey = grayscale;
console.log("this onGrayscale " + setGrayscale('50'));
}
return (
<div>
<div style={headerTitle}>
React Photo-Modifier <br/> with Hooks
</div>
<div style={container}>
<div style={settings}>
<ImageSlider
max={100}
value={grayscale}
onChange={e => setGrayscale(e.target.value)}
>
Grayscale {grayscale}
</ImageSlider>
</div>
<div style={elementChangingStyle}>
<div>
<span>
<img src={logo} className="App-logo" alt="logo" />
</span>
</div>
<img style={imgStyle} src={defaultImage} />
<p style={imgStyle} > {name}</p>
</div>
</div>
</div>
)
}
If I triggered function onGrayscale the I have only slide to 50 but I want do this dynamically? How to do?
If I set ImageSlider to target value then change to grayscale but I can't then change manually using the slider?
What I'm doing wrong?
EDIT 1:
This. it's working now! Under the function and return in return.
function onGrayscale (e, grayscale) {
setGrayscale(grayscale);
}
<ImageSlider
max={100}
value={grayscale}
onChange={onGrayscale}
>
Grayscale {grayscale}
</ImageSlider>
You aren't using the function arguments correctly in onGrayScale function. This function is only passed the value and not the event, so it would look like
function onGrayscale (grayscale) {
let newGrey = grayscale;
setGrayscale(grayScale);
}

Resources