reactJS not applying styles (.less files)? - javascript

I have been trying to search on the topic but it seems that I might be using the wrong terms as I cannot find any information....
I am trying to get this package to work..(https://github.com/wangzuo/input-moment)
I have succeeded in getting the calendar to work, it saves the date, but it will not switch to the time tab and it also does not style correctly, even though I have imported the .less files into my react component.. the file looks like this...
require('input-moment/src/less/input-moment.less')
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import moment from 'moment';
import InputMoment from 'input-moment';
class Date extends Component {
constructor(props) {
super(props);
this.state = {m: moment()}
}
handleChange(m) {
this.setState({ m });
}
handleSave() {
console.log('saved', this.state.m.format('llll'));
}
render () {
return (
<InputMoment
moment={this.state.m}
onChange={this.handleChange}
onSave={this.handleSave}
/>
)
}
}
and yet my component looks like this...
Can you see any obvious reason as to why the component will not style correctly like the example on github...(http://wangzuo.github.io/input-moment/)

You probably aren't getting the styles provided by the package. If you used npm to install the package, then your import statement could look like this:
require('input-moment/dist/input-moment.css')
Also, compare your App.css to the CSS used by the package author in the example, which can be found at https://github.com/wangzuo/input-moment/blob/master/example/app.less, source is repeated below
*, *:before, *:after {
box-sizing: border-box;
}
body {
margin: 0;
font: 87.5%/1.5em 'Lato', sans-serif;
}
.app {
max-width: 400px;
margin: 0 auto;
margin-top: 90px;
padding: 0 20px;
.input {
margin-bottom: 20px;
}
input {
padding: 7px 8px;
font-size: 14px;
width: 100%;
}
}

Related

How can I customize the checked state of a checkbox when using svgr in React?

I'm working on a React project and I'm using styled-component and typescript.
I'm customizing the checkbox like this:
Source
import React, { ReactElement } from 'react';
import styled from 'styled-components';
import IconChecked from '#assets/Icons/ico_checked.svg';
interface Props {
id: string;
}
const StyledCheckBox = styled.input`
box-sizing: border-box;
width: 20px;
height: 20px;
background: #ffffff;
border: 1px solid #d4dae4;
border-radius: 4px;
appearance: none;
&:checked {
background-image: url(${IconChecked});
background-repeat: no-repeat;
background-color: #ffffff;
background-position: 50%;
}
`;
const CheckBox = ({ id }: Props): ReactElement => (
<StyledCheckBox type="checkbox" id={id} />
);
export default CheckBox;
Question
To use the svg icon without the <img> tag, I installed the svgr package and set it as an svg type loader through webpack.
The problem is that svgr has the logic to convert svg to component, so I can't set the checked icon in the following way.
&:checked {
background-image: url(${IconChecked});
...
}
As a result, the check icon(IconChecked) does not appear when I click the checkbox after using svgr. How can I solve this?
You can move your ico_checked.svg file to public folder and use the svg directly from the url like this:
&:checked {
background-image: url("/ico_checked.svg");
...
}
You can take a look at this sandbox for a live working example of this approach.

Styles in .scss file not applied

I have a react app and use .scss files for styling.
My index.js looks like this:
import './App.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrictMode>,
document.getElementById('root')
);
My App.scss looks like this:
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
height: 100%;
}
body,
:global(#root) {
min-height: 100%;
color: var(--primary-font-color);
font-family: "Open Sans", sans-serif;
font-weight: 400;
font-size: 18px;
line-height: 22px;
}
h1 {
color: var(--primary-font-color);
font-size: 32px;
font-weight: 600;
line-height: 36px;
}
:root {
/*Colors */
--primary-color: #f6f5f2;
}
Now my problem is that all the styles apart from *,*::before,*::after and :root are not applied.
In the browser console I can see that the App.scss is used and the *,*::before,*::after styles are applied. Also all vars from :root can be found there.
I want to use the App.scss file for global styles, but the only way I found to apply them is with an #import("App.scss") in a component.module.scss. Importing the App.scss to every module results in as many duplicates as imports. Is this the intended way to handle scss styles?
Sass is not recommended to use today for global styles, because as they wrote -> it can generate more files than you want -> effect is that you have worse performance
This information we can read on their main page
I recommend you use once simple CSS file for variables, global styles then easily you can reuse them and if you wanna use Sass as a developer then go-ahead for the rest of styling
Best!
For example what you can do
App.css:
body {
margin: 0;
font-family: Lato, Helvetica, Arial, sans-serif;
transition: all 0.3s linear;
}
:root {
--facebook-color: #507dc0;
}
And then:
Login.scss
body {
.login {
background-color: var(--facebook-color);
}
}
Of course this is only example.
I found the a solution:
Looks like it was the :global(#root) which caused the problem. Removing it makes the other styles applied no matter if they are in a .scss or .css file.

Two Components Connected to Each-other

Two of my React components are connected together. You might be thinking, if they are both separate components then they shouldn't be connected, right. WRONG.
What I want to do is this. I want to create a footer but the footer is apparently linked to another component. I think this is a react bug but I have decided not to go there in case it's just my fault. I want to change the width of the footer to be max width with the screen but it doesn't work, it changes both of the components width.
.footer {
width: 100%;
}
.footer {
background-color: gray;
border: 1px solid gray;
border-radius: 1px;
height: 100px;
width: 10000px; /*Or 100%*/
}
.otherComponent {
/*For some reason it copies the same attributes as the css one above (there in different files by the way*/
width: 10000px; /*Or 100%*/ /*The one that got copied by react.*/
background-color: gray;
border: 1px solid gray;
border-radius: 1px;
height: 100px;
}
<div class="otherComponent">
</div>
<br />
<p>This is to demonstrate the bug/error that is happening with my program. And what it looks like</p>
<div class="footer">
</div>
Edit:
I am editing this question since I have received comments saying that this question is not understandable, which I understand. The problem is that I want one of the components (which is a code-box for a documentation website that I am working on) to be somehow separated from another component (which is the footer). Every time I apply a style to the footer component the code-box component is having the same styles.
Information
Both of the different styles for the components are in separate folders. They are separated away from each-other using "<br />" tags. The components are placed like this in the App.js file.
{/* Middle of the page */}
<HomeInfo />
{/* Bottom of the page */}
<Footer />
If this edit still doesn't make sense commenting on the post would help.
As there is little to go on here I'll describe one case where this could occur.
Given the following two components and root app.
Component A:
CSS:
.root {
width: 100%;
}
.component-a-heading {
color: blue;
}
Component:
import React from 'react';
import './component-a.css';
const ComponentA = () => {
return (
<div className="root">
<h1 className="component-a-heading">
I am component A
</h1>
</div>
)
}
export default ComponentB;
Component B:
CSS:
.root {
width: 50%;
}
.component-b-heading {
color: red;
}
Component:
import React from 'react';
import './component-b.css';
const ComponentB = () => {
return (
<div className="root">
<h1 className="component-b-heading">
I am component B
</h1>
</div>
)
}
export default ComponentA;
App:
import React from 'react';
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
const App = () => {
return (
<div>
<ComponentA />
<ComponentB />
</div>
);
}
export default App;
The assumed intended result is that:
ComponentA would be 100% width,
ComponentA heading would be blue,
ComponentB would be 50% width,
ComponentB heading would be red.
The reality is that:
ComponentA would be 50% width,
ComponentA heading would be blue,
ComponentB would be 50% width,
ComponentB heading would be red.
This is caused by the fact that even though the CSS unique to each component is imported per component the resulting CSS is global and effects all components that might use the class names defined within (in the example above .root).
Depending on your bundling process you might end up with a single CSS file that
looks something like this:
.root {
width: 100%;
}
.component-a-heading {
color: blue;
}
.root {
width: 50%;
}
.component-b-heading {
color: red;
}
Or you might end up with the styles inserted into the head of your HTML like this:
<style type="text/css">
.root {
width: 100%;
}
.component-a-heading {
color: blue;
}
</style>
<style>
.root {
width: 50%;
}
.component-b-heading {
color: red;
}
</style>
This is a common mistake for people who come from Angular, where imported CSS is scoped to each component, to React.
One way to get around this is to look at the possibility of using CSS Modules which will allow you to locally scope each imported CSS file (this just makes the CSS class names unique in your resulting bundle).
Another option would be to implement a naming policy to ensure that the class names remain unique between components.

How can I have different background color for different component in a React app?

I have never worked with React, Js or CSS. So, I decided to make a very simple Portfolio site with some additional pages. I have planned for having three pages -> Home, About and Portfolio. I have the Home page working as I want it to. I was working on the About page and I realized that whenever I use a custom css for this component with a different background color, it makes it default background color for every component. I'm using routes to jump from one component to the other. I think I'm doing something wrong with routes in index.js. My index.js looks like below,
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router, Route} from 'react-router-dom'
import App from './component/js/App';
import About from './component/js/About'
ReactDOM.render((
<Router>
<div>
<Route path='/' component={App} exact/>
<Route path='/about' component={About} strict/>
</div>
</Router>
), document.getElementById('root'))
I did not create a route for Portfolio since I have not started working on it yet. My App.js looks like below
App.js
import React from 'react';
import Git from '../../images/github.png';
import Email from '../../images/email.png';
import CV from '../../images/resume.png';
import Resume from '../../files/2019.pdf';
import LinkedIn from '../../images/linkedin.png';
import '../css/App.css';
import {NavLink} from 'react-router-dom';
export default class App extends React.Component {
render = () => {
let git_url = 'xxxx'
let Linkedin = 'xxxx'
return (
<div id='main'>
<div id='menu'>
<NavLink id='nav' to='/about'>About</NavLink>
<NavLink id='nav' to='/portfolio'>Portfolio</NavLink>
<NavLink id='nav' to='/home'>Home</NavLink>
</div>
<div id='name'>
<h1 id='pp'>xxxxx</h1>
<h2 id='title'>Engineer / Developer / Designer</h2>
</div>
<div id='contacts'>
<a href={git_url} target='_blank'><img className='nav' id='git' src={Git} /></a>
<a href={Resume} target='_blank'><img className='nav' id='cv' src={CV} /></a>
<a href={Linkedin} target='_blank'><img className='nav' id='cv' src={LinkedIn} /></a>
<img className='nav' id='email' src={Email} />
</div>
</div>
)
}
}
And the css for it looks like below
App.css
body{
background-color: khaki}
#main{
display: flex;
text-align: center;
flex-direction: column;
margin-top: 10%;
}
#menu {
text-align: center;
flex-direction: row;
}
#nav {
padding: 14px 16px;
text-decoration: none;
color: #061A40;
font-size: 20px;
font-weight: bold;
}
#nav:hover {
background-color: #d75f5f;
}
#pp {
color: transparent;
background: url(../../images/background2.jpg) no-repeat center center;
background-size:100%;
-webkit-background-clip: text;
background-clip: text;
margin: 0;
padding: 0;
font-size: 100px;
}
#title {
font-size: 24px;
color: #214F4B;
}
#contacts {
display: flex;
align-self: center;
flex-wrap: wrap;
}
.nav {
height: auto;
width: 50px;
margin: 15px;
transition: transform 3s;
}
.nav:hover{
transform: scale(1.5);
}
I created a test About component to figure out this background-color issue and below is my code,
About.js
import '../css/About.css'
import React from 'react';
export default class About extends React.Component {
render = () => {
return (
<div>
<div id='test'>
<h1>Test</h1>
</div>
<div id='line'></div>
</div>
)
}
}
The css for this looks like below
About.css
body {
background-color:white;
}
#test {
text-align: center;
background-color: #B6C8A9;
padding: 0.01%;
}
h1 {
color: #160C28;
font-family: Arial;
}
In the About.css file, if I have the body{background-color: ...}, every page becomes that color. If I take it out, every page becomes whatever color was set in App.css. As I said, I'm new to JS, CSS and React in general. As I understand, if I include a custom css in the component, it should only apply it to that component. I don't know why it's applying to all the component.
body refers to the whole webpage so it colors the thing which all components are inside of. Further, the CSS in your About.css file is not added/removed when the component is added/removed.
The simplest solution would be to make your About page a div that fills the whole screen and color that.
About.js
export default class About extends React.Component {
render = () => {
return (
<div className="about-page">
<div id='test'>
<h1>Test</h1>
</div>
<div id='line'></div>
</div>
)
}
}
About.css
.about-page {
background-color:white;
min-height: 100vh;
}
#test {
text-align: center;
background-color: #B6C8A9;
padding: 0.01%;
}
h1 {
color: #160C28;
font-family: Arial;
}
The way you have different colors for different components is to use styled-components. You then wrap your components with that styled component. Here is an example:
import styled from 'styled-components'
import style from 'styled-components'
const Div = styled.div`
background-color:#FF7759;
`
const Container = style.div`
background-color:#000000;
`
function Example() {
return (
<div>
<Div>
< Portfolio />
</Div>
<Container>
< Portfolio />
</Container>
</div>
)
}
use style={{ inline css}} props to parent div
example :
<div style={{backgroundColor:'color name here '}}>

