When using npm run build in my react app (create-react-app),
it fails to compile and gives me the message Cannot read property 'toLowerCase' of undefined.
I am not using toLowerCase in my app and figured the only place where this is used is in the script : node_modules/react-scripts/scripts/build.js in this piece of code:
if (
process.env.CI &&
(typeof process.env.CI !== 'string' ||
process.env.CI.toLowerCase() !== 'false') &&
messages.warnings.length
) {
console.log(
chalk.yellow(
'\nTreating warnings as errors because process.env.CI = true.\n' +
'Most CI servers set it automatically.\n'
)
);
return reject(new Error(messages.warnings.join('\n\n')));
}
What seems strange to me is that even there, it should not even give me Cannot read property 'toLowerCase' of undefined because if processe.env.CI was undefined it should read the first conditional statement as false-y and not even read processe.env.CI.toLowerCase.
Also I have tried deleting this whole section of code and I get the same error.
I have another react-app and the npm run build command works just fine, so I am really at loss wondering where I should even look for the answer.
Ok,
this is very weird but here is what my problem was:
.collage{
margin: ;
display: flex;
flex-wrap:wrap;
justify-content: space-between;
align-items: stretch;}
I had a typo for my margin value, and this simple bug was what was blocking the wole thing and giving me a toLowerCase issue!!!!
I would have never guessed !
I had the same problem because of "important" at border-width:
&.checkbox-accent {
> span {
border-width: get($checkbox-config, types, accent, borderWidth) !important;
border-style: solid !important;
background-color: transparent !important;
&:after {
display: block;
}
}
}
In my case error message was:
Cannot read property 'toLowerCase' of undefined
CompileError: Begins at CSS selector .checkbox.checkbox-accent>span
so i was able to find an exact file & row
I had the same issue cause with !important being used where variable where undefined:
.form-checkbox,
.form-radio {
input {
&:checked {
background-color: color-bg(check-checked-inverse) !important;
border-color: color-bg(check-checked-inverse) !important;
}
}
}
It could be fixed with :
.form-checkbox,
.form-radio {
input {
&:checked {
background-color: color-bg(check-checked-inverse);
border-color: color-bg(check-checked-inverse);
}
}
}
Or by settings the variable check-checked-inverse.
I am not using toLowerCase in my app
Well you clearly are when calling build.js.
Either way, in an if() statement, each individual statement will be tested. It won't "break out" if say the first fails.
As you have not set the environment property 'CI' then this if statement will always fails as process.env.CI will always be undefined/null.
.toLowerCase() is a method that will NOT work on nulls.
Related
In a project, I was using SCSS, where I wrote this code and it works like a charm:
.container {
padding: 0 1rem;
.container {
padding: 0;
}
}
Now, I am starting another project using styled-components. So, there I am writing these styles:
const Container = styled.div`
padding: 0 1rem;
${Container} {
padding: 0;
}
`;
Now I get a warning from compiler saying:
Container was used before it was defined.
I want to ignore this warning without making any changes to eslint-file or disabling eslint for the line itself. I also don't want to use var instead of const.
Also, I am not willing to use a class on the div and then use it again here. (I would consider this as the last option if I do not find any better way of doing this).
Is there any better way that I can change this code to ignore this warning?
If I understand your question/issue it seems you want to reference the same container component. Use & to refer back to the main component.
Using pseudoelements, pseudoselectors, and nesting
const Container = styled.div`
padding: 0 1rem;
& {
padding: 0;
}
`;
I am using an ExpansionPanel,
where I control the expanded state based on some conditions.
Although, I want the ExpansionPanel to be always expanded, when I am printing (window.print()).
What I intuitively wanted to try was:
//...
const isPrinting = useMediaQuery("print")
const controlledExpanded = useSomeMethodToControlExpanded()
const expanded = isPrinting || controlledExpanded
return (
<ExpansionPanel expanded={expanded}>
{/*...*/}
</ExpansionPanel>
)
Although this won't work because of a bug in browsers:
Maybe somehow override the global styling would help, but I cannot figure out how.
Any ideas?
You can use #media print in your css:
#media print {
div.MuiCollapse-container.MuiCollapse-hidden {
min-height: auto !important;
height: auto !important;
visibility: visible !important;
}
}
No need for anything in the react component
I am trying to set dynamically and image like this:
const IntroVideoWrapper = styled.div`
background-image: url("../images/${(props)=>props.image_prefix}_427.png");
`;
However, the image is not being displayed. when I look in the debugger tools, it is being parsed like:
background-image: url("../images/" + selfie + "_427.png" )
instead of:
background-image: url("../images/selfie_427.png" )
What is wrong?
The callback function has to return the entire string like the following
background: ${props => `url('../images/${props.selfie}_427.png.jpg')`};
Sandboxed
You made a mistake in using `` in first you tried.
background-image: url(${props => `../images/${props.image_prefix}_427.png`});
I have an external Select react component which in turn render li tags.
I want to style all li except the first one with margin-left of 20px;
Below is the code:
const StyledSelect = styled(Select)`
li {
margin-left: 20px;
}
`
Any idea why this is not working or another way to do this?
This should work, but depending on how the external Select has the styles applied they might have a higher specificity and are still overriding the styles you applied. (see this article for a primer on how specificity works)
Without knowing which Select component you're using it's a bit hard to debug, but I'm assuming it uses inline styles (i.e. the style prop) which have a very high specificity and would thus override your applied styles.
There's two ways to bump specificity of your styles, both of which are not recommended if the external component doesn't use inline styles.
The first way to bump specificity is to use !important:
const StyledSelect = styled(Select)`
li {
margin-left: 20px!important;
}
`
In some cases that might not suffice, and it's also pretty tedious once you have more properties you need to forcibly override. A better way, but still not recommended way too it is to use the class hack: (notice the ampersands)
const StyledSelect = styled(Select)`
&&& li {
margin-left: 20px;
}
`
What styled-components does here is replace each of these & with the generated class, meaning the resulting CSS will look something like this:
.sc-asdf123.sc-asdf123.sc-asdf123 li {
margin-left: 20px;
}
These three classes massively bump the specificity of the styles within the block. That should do the trick!
To not style the first child you can use the first-child together with the not pseudo selector:
const StyledSelect = styled(Select)`
&&& li:not(:first-child) {
margin-left: 20px;
}
`
You could use CSS pseudo-classes:
const StyledSelect = styled(Select)`
li:not(:first-child) {
margin-left: 20px;
}
`
Read more about CSS pseudo-classes: https://developer.mozilla.org/en/docs/Web/CSS/Pseudo-classes
How would I select all but the last child using CSS3 selectors?
For example, to get only the last child would be div:nth-last-child(1).
You can use the negation pseudo-class :not() against the :last-child pseudo-class. Being introduced CSS Selectors Level 3, it doesn't work in IE8 or below:
:not(:last-child) { /* styles */ }
Make it simple:
You can apply your style to all the div and re-initialize the last one with :last-child:
for example in CSS:
.yourclass{
border: 1px solid blue;
}
.yourclass:last-child{
border: 0;
}
or in SCSS:
.yourclass{
border: 1px solid rgba(255, 255, 255, 1);
&:last-child{
border: 0;
}
}
easy to read/remember
fast to execute
browser compatible (IE9+ since it's still CSS3)
Nick Craver's solution works but you can also use this:
:nth-last-child(n+2) { /* Your code here */ }
Chris Coyier of CSS Tricks made a nice :nth tester for this.
When IE9 comes, it will be easier. A lot of the time though, you can switch the problem to one requiring :first-child and style the opposite side of the element (IE7+).
Using nick craver's solution with selectivizr allows for a cross browser solution (IE6+)
There is a:not selector in css3. Use :not() with :last-child inside to select all children except last one. For example, to select all li in ul except last li, use following code.
ul li:not(:last-child){ }
If you're using it within the nesting of the parent then the easiest way is:
&:not(:last-child){
....
}
Example:
.row { //parent
...
...
...
&:not(:last-child){
....
}
}
Using a more generic selector, you can achieve this as seen below
& > *:not(:last-child) {/* styles here */}
Example
<div class="parent">
<div>Child one</div>
<div>Child two</div>
</div>
This will capture all the child DIV in the parent
to find elements from last, use
<style>
ul li:not(:last-child){ color:#a94442}
</style>
Nick Craver's solution gave me what I needed but to make it explicit for those using CSS-in-JS:
const styles = {
yourClass: {
/* Styles for all elements with this class */
'&:not(:last-child)': {
/* Styles for all EXCEPT the last element with this class */
},
},
};
.nav-menu li:not(:last-child){
// write some style here
}
this code should apply the style to all except the last child