ReactJS changing styles with const strings - css

Hi I am trying to change the styles of a component using a const string but it does not work. May I know why this approach is wrong?
style={{ color: {newColor} }}

No need to use brackets again
style={{ color: newColor }}

Related

How can a prop value be used in an Stitches js component?

How to pass a prop value into a Stitchesjs component and use it in the component definition?
This is a common pattern in styled-components. In Stitches, however, I can't seem to find a way. Take this component for example:
const Spacer = styled('div', {
'16': {marginBottom: '$16'},
variants: {
size: {
'20': {marginBottom: '$20'}
}
}
});
Instead of creating 10 variants, I want to pass the amount trough a prop:
<Spacer size={'30px'} />
or even better:
<Spacer size={'$sizes$3'} />
How can I use this value so that the marginBottom matches whatever I give it?
Take a look at https://stitches.dev/docs/utils.
And then you can use like this:
<div css={{ mb: '$40' }} />
I was looking for this answer and tried a few different ways.
The easiest way for me turned out to be locally scoped theme-tokens.
So your styled component would look like this:
const Spacer = styled('div', {
marginBottom: '$$marginSize',
});
And then pass the locally scoped token into the css prop:
<Spacer css={{ $$marginSize: '$sizes$3' }} />
There was a discussion on Stitches Github about the possibility to pass dynamic values as property.
But the goal of stitches is to have the smallest runTime possible, so it was not implemented !
Github PR stitches
When you need to use a JSX variable in stitches that can be any value, one solution would be to use CSS variables;
All stitches elements get the css property, and you can pass new properties through it!
Styled component:
export const Box = styled('div', {
marginTop: 'var(--margin-top)',
backgroundColor: 'red',
width: '200px',
height: '200px',
})
Component:
export function Hero({props = 200 }) {
const variableExample = `${props}px`
return (
<>
<Box css={{ '--margin-top': '10px' }} />
<Box css={{ '--margin-top': '150px' }} />
<Box css={{ '--margin-top': variableExample }} />
</>
)
}
By far the best solution that has worked for me for this very problem. simplifies the code and is better to maintain later!

What is the use of '& .MuiTextField-root' in { makeStyles } of Material UI?

