How to write and access function in React stateless components - reactjs

I want to write and access function/const in CSS style with stateless React Component.
I did below implementation but can't get success:
const MyComponent = ({ title, data }: Props) => {
function setPercentageColor() {
console.log("standard");
return "#ca2626";
}
const percentage = "50";
return (
<div className="progress-circle">
<CircularProgressbar
percentage={percentage}
text={percentage}
styles={{
root: {},
path: {
stroke: "#0080a6",
strokeWidth: "8",
transition: "stroke-dashoffset 0.5s ease 0s"
},
trail: {
stroke: setPercentageColor //here I want to access
},
text: {
fill: "#28323c",
fontSize: "35px",
fontFamily: "Roboto Regular"
}
}}
/>
</div>
);
};
export default MyComponent;
Please help in to write the correct solution.
Thanks

You can access your function directly by calling it. ie:
stroke: setPercentageColor()
Here is a simple working example:
const App = () => {
const setTextColor = () => "#ca2626";
return (
<div>
<Foo
styles={{ colors: { text: setTextColor(), background: "black" } }}
/>
</div>
);
};
const Foo = (props) => {
const { styles } = props;
return (
<div
style={{
color: styles.colors.text,
backgroundColor: styles.colors.background,
}}
>
Foo
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("root")
);
<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>
<div id="root"></div>

Related

How can I change two different buttons' text if I switch between two language buttons?

My main problem is that when I switch from "ENG" to "HUN" button, the "Home" and the "New Game" text button don't transform to the Hungarian equivalent.
{ LangButton } component switches "ENG" to "HUN". When the "HUN" button active, should transform any innerText. Those innerText changes are stored in { languages } object, what is also a different js file.
Buttons
Current codes are here, LangButton used as a Child component in Header.js file;
LangButton.js file:
import React from 'react';
import ".././Header_module.css";
export const LangButton = ({ hunLang, setHunLang, num, text, onClick }) => (
<button
onClick={() => setHunLang(num)}
className="button"
style={{
backgroundColor: hunLang === num ? 'white' : 'black',
color: hunLang === num ? 'red' : 'rgb(112, 255, 0)',
borderRadius: num === 1 ? '5px 0 0 5px' : '0 5px 5px 0',
marginRight: num === 2 ? '10px' : '0px',
onClick: {onClick}
}}
>
{text}
</button>
);
Header.js file:
import "./Header_module.css";
import React, { useState } from "react";
import { LangButton } from "./Language/LangButton";
import { languages } from ".././languages";
const Header = (props) => {
const [hunLang, setHunLang] = useState(1);
const [homeButton, setHomeButton] = useState(languages.en.home_btn);
const [newGameButton, setNewGameButton] = useState(languages.en.new_game_btn);
const engButtonClick = () => {
setHomeButton(languages.en.home_btn);
setNewGameButton(languages.en.new_game_btn);
};
const hunButtonClick = () => {
setHomeButton(languages.hu.home_btn);
setNewGameButton(languages.hu.new_game_btn);
};
return (
<div className="header-bg">
<div className="btn-container">
<button className="button">{homeButton}</button>
<button className="button">{newGameButton}</button>
<LangButton
hunLang={hunLang}
setHunLang={setHunLang}
num={1}
text="ENG"
onClick={engButtonClick}
/>
<LangButton
hunLang={hunLang}
setHunLang={setHunLang}
num={2}
text="HUN"
onClick={hunButtonClick}
/>
</div>
</div>
);
};
export default Header;
You have added two onClick handlers including one inside a style block of LangButton component.
It works after fixing it:
const languages = {
en: {
home_btn: "Home",
new_game_btn: "Game"
},
hu: {
home_btn: "Home hu",
new_game_btn: "Game hu"
}
};
const LangButton = ({ hunLang, num, text, onClick }) => (
<button
onClick={onClick}
className="button"
style={{
backgroundColor: hunLang === num ? "white" : "black",
color: hunLang === num ? "red" : "rgb(112, 255, 0)",
borderRadius: num === 1 ? "5px 0 0 5px" : "0 5px 5px 0",
marginRight: num === 2 ? "10px" : "0px"
}}
>
{text}
</button>
);
const Header = (props) => {
const [hunLang, setHunLang] = React.useState(1);
const [homeButton, setHomeButton] = React.useState(languages.en.home_btn);
const [newGameButton, setNewGameButton] = React.useState(
languages.en.new_game_btn
);
const engButtonClick = () => {
setHunLang(1);
setHomeButton(languages.en.home_btn);
setNewGameButton(languages.en.new_game_btn);
};
const hunButtonClick = () => {
setHunLang(2);
setHomeButton(languages.hu.home_btn);
setNewGameButton(languages.hu.new_game_btn);
};
return (
<div className="header-bg">
<div className="btn-container">
<button className="button">{homeButton}</button>
<button className="button">{newGameButton}</button>
<LangButton
hunLang={hunLang}
setHunLang={setHunLang}
num={1}
text="ENG"
onClick={engButtonClick}
/>
<LangButton
hunLang={hunLang}
setHunLang={setHunLang}
num={2}
text="HUN"
onClick={hunButtonClick}
/>
</div>
</div>
);
};
ReactDOM.render(<Header />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class='react'></div>

How to tag results separately in React

I have a record that I displayed in React.
The record contains values that are separated by commas as per below
tag1,tag2,tag3,tag_new,tag_old.
Here is my issue: I need to create tag of the records as it is being separated by commas.
The screenshot below will show what am trying to achieve:
Here is the code:
//import goes here
const App = () => {
const record = {
my_tags: 'tag1,tag2,tag3,tag_new,tag_old',
};
const style = {
color: 'white',
background: 'blue',
borderRadius: '20px'
};
return (
<div>
Display Tags
<div>
<br />
<span style={style}>{record.my_tags}</span>
<br />
</div>
</div>
);
};
You could split them and map them to make it as you desired
Like so:
const App = () => {
const record = {
my_tags: "tag1,tag2,tag3,tag_new,tag_old"
};
const style = {
color: "white",
background: "blue",
borderRadius: "20px"
};
return (
<div>
Display Tags
<div>
<br />
{record.my_tags.split(",").map((tag) => (
<span key={tag} style={style}>{tag}</span>
))}
<br />
</div>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>
//import goes here
const App = () => {
const record = {
my_tags: 'tag1,tag2,tag3,tag_new,tag_old',
};
const style = {
color: 'white',
background: 'blue',
borderRadius: '20px'
};
return (
<div>
Display Tags
<div>
<br />
{
record.my_tags.split(',').map((item)=>{
return <span style={style}>{item}</span>
})
}
<br />
</div>
</div>
);
};

Material UI is not working properly with Next.js

These are the problems I faced with Next.js and Material UI, even though I am following the methods mentioned in Material UI docs.
I am getting this error, if I use props with makeStyles:
I am getting if I pass state as props
const useStyles = makeStyles((theme: Theme) => ({
root: {
background: "#EFEFEF",
minHeight: (props: any) => (props.open ? "150vh" : "100vh"),
},
},
}));
const Profile = () => {
const [open, setOpen] = useState(false);
const classes = useStyles({ open });
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div className={classes.root}>
<Layout authRoute={false} showNavbar={false}>
<Container maxWidth="lg">
<Header method={method} />
<div className={classes.btnContainer}>
<Button
variant="contained"
color="secondary"
className="yesBtn"
onClick={handleOpen}>
<IoMdCheckmark />
Yes
</Button>
<Button
variant="contained"
color="default"
className="noBtn"
onClick={() => router.push("/")}>
<TiDeleteOutline />
No
</Button>
</div>
<ProfileModal handleClose={handleClose} open={open} />
</Container>
</Layout>
</div>
);
};
export default Profile;
Media query is not working in production (theme.breakpoints.down("sm")).
export const useButtonStyle = makeStyles(theme => ({
submitBtn: {
padding: "12px 16px",
borderRadius: theme.shape.borderRadius,
position: "absolute",
bottom: "25%",
display: "block",
left: "0%",
right: "0%",
width: "83.5%",
margin: " auto",
[theme.breakpoints.down("xs")]: {
bottom: "35%",
width: "88%",
},
"& .MuiButton-label": {
display: "flex",
justifyContent: "center",
alignItems: "center",
"& .MuiCircularProgress-root": {
height: "20px",
width: "20px",
marginRight: "10px",
},
},
},
root: {
position: "relative",
backgroundColor: theme.palette.secondary.dark,
minHeight: "100vh",
[theme.breakpoints.up("sm")]: {
padding: "2rem 0.2rem",
"& .overlay": {
display: "none",
},
},
[theme.breakpoints.down("sm")]: {
"& .MuiContainer-root": {
paddingLeft: "0",
paddingRight: "0",
},
},
},
}));
Here is _document.tsx file
import Document, { Html, Head, Main, NextScript } from "next/document";
import { ServerStyleSheets } from "#material-ui/styles";
class MyDocument extends Document {
static async getInitialProps(ctx: any) {
const sheet = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App: any) => (props: any) =>
sheet.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
ctx.renderPage(sheet);
}
}
render() {
return (
<Html>
<Head>
<link
rel="shortcut icon"
type="image/png"
href="../static/favicon.ico"
/>
<style>{`body { margin: 0 } /* custom! */`}</style>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
</Head>
<body className="custom_class">
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
This is _app.tsx file
import { ApolloProvider } from "#apollo/client";
import CssBaseline from "#material-ui/core/CssBaseline";
import { ThemeProvider } from "#material-ui/core/styles";
import Head from "next/head";
import React from "react";
import theme from "../src/theme";
import "../styles/styles.scss";
import { withApollo } from "../src/utils/apollo";
import App from "next/app";
class MyApp extends App<any> {
componentDidMount() {
const jssStyles = document.querySelector("#jss-server-side");
if (jssStyles) {
jssStyles.parentElement!.removeChild(jssStyles);
}
}
render() {
const { Component, pageProps, apolloClient } = this.props;
return (
<>
<Head>
<title>Beauty wall spot</title>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width"
/>
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
<ApolloProvider client={apolloClient}>
<Component {...pageProps} />
</ApolloProvider>
</ThemeProvider>
</>
);
}
}
export default withApollo(MyApp);
Install 'npm install #mui/styles'
Then Import: import { makeStyles } from '#mui/styles';

Passing props in makeStyles keyframe animations

How to pass props fill value to makeStyles' keyframe? Do I have to specify initial states to pass the prop?
It works for the color but does not work for fillvalue.
---Child component
const useStyles = makeStyles({
progress: {
animation: '$load 3s normal forwards',
background: props => props.color,
width: '0',
},
"#keyframes load": {
"0%": { width: "0" },
"100%": { width: props => props.fillvalue}
}
});
export default function ProgressBar(props) {
const propsStyle = {color: props.color, fillvalue: props.fillvalue}
const classes = useStyles(propsStyle)
return(
<div>
<div className={classes.progress}>
</div>
</div>
);
}
---Parent
function App() {
return (
<div>
<ProgressBar color="#000" fillvalue = "60%"/>
</div>
);
}
The answer to this is - you can't (at least for now). This is a bug as of this writing (MUI latest release is v4.11.0 as of this writing) and is acknowledged by one of the MUI contributors. You can track its progress at this issue: https://github.com/mui-org/material-ui/issues/21011
You are going to have to find other means of passing those props without the use of keyframes
const useStyles = makeStyles({
progress: {
height: "10px",
background: (props) => props.color,
width: (props) => props.fillvalue,
transition: "width 3s"
}
});
function ProgressBar(props) {
const propsStyle = { color: props.color, fillvalue: props.fillvalue };
const classes = useStyles(propsStyle);
return (
<div>
<div className={classes.progress}></div>
</div>
);
}
function App() {
const [fill, setFill] = React.useState("0%");
return (
<div>
<button onClick={() => setFill("0%")}>0%</button>
<button onClick={() => setFill("60%")}>60%</button>
<ProgressBar color="#aaa" fillvalue={fill} />
</div>
);
}
ReactDOM.render(<App/>,document.getElementById("root"));
<body>
<div id="root"></div>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<script src="https://unpkg.com/#material-ui/core#latest/umd/material-ui.development.js"></script>
<script type="text/babel">
const { makeStyles } = MaterialUI;
</script>
</body>
I see that there is no shorter way to do this, so I've discovered a really easy way to pass the props to the #keyframes inside makeStyles You just have
to create a "helper" hook in order to pass the props:
export const useAnimationStyles = ({ width, duration }: Props) => {
const classes = makeStyles({
'#keyframes animation': {
'0%': {
transform: 'translateX(0px)',
},
'100%': {
transform: `translateX(${width}px)`,
},
},
scroll: {
animation: `$animation linear infinite`,
animationDuration: `${duration}s`
},
})
return classes()
}
and you can use it as usual:
const classes = useAnimationStyles({width, duration})
...
<div className={classes.scroll}

MaterialUI - Changing the color Textfield on focus

I'm trying to change the color of the label text in Textfield but I can't seem to figure it out.
Here is what I'm trying:
<TextField
value={value}
key={name}
label={label}
id={id}
name={name}
InputLabelProps={{
shrink: true,
FormLabelClasses: {
'root': {
'&:focused': {
color: 'white'
}
},
focused: 'true'
}
}}
/>
Can someone give me a pointer on what I'm doing wrong here?
I've also tried using the MuiThemeProvider but can't seem to figure that one out either:
const theme = createMuiTheme({
overrides: {
MuiFormLabel: {
focused: true,
root: {
'&.focused': {
color: 'white'
}
}
}
}
});
How can I change the color of the Label? In this photo, I want the "Notes" to match the color of the underline
Thanks for your help!
Tim!
Here is the snippet that should help you.
const {
TextField,
createMuiTheme,
MuiThemeProvider,
CssBaseline,
} = window['material-ui'];
const theme = createMuiTheme({
overrides: {
MuiFormLabel: {
root: {
"&$focused": {
color: "tomato",
fontWeight: "bold"
}
},
focused: {}
}
}
});
class Index extends React.Component {
render() {
return (
<MuiThemeProvider theme={theme}>
<div>
<CssBaseline />
<TextField label="Text field" InputLabelProps={{shrink:true}} />
</div>
</MuiThemeProvider>
);
}
}
ReactDOM.render(<Index />, document.getElementById('root'));
<script src="https://unpkg.com/react#latest/umd/react.development.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom#latest/umd/react-dom.development.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/#material-ui/core/umd/material-ui.development.js" crossorigin="anonymous"></script>
<div id="root"></div>
Another way of doing it without the override is to have:
const textStyles = makeStyles({
root: {
"& .Mui-focused": {
color: "tomato",
fontWeight: "bold"
},
});
class Index extends React.Component {
const TextClass = textStyles()
render() {
return (
<MuiThemeProvider theme={theme}>
<div>
<CssBaseline />
<TextField className={textStyles.root} label="Text field" InputLabelProps={{shrink:true}} />
</div>
</MuiThemeProvider>
);
}
}
for v5 of #mui this code works
const theme = createTheme({
components: {
MuiInputLabel: {
styleOverrides: {
root: {
fontWeight: 'bold',
"&.Mui-focused": {
color: 'rgba(0, 0, 0, 0.87)',
},
},
}
},
MuiTextField: {
defaultProps: {
variant: 'standard',
},
},
},

Resources