I have created a custom cursor in my NextJS application like this:
import { useEffect, useState } from "react";
import { motion } from "framer-motion";
export default function Cursor(props: any) {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const mouseMove = (e: any) => {
setPosition({ x: e.clientX, y: e.clientY });
};
window.addEventListener("mousemove", mouseMove);
return () => {
window.removeEventListener("mousemove", mouseMove);
};
}, []);
const variants = {
default: {
x: position.x - 16,
y: position.y - 16,
backgroundColor: "#fff",
},
text: {
height: 150,
width: 150,
x: position.x - 75,
y: position.y - 75,
backgroundColor: "#fff",
},
};
return (
<motion.div
variants={variants}
animate={props.cursorVariant}
className="h-[32px] w-[32px] rounded-full fixed top-0 left-0"
/>
);
}
and added it to my index.tsx file as follows:
import HeadTag from "../components/HeadTag";
import Navbar from "../components/Navbar";
import Landing from "../components/Landing";
import AboutMe from "../components/AboutMe";
import Divider from "../components/Divider";
import Projects from "../components/Projects";
import Footer from "../components/Footer";
import ParticleComponent from "../components/Particles";
import Cursor from "../components/Cursor";
import { useState } from "react";
export default function Home() {
const [cursorVariant, setCursorVariant] = useState("default");
return (
<>
<HeadTag />
<div
style={{ scrollBehavior: "smooth" }}
className="select-none bg-slate-900 w-full overflow-x-hidden flex flex-col items-center"
>
<Cursor cursorVariant={cursorVariant}/>
<ParticleComponent />
<Navbar />
<Landing setCursorVariant={setCursorVariant}/>
<AboutMe />
<Divider />
<Projects />
<Divider />
<Footer />
</div>
</>
);
}
Everything works fine regarding the styling and functions of the cursor but when I hover over elements like e.g. my Navbar Toggle, the cursor in in the background of that element and isn't visible anymore.
I have already tried giving the Div element of the cursor a higher z-index than the elements I want to hover over but this in not changing anything...
My global.css looks like this to prevent the default cursor from showing up:
#tailwind base;
#tailwind components;
#tailwind utilities;
* { cursor: none;}
Anyone has a tip for me how to solve this problem? :)
Thanks a lot!
Related
I'm trying to make a very simple react component that would crop images with react-easy-crop. Apparently it is possible to customize the style of react-easy-crop module with style prop that takes 3 objects: containerStyle, mediaStyle and cropAreaStyle.
This is the default layout:
I want to expand cropArea to full width of its container and to fit media in it by height (so that we don't see the part of the original image outside of cropArea) but can't figure out how to do it. The cropAreaStyle object doesn't seem to affect width or height since it is calculated and injected in the module file (even after setting disableAutomaticStylesInjection to true).
import React from 'react'
import ReactDOM from 'react-dom'
import Cropper from 'react-easy-crop'
import './styles.css'
class App extends React.Component {
state = {
imageSrc:
'https://img.huffingtonpost.com/asset/5ab4d4ac2000007d06eb2c56.jpeg?cache=sih0jwle4e&ops=1910_1000',
crop: { x: 0, y: 0 },
zoom: 1,
aspect: 1 / 1,
style: { containerStyle: { position: "absolute", top: "0", width: "calc(100% - 2px)", height: window.innerWidth, overflow: "hidden", border: "1px solid black" },
mediaStyle: { height: "100%", display: "block" },
cropAreaStyle: {position: "absolute", top: "0", border: "1px solid black", width: "100%", height: "100%" }}
}
onCropChange = (crop) => {
this.setState({ crop })
}
onCropComplete = (croppedArea, croppedAreaPixels) => {
console.log(croppedArea, croppedAreaPixels)
}
onZoomChange = (zoom) => {
this.setState({ zoom })
}
render() {
return (
<div className="App">
<div className="crop-container">
<Cropper
image={this.state.imageSrc}
crop={this.state.crop}
zoom={this.state.zoom}
aspect={this.state.aspect}
onCropChange={this.onCropChange}
onCropComplete={this.onCropComplete}
onZoomChange={this.onZoomChange}
style={this.state.style}
disableAutomaticStylesInjection={true}
/>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
This is what I'm trying to achieve:
The black square is cropArea that I can't resize...
I want cropArea to remain square.
Is there an easy way to do this, without changing the module file?
The solution with another module is acceptable also
Thanks in advance
I tried to use the object cropAreaStyle but it's not working, instead use the prop cropSize and don't pass the prop aspect.
In order to get the height of the media pass the prop onMediaLoaded:
onMediaLoad = (mediaSize) => {
this.setState({
cropHeight: mediaSize.height,
});
};
App.js
import React from 'react';
import ReactDOM from 'react-dom';
import Cropper from 'react-easy-crop';
import './style.css';
class App extends React.Component {
state = {
imageSrc:
'https://img.huffingtonpost.com/asset/5ab4d4ac2000007d06eb2c56.jpeg?cache=sih0jwle4e&ops=1910_1000',
crop: { x: 0, y: 0 },
zoom: 1,
cropHeight: 0,
};
onCropChange = (crop) => {
this.setState({ crop });
};
onCropComplete = (croppedArea, croppedAreaPixels) => {
console.log(croppedArea, croppedAreaPixels);
};
onZoomChange = (zoom) => {
this.setState({ zoom });
};
onMediaLoad = (mediaSize) => {
this.setState({
cropHeight: mediaSize.height,
});
};
render() {
const cropSize = {
height: `${this.state.cropHeight}px`,
width: '100%',
};
return (
<div className="App">
<div className="crop-container">
<Cropper
image={this.state.imageSrc}
crop={this.state.crop}
zoom={this.state.zoom}
onCropChange={this.onCropChange}
onCropComplete={this.onCropComplete}
onZoomChange={this.onZoomChange}
onMediaLoaded={this.onMediaLoad}
cropSize={cropSize}
/>
</div>
</div>
);
}
}
export default App;
Demo: https://stackblitz.com/edit/react-4zmgud
It seems that what you need is the objectFit property set to vertical-cover.
See this demo: https://codesandbox.io/s/crazy-liskov-04u7m0
I have a TextField defined as follows:
<TextField
id="standard-with-placeholder"
label="First Name"
className={classes.textField}
margin="normal"
/>
And it looks like this:
But I want it look like this:
The "First Name" text is larger. How can I adjust the label text size? Currently my styles object is empty. I think that should be where the CSS to do this should go, but I'm unsure what the css would look like for the label text.
Thanks
Here's an example of how to modify the label font size in v4 of Material-UI (v5 example further down). This example also modifies the font-size of the input on the assumption that you would want those sizes to be in sync, but you can play around with this in the sandbox to see the effects of changing one or the other.
import React from "react";
import ReactDOM from "react-dom";
import TextField from "#material-ui/core/TextField";
import { withStyles } from "#material-ui/core/styles";
const styles = {
inputRoot: {
fontSize: 30
},
labelRoot: {
fontSize: 30,
color: "red",
"&$labelFocused": {
color: "purple"
}
},
labelFocused: {}
};
function App({ classes }) {
return (
<div className="App">
<TextField
id="standard-with-placeholder"
label="First Name"
InputProps={{ classes: { root: classes.inputRoot } }}
InputLabelProps={{
classes: {
root: classes.labelRoot,
focused: classes.labelFocused
}
}}
margin="normal"
/>
</div>
);
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);
Below is an equivalent example for v5 of Material-UI using styled instead of withStyles:
import React from "react";
import ReactDOM from "react-dom";
import MuiTextField from "#material-ui/core/TextField";
import { inputClasses } from "#material-ui/core/Input";
import { inputLabelClasses } from "#material-ui/core/InputLabel";
import { styled } from "#material-ui/core/styles";
const TextField = styled(MuiTextField)(`
.${inputClasses.root} {
font-size: 30px;
}
.${inputLabelClasses.root} {
font-size: 30px;
color: red;
&.${inputLabelClasses.focused} {
color: purple;
}
}
`);
function App() {
return (
<div className="App">
<TextField
id="standard-with-placeholder"
label="First Name"
margin="normal"
variant="standard"
/>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here are the relevant parts of the documentation:
https://material-ui.com/api/text-field/
https://material-ui.com/api/input/
https://material-ui.com/api/input-label/
https://material-ui.com/api/form-label/
You can target the textfield label like this:
.MuiFormLabel-root {
font-size: 20px !important;
}
I'm new on React. I just added a theme color to my page.
Everything goes from black to white and vice versa when I click my button "Change Theme".
But .. the navbar that was initially lightblue colored, isnt changing !
That navbar is the only element that isnt changed by my button " Change Theme ".
I dont quite clearly understand, because the body color was supposed to be changed.
Im really bad at CSS.
App.js
import './App.css';
import React, { useState } from 'react';
import {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom';
import About from './Pages/About';
import Home from './Pages/Home';
import Works from './Pages/Works';
import PageNotFound from './Pages/PageNotFound';
import StudyCase from './Pages/StudyCase';
import styled, { ThemeProvider } from "styled-components";
import { lightTheme, darkTheme, GlobalStyles } from './Components/Themes';
const StyledApp = styled.div`
color: ${props => props.theme.fontColor}
`;
function App() {
const [theme, setTheme] = useState('light')
const themeToggler = () => {
theme === 'light' ? setTheme("dark") : setTheme("light");
}
return (
<ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme} >
<GlobalStyles />
<StyledApp>
<Router>
// NAVBAR
<div style={{width: 100 + "vw", height: 80, backgroundColor: "lightblue"}}>
<button onClick={() => themeToggler()}>Change Theme</button>
<Link to="/" style={{margin: 50}}>Home</Link>
<Link to="/works" style={{margin: 50}}>Projets</Link>
<Link to="/about" >L'agence</Link>
</div>
// END OF NAVBAR
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" exact component={About} />
<Route path="/works" exact component={Works} />
<Route path="/works/:name-study-case" exact component={StudyCase} />
<Route path="*" exact component={PageNotFound} />
</Switch>
</Router>
</StyledApp>
</ThemeProvider>
)
}
export default App;
Themes.js
import {createGlobalStyle} from 'styled-components';
export const lightTheme = {
body: "#fff",
fontColor: "#000"
}
export const darkTheme = {
body: "#000",
fontColor: "#fff"
}
export const GlobalStyles = createGlobalStyle`
body {
background-color: ${props => props.theme.body}
}
`
You set the styling "manually" here:
style={{width: 100 + "vw", height: 80, backgroundColor: "lightblue"}
That will always override your theme stylesheet due to CSS precedence rules. Get rid of that and it should all work fine.
Is Pass Object in style?
let styles = {
backgoungColor: "red;
}
return(<div style={styles}></div>);
I have successfully increased the Label in the TextField of my React app.
My problem is that when its on shrink, it just overlaps some line on its right.
Click Here
import React from "react";
import TextField from "#material-ui/core/TextField";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
root: {
"& .MuiInputLabel-shrink": {
fontSize: "24px"
}
}
}));
export default function CustomTextField({ InputLabelProps = {}, ...props }) {
const classes = useStyles();
return <TextField {...props} className={classes.root} />;
}
I would encourage you to always use the DevTools when it comes to applying customizations. The size of the gap it determined by the <legend> element:
The element's font size has a font-size: 0.75em to account for the CSS transformation.
So you can simply apply the same font size to its parent:
import React from "react";
import TextField from "#material-ui/core/TextField";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
root: {
"& .MuiInputLabel-shrink, & fieldset": {
fontSize: "24px"
}
}
}));
export default function CustomTextField({ InputLabelProps = {}, ...props }) {
const classes = useStyles();
return <TextField {...props} className={classes.root} />;
}
https://codesandbox.io/s/material-ui-custom-textfield-composition-forked-g5co7?file=/src/CustomTextField.js
You should use the Shrink as prop for TextField
Remove fontSize: "24px" let it resize by Material-UI
Make sure your TextField as:
<TextField InputLabelProps={{shrink: true}} .../>
if you want to customize the size of the label:
fontSize: 30,
color: "red",
"&$labelFocused": {
color: "purple"
}
},
labelFocused: {}
};
function App({ classes }) {
return (
<div className="App">
<TextField
id="standard-with-placeholder"
label="Your Label"
InputLabelProps={{
classes: {
root: classes.labelRoot,
focused: classes.labelFocused
}
I'm trying to make sense of how to inject styles into component with MaterialUI and I'm very confused! Can anyone please explain what I did wrong? i read the documentation but it honestly didn't make sense to me. What are classes? And how do I attach the const style into the component BeerList?
My code threw an error "Cannot read property of classes undefined. I know I must have pulled from the wrong props. But I don't know how to fix it...
import React from 'react';
import BeerListItem from './BeerListItem';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import GridList from '#material-ui/core/GridList';
import GridListTile from '#material-ui/core/GridListTile';
import GridListTileBar from '#material-ui/core/GridListTileBar';
import IconButton from '#material-ui/core/IconButton';
import StarBorderIcon from '#material-ui/icons/StarBorder';
const styles = theme => ({
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
overflow: 'hidden',
backgroundColor: theme.palette.background.paper,
},
gridList: {
width: '100%',
height: '100%',
transform: 'translateZ(0)',
},
titleBar: {
background:
'linear-gradient(to bottom, rgba(0,0,0,0.7) 0%, ' +
'rgba(0,0,0,0.3) 70%, rgba(0,0,0,0) 100%)'
},
icon: {
color: 'white',
},
});
const BeerList = ({beers}) =>{
const {classes} = beers;
const beerItems = beers.map((beer) => {
return <BeerListItem key={beer.id} beer = {beer}/>
});
return (<div className={classes.root} >
<GridList cellHeight={250} spacing={1} >
{beerItems}
</GridList>
</div>);
};
export default withStyles(styles)(BeerList);
classes distructured from props.
you need a little change on your components like:
const BeerList = (props) =>{
const {classes, beers} = props;
// rest of your code
return <div className={classes.root} >
<GridList cellHeight={250} spacing={1} >
{beerItems}
</GridList>
</div>
};
That's it.