I am making a project in React JS through some resources using Material-UI. I was creating in Form.js file for my app, and there was some styling given to that as shown below ---
import useStyles from './styles';
const classes = useStyles();
<form autoCapitalize='off' noValidate className={`${classes.root} ${classes.form}`} onSubmit={handleSubmit}> ```
In styles.js --
export default makeStyles((theme) => ({
root: {
'& .MuiTextField-root': {
margin: theme.spacing(1),
},
},
form: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'center',
}
}));
Now I am not able to understand the use of
'& .MuiTextField-root': {
margin: theme.spacing(1),
}
Can anyone please help me with this like what is the use of '& .MuiTextField-root' ??
When I try to simply use the
margin: theme.spacing(1),
its not giving margin from top and bottom, but its giving very less margin
from left and right. But using the Former one gives equal and more margin
from each side to all the textfields and Buttons in the . Why is it so?? Any help will be appreciated. Thanks!
Attaching the Screenshot ---FORM Image with '& .MuiTextField-root'
FORM Image WithOut '& .MuiTextField-root', just using root: {margin: theme.spacing(1)} only
If you know SCSS then this is the convention to select the child selector to write class for. As you are using it in a form. So the text fields are the child of the form. That's why you have to access/write it like this.
The following code actually mean, any child containing the class name MuiTextField-root will have the margin css rules in it. Doc
'& .MuiTextField-root': {
margin: theme.spacing(1),
}
& .MuiTextField-root would mean any children of current element with that class
You can use the browser dev tools to identify the slot for the component you want to override. It can save you a lot of time. The styles injected into the DOM by MUI rely on class names that follow a simple pattern: [hash]-Mui[Component name]-[name of the slot].
⚠️ These class names can't be used as CSS selectors because they are unstable, however, MUI applies global class names using a consistent convention: Mui[Component name]-[name of the slot].
If you would like to override the styles of the components using classes, you can use the className prop available on each component. For overriding the styles of the different parts inside the component, you can use the global classes available for each slot, as described in the previous section.

CSS Word break when importing string from json not work

I am importing json file like that and pass it as prop to all componentts.
const lang = require(`./languages/${language}.json`);
setLanuageJson(lang);
Then use it particular component
const t = props.languageJson;
<AccordionDetails style={{ padding: '0 0.5em' }}>
<Typography className={classes.link}>{t['38']}</Typography>
</AccordionDetails>
Here is my css
link: {
color: '#A3A3A3',
lineBreak: 'anywhere',
padding: '0 5px',
...theme.typography.internbody,
// fontSize: '0.6em',
},
Without lineBreak: 'anywhere' the whole content is coming in one line like that.
When using lineBreak: 'anywhere' some of the words are breaking
Any solutions please

How can I imitate the look of the outline and label from Material-UI's outlined textfield?

I'm trying to imitate the outlined textfield from Material-UI but I don't know how to hide the border behind the title text.
In the below image, notice how the "Due Date/Time" is taken from the Material-UI library and the title hides the border behind it but when I tried to imitate it with a custom component I just couldn't hide the border.
Alternatively, Is there a better way to use this outline design instead of just implementing it with CSS?
My current component looks liks this:
<div style={inputContainerStyle}>
<div style={{
...titleStyle,
transform: 'translate(-43px, -11px) scale(0.75)',
fontSize: '17px',
color: 'rgba(0, 0, 0, 0.54)',
position: 'absolute',
}}
>
Color
</div>
<div
className="flex-row"
style={{
border: '1px solid rgba(0, 0, 0, 0.23)',
padding: '18.5px 14px',
borderRadius: '4px',
}}
>
{
availableColors.map(color => <div style={colorCircleStyle(color)} />)
}
</div>
</div>
UPDATE
For many scenarios, my later answer (which avoids using TextField and therefore has no side-effects on FormControl context) may be more appropriate: How can I set an static outlined div similar to Material-UI's outlined textfield?
There is a great deal of flexibility in what you can do with TextField. TextField supports plugging in different types of inputs (e.g. Select, input, custom pickers) via the inputComponent property. You could leverage this to put anything inside its labelled outline by creating a custom component like this OutlinedDiv:
import React from "react";
import TextField from "#material-ui/core/TextField";
const InputComponent = ({ inputRef, ...other }) => <div {...other} />;
const OutlinedDiv = ({ children, label }) => {
return (
<TextField
variant="outlined"
label={label}
multiline
InputLabelProps={{ shrink: true }}
InputProps={{
inputComponent: InputComponent
}}
inputProps={{ children: children }}
/>
);
};
export default OutlinedDiv;
The className passed to the inputComponent takes care of the CSS that makes this all work. You can then use this like in the following:
import React from "react";
import ReactDOM from "react-dom";
import OutlinedDiv from "./OutlinedDiv";
import Avatar from "#material-ui/core/Avatar";
import deepOrange from "#material-ui/core/colors/deepOrange";
import deepPurple from "#material-ui/core/colors/deepPurple";
import red from "#material-ui/core/colors/red";
import green from "#material-ui/core/colors/green";
import blue from "#material-ui/core/colors/blue";
import Grid from "#material-ui/core/Grid";
function App() {
return (
<div className="App">
<OutlinedDiv label="Color Picker">
<Grid container justify="center" alignItems="center">
<Avatar style={{ backgroundColor: deepOrange[500] }} />
<Avatar style={{ backgroundColor: deepPurple[500] }} />
<Avatar style={{ backgroundColor: red[500] }} />
<Avatar style={{ backgroundColor: green[500] }} />
<Avatar style={{ backgroundColor: blue[500] }} />
</Grid>
</OutlinedDiv>
<br />
<br />
<OutlinedDiv label="Custom Outlined Thing">
You can put whatever you want in here.
</OutlinedDiv>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
No need to write Outlined div component and all. As we can achieve this using FormControl, FormLabel and Formgroup.
If you follow the Outlined div logic your input fields will lose focus.
The below solution is very easy and quick you just need to wrap your code:
<FormControl component="fieldset" className="fieldset">
<FormLabel component="Legend">Title</FormLabel>
<FormGroup row>
{/*Your Input fields e.g TextField or Select e.t.c*/}
</FormGroup>
</FormControl>
Now using useStyles apply some css:
fieldset: {
width: '100%',
marginBottom: 10,
padding: 10,
border: '1px solid #ddd',
borderRadius: 5
}
The outlined textfield was really tricky to implement. When pushing that feature, we had to consider several options, each with their own drawbacks
SVG Element
Easy to build and animate, but tough to scale with the surrounding elements. If we had gone this route, we would have needed to listen for some type of resize event, which would mean either using a window resize event, which is not robust, or using a newer and less supported feature such as a ResizeObserver/MutationObserver. There are polyfills, but that would have increased the bundle size about 2K for a relatively small feature.
The SVG route is likely what will be used in the future. It is also worth noting that this is how Google's Material Components Web solves the problem.
Plain old border with a background on the label
This is by far the simplest approach, but it is also somewhat inflexible. You can see an example of this in Google's new sign-in flow. There they actually set the background color to white. This is probably a fine approach for plenty of users, but of course won't work if your background is a gradient or some similar edge case. That said, there's no need to worry about resize because it's just a border.
Fieldset and legend
This is what we ended up going with, largely because of its flexibility for end users. Fieldset and its legend component are both built-in ways of attaining pretty much this exact functionality. The big drawbacks to this are that styling across browsers is tough, and the properties we'd be animating on are not performant, such as legend width. Additionally, it's always best to use semantic HTML of course, which this is not, which means we need to use aria-hidden to instruct screen readers to ignore the element.
Depending on your goals, any one of these solutions may work best for you. Beware that getting the perfect solution that solves all of these problems may be very tricky!
Just apply the same background color on the color div as the parent's background color, you can do it by background-color: inherit like this:
<div style={inputContainerStyle}>
<div style={{
...titleStyle,
transform: 'translate(-43px, -11px) scale(0.75)',
fontSize: '17px',
color: 'rgba(0, 0, 0, 0.54)',
position: 'absolute',
background-color:'inherit' **(just add this line)**
}}
>
Color
</div>
<div
className="flex-row"
style={{
border: '1px solid rgba(0, 0, 0, 0.23)',
padding: '18.5px 14px',
borderRadius: '4px',
}}
>
{
availableColors.map(color => <div style={colorCircleStyle(color)} />)
}
</div>
</div>

MaterialUI how to align text inside an Input to the right or center?

How to align text of a Material UI input text? Following does not seem to work. Im using version 1.x
import {Input} from 'material-ui';
//didn't work
<Input
className="max-w-128 inline-block"
style = {{textAlign: 'center'}}
id="input-quantity"
inputStyle={{ textAlign: 'center' }}
//tried hintStyle as suggested in a bug
hintStyle={{ width: '600px', textAlign: 'center' }}
value={this.state.currentRecord.quantity}
onChange={this.handleCurrentRecordTextChange('quantity')}
/>
you just need to use (with styles overriding) :
classes={{
input: classes.inputCenter
}}
and the styles should be:
const styles = theme => ({
inputCenter: {
textAlign: "center",
color: "red"
}
});
go through the documentation from here: https://material-ui.com/api/input/#css-api
here is a working example: https://codesandbox.io/s/n9nr9x8xo0
hope this will help you.
Please Use
<Typography align="centre|right" />
If you have specific font already set then use above solution with withStyle HOC

Resources