I have a problem with add font in React with use Aphrodite.
In the Aphrodite documentation (https://github.com/Khan/aphrodite) we have described how to add our font to project, but it didn't work for me.
In terminal (vsc), after npm start I don't see any errors,
but in the browser (chrome) I have this: TypeError: _nested.set is not a function.
import React, { FC, useState } from "react";
import ScreenWrapper from "components/ScreenWrapper";
import StyledInput from "components/StyledInput";
import TextArea from "components/TextArea";
import StyledText from "components/StyledText";
import { StyleSheet, css } from "aphrodite";
import { colors } from "styles";
import { i18n } from "locale";
import "fonts/Roboto.woff";
interface Props {}
const HomeScreen: FC<Props> = () => {
const [inputValue1, setInputValue1] = useState<string>("");
const [textareaValue1, setTextareaValue1] = useState<string>("");
const handleInputValue = (value: string): void => {
setInputValue1(value);
};
const handleTextareaValue = (value: string): void => {
setTextareaValue1(value);
};
return (
<ScreenWrapper>
<div className={css(styles.homeScreen)}>
<h3>{i18n.t("header:title")}</h3>
<StyledInput
value={inputValue1}
onChange={handleInputValue}
placeholder={i18n.t("textAreaPlaceholder:search")}
/>
<TextArea
value={textareaValue1}
onChange={handleTextareaValue}
placeholder={i18n.t("textAreaPlaceholder:type")}
/>
<StyledText style={styles.testText}>{i18n.t("test:lorem")}</StyledText>
</div>
</ScreenWrapper>
);
};
const Roboto = {
fontFamily: "Roboto",
fontStyle: "normal",
fontWeight: "normal",
src: "url('fonts/Roboto.woff') format('woff')",
};
const styles = StyleSheet.create({
homeScreen: {
flexDirection: "column",
alignItems: "stretch",
display: "flex",
flexGrow: 1,
backgroundColor: colors.white,
textAlign: "center",
textTransform: "uppercase",
color: colors.blue4,
},
testText: {
margin: "20px 10vw",
fontFamily: Roboto,
},
});
export default HomeScreen;
Had anyone similar problem?
Try the following.
const styles = StyleSheet.create({
testText: {
margin: "20px 10vw",
fontFamily: [AldotheApacheFont, "sans-serif"],
},
});
Or check below https://www.npmjs.com/package/aphrodite-local-styles#font-faces
Related
Before v5, I was able to apply multiple class to the component like the following:
import React from "react";
import { makeStyles } from '#mui/styles';
const useStyles = makeStyles({
image: {
borderRadius: "50%",
width: 256,
height: 256,
},
shadow: {
boxShadow: "-4px -3px 45px 21px rgba(0,0,0,0.35)",
},
}));
const MyComponent = (props) => {
const { data } = props;
const classes = useStyles();
return (
<img src={data.image} className={`${classes.image} ${classes.shadow}`} alt={data.title} />
);
};
export default MyComponent;
However, since the change of styling engine(?), it seems like I can only apply a single styling like:
import React from "react";
import { styled } from "#mui/system";
const ProfileImage = styled("img")({
borderRadius: "50%",
width: 256,
height: 256,
});
const MyComponent= (props) => {
const { data } = props;
return (
<ProfileImage src={data.image} alt={data.title} />
);
};
export default MyComponent;
Would there be any possible solution to achieve the same behavior as the one above?
Thank you!
You could use an object and just spread the properties you want to use
const classes = {
image: {
borderRadius: "50%",
width: 256,
height: 256
},
shadow: {
boxShadow: "-4px -3px 45px 21px rgba(0,0,0,0.35)"
}
};
const ProfileImage1 = styled("img")({
...classes.image,
...classes.shadow
});
If you are using JS and want to benefit from type intellisense, you could use type annotation to get the hint of CSS properties
import { styled, SxProps, Theme } from "#mui/system";
/** #type{Record<string, SxProps<Theme>>} */
const classes = {
image: {
borderRadius: "50%",
width: 256,
height: 256
},
shadow: {
boxShadow: "-4px -3px 45px 21px rgba(0,0,0,0.35)"
}
};
Also, if you want to make the class conditional, styled component allows you to use prop from the component
const ProfileImage1 = styled("img")(({ shadow }) => ({
...classes.image,
...(shadow ? classes.shadow : {})
}));
export default function App() {
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
gap: 5
}}
>
<ProfileImage1 src={"https://via.placeholder.com/256"} shadow />
<ProfileImage1 src={"https://via.placeholder.com/256"} />
</Box>
);
}
import { Container } from "#mui/material";
import * as React from "react";
import { Home } from "#mui/icons-material";
import PersonIcon from "#mui/icons-material/Person";
import FormatListBulletedIcon from "#mui/icons-material/FormatListBulleted";
import CameraAltIcon from "#mui/icons-material/CameraAlt";
import OndemandVideoIcon from "#mui/icons-material/OndemandVideo";
import PhoneAndroidIcon from "#mui/icons-material/PhoneAndroid";
import FeaturedPlayListIcon from "#mui/icons-material/FeaturedPlayList";
import StorefrontIcon from "#mui/icons-material/Storefront";
import SettingsIcon from "#mui/icons-material/Settings";
import LogoutIcon from "#mui/icons-material/Logout";
import Typography from "#mui/material/Typography";
import { styled } from "#mui/material/styles";
const StyledContainer = styled("div")(({ theme }) => ({
paddingTop: theme.spacing(10),
backgroundColor: theme.palette.primary.main,
height: "100vh",
color: "white",
[theme.breakpoints.up("sm")]: {
backgroundColor: "white",
color: "#555",
border: "1px solid #ece7e7",
},
}));
const Item = styled("div")(({ theme }) => ({
display: "flex",
alignItems: "center",
marginBottom: theme.spacing(4),
[theme.breakpoints.up("sm")]: {
marginBottom: theme.spacing(3),
cursor: "Pointer",
},
}));
const Icon = styled("div")(({ theme }) => ({
marginRight: theme.spacing(1),
[theme.breakpoints.up("sm")]: {
//I need to change the Icon size
//fontSize:"18px" but this not working
},
}));
const Text = styled("div")(({ theme }) => ({
fontWeight: 500,
fontSize: "300px",
[theme.breakpoints.down("sm")]: {
display: "none",
},
}));
function Leftbar() {
return (
<StyledContainer>
<Container>
<div>
<Item>
<Icon>
<Home />
</Icon>
<Text>
<Typography>Homepage</Typography>
</Text>
</Item>
</div>
<div>
<Item>
<Icon>
<PersonIcon />
</Icon>
<Text>
<Typography>Friends</Typography>
</Text>
</Item>
</div>
</Container>
</StyledContainer>
);
}
export default Leftbar;
This is my sidebar code. and this is the screenshot of the page.
Here I need to change the sidebar icon sizes. But the problem is I unable to change the Icon sizes in breakpoints. This is the code of that breakpoint.
const Icon = styled("div")(({ theme }) => ({
marginRight: theme.spacing(1),
[theme.breakpoints.up("sm")]: {
//I need to change the Icon size
//fontSize:"18px" but this not working
},
}));
I tried several times to solve this problem. But I didn't get a solution. So if anyone knows how to solve this problem, Please help me. Thank you
[![enter image description here][2]][2]
You need to select svg to apply font size.
Try this
[theme.breakpoints.up("sm")]: {
'& svg': {
fontSize: 18
}
},
I am new to React and material UI. I am using material UI button and I want to remove default button classes (MuiButtonBase-root MuiButton-root MuiButton-text makeStyles-buttonCss-3). I want to use only my class 'buttonCss'. Please can anyone help me to fix this.
My code is below -:
import { TextField } from '#material-ui/core';
import Button from '#material-ui/core/Button';
import { makeStyles } from '#material-ui/core/styles'
import { Form, Formik } from 'formik';
import * as React from 'react';`enter code here`
const useStyles = makeStyles((theme) => ({
container: {`enter code here`
maxWidth: "100vw",
maxHeight: "100vh",
display: "flex",
alignItems: "flex-start",
justifyContent: "space-evenly",
flexWrap: 'wrap'
},
mybox: {
width: 300,
backgroundColor: theme.palette.success.main,
color: "white",
padding: theme.spacing(1),
borderRadius: 4,
boxShadow: theme.shadows[10]
},
buttonCss : {
backgroundColor: theme.palette.success.dark
},
deafult: {
color: 'red'
}
}));
// implementing button this way
<Button className={classes.buttonCss} >Submit</Button>
You can't remove the default class and then continue using MaterialUi, now just use the default html button .
If you want only to customise, now just use
const useStyles = makeStyles({
root: {background: "red}
});
export default () => {
const classes = useStyles();
return <Button className={classes} >Submit</Button>
}
The html video element below does not play the webcam stream.
setState works fine since the browser notifies me that the site is accessing the camera.
It still invokes the webcam but the html video element is not activated after state change.
What i see is the black screen even if the webcam is active.
There are no error messages on browser console
any help appreciated
import React, {useState,useEffect} from 'react';
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
import { connect } from "react-redux";
const styles = () => ({
root: {
display: "flex",
flexDirection: "column",
width: "20%",
height: "25%",
overflowY: "auto",
},
videoPreview:{
alignSelf: "center",
width: "30%",
backgroundColor: "rgba(0, 0, 0, 0.25)",
marginTop: 20,
},
});
const Preview = (props) => {
const {classes} = props;
const [videoPreviewTrack, setVideoPreviewTrack] = useState(navigator.mediaDevices.getUserMedia({video:true}) );
useEffect(() => {
//something here maybe?
});
return (
<div className={classes.videoPreview}>
<video src={videoPreviewTrack} autoPlay={true} id={"videoPreviewElement"}>
</video ></div>
);
};
Preview.propTypes = {
classes: PropTypes.object.isRequired,
};
export default connect()(withStyles(styles)(Preview));
import React, {useState,useEffect,useRef} from 'react';
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
import { connect } from "react-redux";
import Select from '#material-ui/core/Select';
const styles = () => ({
root: {
display: "flex",
flexDirection: "column",
width: "20%",
height: "25%",
overflowY: "auto",
},
previewBackground:{
alignSelf: "center",
backgroundColor: "rgba(0, 0, 0, 0.25)",
marginTop: 20,
},
videoPreview:{
alignSelf: "center",
width: "15%",
backgroundColor: "rgba(0, 0, 0, 0.25)",
marginTop: 5,
},
});
const Preview = (props) => {
const {classes} = props;
const videoRef = useRef(null);
useEffect(() => {
getVideo();
}, [videoRef]);
const getVideo = () => {
navigator.mediaDevices
.getUserMedia( {video: true} )
.then(stream => {
let video = videoRef.current;
video.srcObject = stream;
video.play();
})
.catch(err => {
console.error("error:", err);
});
};
return (<div align={"center"} className={classes.previewBackground} >
<div >
<video className={classes.videoPreview} ref={videoRef} >
</video >
</div>
</div>
);
};
Preview.propTypes = {
classes: PropTypes.object.isRequired,
};
export default (withStyles(styles)(Preview));
So I got the latest versions of jss and material ui.
Im using withStyles HOC and dynamically changing css in styles object, but I cant seem to be able to declare keyframes in css. Im also using nextjs if that makes any difference. Ive looked at how material-ui declares their animations, and I'm following their example https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/ButtonBase/TouchRipple.js.
import React, { useEffect, useState } from "react";
import classnames from "classnames";
import PropTypes from "prop-types";
import { withStyles, makeStyles } from "#material-ui/core/styles";
import { sectionAnchors, maxContentWidth } from "../../../util/constants";
import LearnMoreLink from "./LearnMoreLink";
import SectionContent from "../../common/SectionContent";
import content from "../../../../content";
import useRealHeight from "../../../util/useRealHeight";
import SplashHeading from "./SplashHeading";
import { singleHeight, doubleHeight } from "../../common/Footer";
import GetStartedForm from "./GetStartedForm";
import { withRouter } from "next/router";
import SwipeableTextMobileStepper from "./SwipeableTextMobileStepper";
import { Link } from 'next/router'
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import FormHelperText from '#material-ui/core/FormHelperText';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import FormControl from '#material-ui/core/FormControl';
import FormLabel from '#material-ui/core/FormLabel';
import { green } from '#material-ui/core/colors';
import RadioButtonUncheckedIcon from '#material-ui/icons/RadioButtonUnchecked';
import RadioButtonCheckedIcon from '#material-ui/icons/RadioButtonChecked';
import Switch from '#material-ui/core/Switch';
import Button from '#material-ui/core/Button';
const styles = theme => ({
heading: {
marginBottom: theme.spacing.unit * 6
},
headingColored: {
marginBottom: 0,
color: theme.palette.primary.dark
},
container: {
width: "100%",
// '#keyframes fade': {
// '0%': {
// opacity: 1
// },
// '100%': {
// opacity: 0
// }
// },
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
},
// backgroundColor: theme.palette.primary.dark,
// background: 'url(https://images.newscientist.com/wp-content/uploads/2019/04/08111018/screenshot-2019-04-08-10.24.34.jpg)',
backgroundImage: props => props.background,
backgroundSize: "cover",
// animation: '$fadeMe linear 1s infinite',
// animationName: '#fadeMe',
// animdationDuration: '1s',
// animation:
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
},
containerWizard: {
background: "none",
marginBottom: -doubleHeight,
paddingBottom: doubleHeight + theme.spacing.unit * 3,
[theme.breakpoints.up("sm")]: {
marginBottom: -singleHeight,
paddingBottom: singleHeight + theme.spacing.unit * 3
}
},
inner: {
maxWidth: maxContentWidth,
width: "100%",
flex: "1 0 auto",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
flex: {
flex: "1 0 auto"
},
form: {
width: "100%",
maxWidth: maxContentWidth / 2,
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
}
});
// http://www.coverbash.com/wp-content/covers/caeli_flowers_facebook_cover.jpg
function SplashLogic() {
const [selectedValue, setSelectedValue] = React.useState(1);
let int
useEffect(() => { int = init(1) }, []);
let background = selectedValue == 1 ? bG('http://www.coverbash.com/wp-content/covers/caeli_flowers_facebook_cover.jpg') :
bG('https://images.newscientist.com/wp-content/uploads/2019/04/08111018/screenshot-2019-04-08-10.24.34.jpg?')
const handleChange = event => {
setSelectedValue(event.target.value);
clearInterval(int)
int = init(event.target.value)
};
function init(num) {
return setInterval(() => {
background = bG('http://www.coverbash.com/wp-content/covers/caeli_flowers_facebook_cover.jpg')
setSelectedValue(2)
}, 4000)
}
return <SplashFull {...{ setSelectedValue, selectedValue, background, handleChange }}></SplashFull>
}
const SplashSection = ({ classes, router, setSelectedValue, selectedValue, background, handleChange }) => {
// const [height] = useRealHeight({ resize: false });
console.log(classes.container)
useEffect(() => {
router.prefetch("/signup");
}, []);
const onSubmit = values => {
router.push(`/signup?destination=${values.destination}`, "/signup");
};
return (
<SectionContent id={sectionAnchors.SPLASH} className={classes.container}>
<div className="bg-white opacity-50 rounded-full">
<Radio
checked={selectedValue === 1}
onChange={handleChange}
value={1}
name="radio-button-demo"
inputProps={{ 'aria-label': 'A' }}
/>
<Radio
checked={selectedValue === 2}
onChange={handleChange}
value={2}
name="radio-button-demo"
inputProps={{ 'aria-label': 'B' }}
/>
<Radio
checked={selectedValue === 3}
onChange={handleChange}
value={3}
name="radio-button-demo"
inputProps={{ 'aria-label': 'D' }}
/>
<Radio
checked={selectedValue === 4}
onChange={handleChange}
value={4}
name="radio-button-demo"
inputProps={{ 'aria-label': 'E' }}
/>
</div>
<div className={classes.inner}>
<SplashHeading
classes={{
container: classes.heading
}}
/>
<GetStartedForm className={classes.form} onSubmit={onSubmit} />
</div>
<Button variant="contained" >
Default
</Button>
<LearnMoreLink />
</SectionContent>
// <SwipeableTextMobileStepper></SwipeableTextMobileStepper>
);
};
SplashSection.propTypes = {
classes: PropTypes.object.isRequired
};
function bG(arg) {
return `url(${arg})`
}
const SplashFull = withStyles(styles)(withRouter(SplashSection));
export default SplashLogic
I get error:
container.addRule(...).addRule is not a function
TypeError: container.addRule(...).addRule is not a function
at Array.onProcessStyle (/workspace/travelcontacts/node_modules/jss-plugin-nested/dist/jss-plugin-nested.cjs.js:96:10)
at PluginsRegistry.onProcessStyle (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:1246:51)
at PluginsRegistry.onProcessRule (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:1235:26)
at Array.forEach (<anonymous>)
at RuleList.process (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:871:25)
at new StyleSheet (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:1041:16)
at Jss.createStyleSheet (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:2007:17)
at attach (/workspace/travelcontacts/node_modules/#material-ui/styles/makeStyles/makeStyles.js:116:39)
at /workspace/travelcontacts/node_modules/#material-ui/styles/makeStyles/makeStyles.js:256:7
at useSynchronousEffect (/workspace/travelcontacts/node_modules/#material-ui/styles/makeStyles/makeStyles.js:210:14)
at /workspace/travelcontacts/node_modules/#material-ui/styles/makeStyles/makeStyles.js:248:5
at Object.WithStyles [as render] (/workspace/travelcontacts/node_modules/#material-ui/styles/withStyles/withStyles.js:70:21)
at ReactDOMServerRenderer.render (/workspace/travelcontacts/node_modules/react-dom/cjs/react-dom-server.node.development.js:3758:44)
at ReactDOMServerRenderer.read (/workspace/travelcontacts/node_modules/react-dom/cjs/react-dom-server.node.development.js:3538:29)
at renderToString (/workspace/travelcontacts/node_modules/react-dom/cjs/react-dom-server.node.development.js:4247:27)
at render (/workspace/travelcontacts/node_modules/next-server/dist/server/render.js:86:16)
The issue appears to be resolved by not nesting #keyframes definitions. The hint was in the second application of the addRule function in the error: container.addRule(...).addRule is not a function.
Solution
Try moving your keyframe animations to the root level. So from this
const styles = theme => ({
container: {
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
}
}
}
to this
const styles = theme => ({
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
}
}
Hope that helps.
Interesting side note: nesting the animation another level removes the error, but does not instantiate the CSS animation.
from
const styles = theme => ({
container: {
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
}
}
}
to
const styles = theme => ({
'#global':{ //need add into global rules
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
}
}
}