In the following you will see that my makeStyles style is not being picked up properly. I'm trying to figure out why. I've reduced the code to not much more than the App component, and a simple Experiment component rendered from within the App.
One particular point of interest, when I refresh the page, I see the correct style flashed on the screen momentarily before it is replace with the incorrect style.
I am using MUI 5.6 and I think I have followed the guides for styling.
I have an App:
const theme = createTheme({
status: {
danger: "#ff0000",
},
});
const App = (props) => {
let app;
app = <>
{typeof theme != "undefined" && (
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<CssBaseline />
<Experiment />
</ThemeProvider>
</StyledEngineProvider>
)}
</>
return (
<div>
{app}
</div>
);
};
The "Experiment" code rendered within the App:
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import Grid from "#mui/material/Grid";
import Typography from "#mui/material/Typography";
import makeStyles from '#mui/styles/makeStyles';
import { useTheme } from "#mui/material/styles";
import useMediaQuery from "#mui/material/useMediaQuery";
const useStyles = makeStyles((theme) => ({
paper: {
width: "100%",
marginBottom: theme.spacing(2),
},
root: {
backgroundColor: theme.palette.background.default,
},
pageTitle: {
backgroundColor: theme.palette.secondary.main,
borderColor: theme.palette.text.primary,
borderWidth: (props) => props.title.borderWidth,
borderStyle: (props) => props.title.borderStyle,
padding: (props) => props.title.padding,
textAlign: (props) => props.title.textAlign,
verticalAlign: (props) => props.title.verticalAlign,
},
pageControl: {
backgroundColor: theme.palette.secondary.light,
borderColor: theme.palette.text.primary,
borderWidth: (props) => props.control.borderWidth,
borderStyle: (props) => props.control.borderStyle,
height: (props) =>
props.control.height === undefined ? "auto" : props.control.height,
textAlign: (props) => props.control.textAlign,
overflow: (props) =>
props.control.overflow === undefined ? "auto" : props.control.overflow,
padding: (props) => props.control.padding,
verticalAlign: (props) => props.control.verticalAlign,
},
pageContent: {
width: "100%",
backgroundColor: theme.palette.secondary.dark,
borderColor: theme.palette.text.primary,
borderWidth: (props) => props.content.borderWidth,
borderStyle: (props) => props.content.borderStyle,
height: (props) =>
props.content.height === undefined ? "auto" : props.content.height,
overflow: (props) =>
props.content.overflow === undefined ? "auto" : props.content.overflow,
padding: (props) => props.content.padding,
textAlign: (props) => props.content.textAlign,
verticalAlign: (props) => props.content.verticalAlign,
},
}));
export default function Experiment() {
const page_configuration = useSelector((state) => state.configuration.page);
const theme = useTheme();
let contentStyle;
contentStyle = { ...page_configuration.content };
let titleStyle;
titleStyle = { ...page_configuration.title };
let controlStyle;
controlStyle = { ...page_configuration.control };
let style = {
...page_configuration,
content: contentStyle,
title: titleStyle,
control: controlStyle,
};
const classes = useStyles({ ...style });
return (
<Grid container className={classes.root}>
<Grid xs={12} item className={classes.pageTitle} >
<Typography>{"title"} </Typography>
</Grid>
<Grid
xs={12}
item
className={classes.pageControl}
>
{"control"}
</Grid>
<Grid
xs={12}
item
className={classes.pageContent}
>
{"content"}
</Grid>
</Grid>
);
}
A simpler Experiment component that also shows the problem:
return (
<Box height="100vh" display="flex" flexDirection="column">
<Box className={classes.pageTitle} >{"Expriment"}</Box>
<Box className={classes.pageControl} >{"Control"}</Box>
<Box className={classes.pageContent} flex={1} overflow="auto">{"Content"}</Box>
</Box>
);
The rendered screen:
If I save the App.js or Experiment.js file then the rendered screen picks up the styling that it should pick up:
If I examine the sytling and peek at the "title" portion of this page, before Saving App.js I see the following:
After I save App.js I see the proper makeStyles.
On first render there are 2 makeStyles style elements in header.
After the save I see additional makeStyle styles in header.
My dependencies:
"dependencies": {
"#date-io/date-fns": "^2.14.0",
"#emotion/react": "^11.9.0",
"#emotion/styled": "^11.8.1",
"#mui/icons-material": "^5.6.0",
"#mui/material": "^5.6.0",
"#mui/styles": "^5.6.0",
"#mui/x-date-pickers": "^5.0.0-alpha.7",
"#react-keycloak/web": "^3.4.0",
"#reduxjs/toolkit": "^1.5.0",
"#testing-library/jest-dom": "^5.11.9",
"#testing-library/react": "^11.2.5",
"#testing-library/user-event": "^12.8.3",
"#types/react": "^18.0.0",
"#types/react-dom": "^18.0.0",
"axios": "^0.21.1",
"capture-video-frame": "^1.0.0",
"clsx": "^1.1.1",
"date-fns": "^2.23.0",
"hls.js": "^1.0.0",
"keycloak-js": "^18.0.0",
"leaflet": "^1.7.1",
"leaflet.markercluster": "^1.5.1",
"lodash": "^4.17.21",
"material-table": "^1.69.3",
"moment": "^2.29.1",
"prop-types": "^15.7.2",
"query-string": "^7.1.1",
"querystring": "^0.2.1",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-draggable": "^4.4.3",
"react-json-view": "^1.21.3",
"react-leaflet": "^3.2.1",
"react-leaflet-markercluster": "^3.0.0-rc1",
"react-player": "^2.9.0",
"react-redux": "^7.2.2",
"react-resize-detector": "^6.7.6",
"react-rnd": "^10.2.4",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.0",
"redux": "^4.0.5",
"redux-saga": "^1.1.3",
"screenfull": "^5.1.0",
"socket.io-client": "^4.1.3",
"status-indicator": "^1.0.9",
"styled-components": "^5.2.1",
"superagent": "^6.1.0",
"use-deep-compare-effect": "^1.6.1",
"use-resize-observer": "^7.0.0",
"uuid": "^8.3.2",
"video.js": "^7.11.8",
"web-vitals": "^1.1.0"
},
It looks like my answer is easy. I need to eliminate use of makeStyles. All I needed to do was to set the sx prop to the structure I had used in makeStyles.:
<Box height="100vh" display="flex" flexDirection="column">
<Box sx={titleStyle} >{"Expriment"}</Box>
<Box sx={controlStyle} >{"Control"}</Box>
<Box className={classes.pageContent} flex={1} overflow="auto">{"Content"}</Box>
</Box>
In the previous the 3rd box is the old deprecated way. The first 2 boxes (using sx), worked fine.
Related
I want to submit a form when I stop type, I'm using react hook form and call the handleSubmit in a function and it doesn't work, please help me, this is my code, I'm doing a map of this code, I've tried with ref but it doesn't work. This is my component.
import React, {useRef} from 'react';
import {View, Text, TextInput, TouchableOpacity} from 'react-native';
import tailwind from 'tailwind-rn';
import {useDebounce} from 'use-debounce';
import {useForm, Controller} from 'react-hook-form';
import {MAIN_COLOR, GRAY} from '../../constants/theme';
function RegisterFormHook({data, onSubmit, control, errors}) {
const [underlineColor, setUnderlineColor] = React.useState(GRAY);
const [field, setField] = React.useState('');
const [value] = useDebounce(field, 1000);
const inputElement = useRef();
const {handleSubmit} = useForm();
React.useEffect(() => {
if (value.length !== 0) {
handleSubmit(onSubmit({[data.name]: value}));
}
console.log(errors);
}, [value]);
const onFocus = () => {
setUnderlineColor(MAIN_COLOR);
};
const onBlur = () => {
setUnderlineColor(GRAY);
};
return (
<View style={tailwind('px-8')}>
<Controller
control={control}
name={data.name}
rules={data.rules}
render={({field: {onChange, value}}) => (
<TextInput
placeholder={data.placeholder}
ref={inputElement}
style={[
tailwind('text-black p-0 text-xl pb-1 flex-row'),
{
borderBottomWidth: 1,
borderBottomColor: underlineColor,
},
]}
onChangeText={value => {
onChange(value);
setField(value);
}}
onBlur={onBlur}
value={value}
onFocus={() => onFocus()}
/>
)}
/>
<Text>{errors[data.name]?.message}</Text>
</View>
);
}
export default RegisterFormHook;
I want to submit in the useEffect but it just works when I press a button.
Here is a sample how you could implement scheduled action after input has been completed:
import * as React from 'react';
import { TextInput, View, StyleSheet, Alert } from 'react-native';
import Constants from 'expo-constants';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App() {
let timer = React.useRef();
const [text, setText] = React.useState('');
React.useEffect(() => {
if (text) {
timer = setTimeout(() => {
Alert.alert('TEXT : ' + text);
}, 3000);
}
}, [text]);
return (
<View style={styles.container}>
<Card>
<TextInput
placeholder={'Enter the tetxt'}
onChange={(e) => {
clearTimeout(timer);
setText(e.nativeEvent.text);
}}
/>
</Card>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});
I am using material ui on a react-typescript project and need the bio to be mostly hidden until the show more button is pressed. In the docs for Collapse from material-ui it says you can pass in a number value for timeout and it will determine the amount of time that the transition takes to expand the card. However, I have passed in a large number here and the transition still only takes less than a second. Should I be passing the timeout prop in differently?
export default function ProfileBio({ bio }: Props) {
const [expandBio, setExpandBio] = useState<boolean>(false);
const [animation, setAnimation] = useState({});
const classes = useStyles();
const [bioHeight, setBioHeight] = useState(classes.notExpanded);
// bio
const BIO = [
{
name: 'Bio',
icon: <IconStyle icon={fileTextOutline} />,
content: bio
}
];
const fields = [
{
name: 'bio',
content: bio,
displayName: 'Bio'
}
];
const handleExpandClick = () => {
setExpandBio(!expandBio);
};
const CurrentContent: Function = () => {
return BIO.map((bioField) => (
<DetailsWrapper key={bioField.name}>
<Collapse
sx={{ mt: 0 }}
collapsedSize={72}
in={expandBio}
easing="ease"
timeout={60000}
onEnter={() => console.log('entered')}
>
<Typography
variant="body2"
color="text.primary"
style={{ whiteSpace: 'pre-wrap' }}
// className={bioHeight}
>
{bioField.icon}
{bioField.content}
</Typography>
</Collapse>
</DetailsWrapper>
));
};
const ShowMoreButton: Function = () => {
if (!edit) {
return (
<ExpandMore
stretchedLink
expand={expandBio}
onClick={handleExpandClick}
aria-expanded={expandBio}
aria-label="show more"
>
<Typography variant="button">
show
{expandBio ? 'less' : 'more'}
</Typography>
<ExpandMoreIcon className="chevron" />
</ExpandMore>
);
}
return <Box />;
};
return (
<Card>
<CardHeader
title="Bio"
action={
<IconButton
onClick={() => {
setEdit(!edit);
}}
>
<CreateIcon />
</IconButton>
}
/>
<CardContent>
<CurrentContent />
</CardContent>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
backgroundColor: '#FFFFFF'
}}
>
<ShowMoreButton />
</Box>
</Card>
);
}
I'm looking for a text field with multiple inputs as:
Here as you can see I can add new text and on press of enter it saves that keyword.
Can someone guide which package to look for.... I found something similar in material ui autocomplete's costomized hook: https://material-ui.com/components/autocomplete/,
but I don't want it to be drop down I want it to be simply be a text field with option as shown in image.
I cannot find with such functionality or I might be looking work as I don't know proper term for it.
Any guidance will be of great help.
I've included material-ui , reactstrap as this is something I have worked with so if there is any other package also let me know
I was also building something like this few days back. This is what I've built till now.
import {
Chip,
FormControl,
Input,
makeStyles,
} from "#material-ui/core";
import React, { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
const classes = useStyles();
const [values, setValues] = useState(["test"]);
const [currValue, setCurrValue] = useState("");
const handleKeyUp = (e) => {
console.log(e.keyCode);
if (e.keyCode == 32) {
setValues((oldState) => [...oldState, e.target.value]);
setCurrValue("");
}
};
useEffect(() => {
console.log(values);
}, [values]);
const handleChange = (e) => {
setCurrValue(e.target.value);
};
const handleDelete = ( item, index) =>{
let arr = [...values]
arr.splice(index,1)
console.log(item)
setValues(arr)
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<FormControl classes={{ root: classes.formControlRoot }}>
<div className={"container"}>
{values.map((item,index) => (
<Chip size="small" onDelete={()=>handleDelete(item,index)} label={item}/>
))}
</div>
<Input
value={currValue}
onChange={handleChange}
onKeyDown={handleKeyUp}
/>
</FormControl>
</div>
);
}
const useStyles = makeStyles((theme) => ({
formControlRoot: {
display: "flex",
alignItems: "center",
gap: "8px",
width: "300px",
flexWrap: "wrap",
flexDirection: "row",
border:'2px solid lightgray',
padding:4,
borderRadius:'4px',
"&> div.container": {
gap: "6px",
display: "flex",
flexDirection: "row",
flexWrap: "wrap"
},
"& > div.container > span": {
backgroundColor: "gray",
padding: "1px 3px",
borderRadius: "4px"
}
}
}));
Here is the working demo:
One possible way to do this using react-hook-form and Autocomplete using the Chip with renderTags function here is an example:
import {
Box,
TextField,
Autocomplete,
Chip,
} from '#mui/material'
...
const {
handleSubmit,
control,
formState: { errors },
} = useForm()
...
<Box mt={2}>
<Controller
control={control}
name="tags"
rules={{
required: "Veuillez choisir une réponse",
}}
render={({ field: { onChange } }) => (
<Autocomplete
defaultValue={
useCasesData?.tags ? JSON.parse(useCasesData?.tags) : []
}
multiple
id="tags-filled"
options={[]}
freeSolo
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip
variant="outlined"
label={option}
{...getTagProps({ index })}
/>
))
}
onChange={(event, values) => {
onChange(values);
}}
renderInput={(params) => (
<TextField
{...params}
label="Métadonnées"
placeholder="Ecriver les métadonnées"
helperText={errors.tags?.message}
error={!!errors.tags}
/>
)}
/>
)}
/>
</Box>
Im building a design system which uses Material UI under the hood. I need to customise the design of a disabled checkbox.
In this code why is the disabled style setting the color to gold not being applied?
import CheckboxMUI from '#material-ui/core/Checkbox';
import CheckBoxOutlineBlankIcon from '#material-ui/icons/CheckBoxOutlineBlank';
import FormControlLabel from '#material-ui/core/FormControlLabel';
const Checkbox = ({ label, onChange, checked, disabled }) => {
const theme = useTheme();
const useStyles = makeStyles({
root: {
color: theme.palette.secondary.main,
'&$disabled': {
color: 'gold',
},
},
});
const classes = useStyles();
return (
<div>
<FormControlLabel
disabled={disabled}
classes={{
root: classes.root,
}}
control={
<CheckboxMUI
disabled={disabled}
checked={checked}
onChange={onChange}
name="checkedA"
color="primary"
icon={
<CheckBoxOutlineBlankIcon
htmlColor={!disabled ? theme.palette.secondary.main : undefined}
/>
}
/>
}
label={label}
/>
</div>
);
};
Material UI's <Checkbox> allows you to provide custom elements for the icon, checkedIcon and indeterminateIcon. In your case, something along these lines would solve your problem:
import React from 'react'
import {
Checkbox as MUICheckbox,
CheckboxProps,
SvgIcon,
} from '#material-ui/core'
import { ReactComponent as CheckboxChecked } from 'assets/svg/ui/CheckboxChecked.svg'
import { ReactComponent as CheckboxUnchecked } from 'assets/svg/ui/CheckboxUnchecked.svg'
import { ReactComponent as CheckboxIndeterminate } from 'assets/svg/ui/CheckboxIndeterminate.svg'
import { ReactComponent as CheckboxDisabled } from 'assets/svg/ui/CheckboxDisabled.svg'
export default function Checkbox(props: CheckboxProps) {
return (
<MUICheckbox
checkedIcon={<SvgIcon component={CheckboxChecked} />}
indeterminateIcon={<SvgIcon component={CheckboxIndeterminate} />}
icon={
<SvgIcon
component={props.disabled ? CheckboxDisabled : CheckboxUnchecked}
/>
}
{...props}
/>
)
}
Which you would then use as follows (which is exactly how I solved this problem):
<Checkbox
disabled={someCondition}
/>
This worked for me:
const useStyles = makeStyles({
root: {
color: theme.palette.secondary.main,
},
label: {
'&.Mui-disabled': {
color: theme.colors.disabledForeground,
},
},
});
<FormControlLabel
disabled={disabled}
classes={{
root: classes.root,
label: classes.label,
}}
I'm quite new in webdevelopment. With that said, I'm trying to change the box color using Material-UI but it's not working. (color=success.main)
Currently, the color that I'm getting is the primary blue. I've tried to change every box component but It didn't really work for any of them.
import React from "react";
import { palette } from '#material-ui/system';
import {
AppBar,
Toolbar,
Box,
Link,
Hidden
} from '#material-ui/core';
import { makeStyles } from '#material-ui/core/styles';
import './Navbar.css';
const useStyles = makeStyles({
links: {
padding: '0 50px',
color: 'white',
"&:hover": {
textDecorationColor: "green",
cursor:'pointer'
}
},
});
export default function Navbar() {
const Navbar = useStyles();
return(
<Box component='nav' color="success.main">
<AppBar>
<Toolbar>
VK Design
<Box m='auto'>
<Hidden only='xs'>
<typography><Link className={Navbar.links} underline='hover'>HOME</Link></typography>
<typography><Link className={Navbar.links} underline='hover'>PORTFOLIO</Link></typography>
<typography><Link className={Navbar.links} underline='hover'>ABOUT</Link></typography>
<typography><Link className={Navbar.links} underline='hover'>CONTACT</Link></typography>
</Hidden>
</Box>
</Toolbar>
</AppBar>
</Box>
)
};
Use "bgcolor" instead of "color"
<Box
bgcolor="primary.main"
> ... </Box>
I think you should define a class to set color for .
You should try:
...
const useStyles = makeStyles((theme) => ({
root: {
color: theme.palette.primary.main
},
links: {
padding: '0 50px',
color: 'white',
"&:hover": {
textDecorationColor: "green",
cursor:'pointer'
}
},
}));
export default function Navbar() {
const Navbar = useStyles();
return(
<Box component='nav' className={Navbar.root}>
...
</Box>
)
};