Logic to render a component only once

I need help with creating a logic for my React component. If the divider line appears once on the page it should not be rendered again.
So, if I add the component to the page it styles the text underneath. But if I try to add the component again to the page, the divider line/styling should be ignored. I should only be able to add it once
This is my code:
import React from 'react';
const Divider = () => (
<>
<hr className="divider"/>
</>
);
/* Seperate css file */
hr.divider {
height: 0;
border: 0;
border-top: solid 1px #cdcdcd;
}
hr.divider ~ p.story-text {
font-size: 0.90rem;
font-weight: normal;
font-stretch: normal;
font-style: normal;
letter-spacing: normal;
line-height: 1.75rem;
color:#707174;
#include text-styles(.75rem, 1.75em, "Gordita");
#include breakpoint(tablet) {
#include text-styles(.90rem, 2em, "Gordita");
}
}
hr.divider ~ p.story-text:last-of-type {
border-top: solid 1px red;
}
You need to use the component LifeCycle tools provided by ReactJS. ComponenDidMount() loads the only once when the class is loaded but the render() function is called on each action of the user or the app. Here is a link to ReactJS docs telling how to use ComponentDidMount(): https://reactjs.org/docs/react-component.html#componentdidmount
It may be better to add a condition in the parent component (the one that calls Divider), but given the current snippets:
const Divider = () => (
let dividers = document.getElementsByClassName('divider')
if (dividers.length > 0) {
return null
} else {
return <hr className="divider"/>
}
);
This will not stop your component from rendering. It will only stop more than one hr from rendering.

Categories

Resources