Why dosen't setting the className style the React element - javascript

I have been trying to add style element to my React, when I would do the following, the style does not show up:
<body>
<div id="root">
<script src="https://unpkg.com/react#16.7.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16.7.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/#babel/standalone#7.8.3/babel.js"></script>
<style>
.box {
border: 1px solid black;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.box--large {
width: 270px;
height: 270px;
}
.box--medium {
width: 180px;
height: 180px;
}
.box--small {
width: 90px;
height: 90px;
}
</style>
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = (
<div>
<div className="box box--small">small lightblue box</div>
</div>
);
ReactDOM.render(element, rootElement);
</script>
</body>
But, when I change the code to the following, it works:
<body>
<div id="root">
<script src="https://unpkg.com/react#16.7.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16.7.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/#babel/standalone#7.8.3/babel.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = (
<div>
<div className="box box--small" style={{fontStyle: 'italic',backgroundColor: 'lightblue',width: "90px",height: "90px"}}>small lightblue box</div>
</div>
);
ReactDOM.render(element, rootElement);
</script>
</body>
Essentially, moving the style to the div element when I declare it adds the styling. I understand why the second one works, but why dosen't the first one work?

The reason your css is not applied to the element is not becuase your class is not applied to the element but because your css is removed from the page.
You see you added all your scripts and also your styles into the <div> that is used to render your react app. React replaces the contents of that div which removes your styles in your first example.
The second example worked because react rendered the style itself and didn't rely on the stylesheet.
(Just FYI and I'm sure you know this through various tutorials but react is not usually rendered and transpiled in the browser)
Try this:
<!DOCTYPE html>
<html>
<head>
<title>Your react app</title>
<script src="https://unpkg.com/react#16.7.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16.7.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/#babel/standalone#7.8.3/babel.js"></script>
<style>
.box {
border: 1px solid black;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.box--large {
width: 270px;
height: 270px;
}
.box--medium {
width: 180px;
height: 180px;
}
.box--small {
width: 90px;
height: 90px;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = (
<div>
<div className="box box--small">small lightblue box</div>
</div>
);
ReactDOM.render(element, rootElement);
</script>
</body>
</html>

In React, inline styles are not specified as a string. Instead they are specified with an object whose key is the camelCased version of the style name, and whose value is the style's value, usually a string (more on that later):
There are few way you can write style in React.
1. inline styling
class MyHeader extends React.Component {
render() {
return (
<div>
<h1 style={{color: "red"}}>Hello Style!</h1>
<p>Add a little style!</p>
</div>
);
}
}
2. javascript object
class MyHeader extends React.Component {
render() {
const mystyle = {
color: "white",
backgroundColor: "DodgerBlue",
padding: "10px",
fontFamily: "Arial"
};
return (
<div>
<h1 style={mystyle}>Hello Style!</h1>
<p>Add a little style!</p>
</div>
);
}
}
3. External stylesheet
App.css:
- Create a new file called "App.css" and insert some CSS code in it:
body {
background-color: #282c34;
color: white;
padding: 40px;
font-family: Arial;
text-align: center;
}
- Import the stylesheet in your application:
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './App.css';
class MyHeader extends React.Component {
render() {
return (
<div>
<h1>Hello Style!</h1>
<p>Add a little style!.</p>
</div>
);
}
}
ReactDOM.render(<MyHeader />, document.getElementById('root'));
4. css modules
mystyle.module.css:
- Create a new file called "mystyle.module.css" and insert some CSS code in it:
.bigblue {
color: DodgerBlue;
padding: 40px;
font-family: Arial;
text-align: center;
}
- Import the stylesheet in your component:
App.js:
import React from 'react';
import ReactDOM from 'react-dom';
import styles from './mystyle.module.css';
class Car extends React.Component {
render() {
return <h1 className={styles.bigblue}>Hello Car!</h1>;
}
}
export default Car;

Related

react js : children style doesn't show

I tried to create a component 'Card' and use it like a container.
the code work well without 'card'.
when I tried to add it the 'Card.css' and expense-item in ExpenseItem.css doesn't work
this is 'ExpenseItem.js':
import Card from './Card';
import ExpenseDate from './ExpenseDate';
import './ExpenseItem.css';
function ExpenseItem(props) {
return (
<Card className='expense-item' >
<ExpenseDate date={props.date} />
<div className='expense-item__description'>
<h2 >{props.title}</h2>
<div className='expense-item__price'>{props.amount} Da </div>
</div>
</Card>
);
}
export default ExpenseItem;
this is 'Card.js':
import './Card.css';
function Card(props){
const classes ='card'+props.className;
return <div className={classes}> {props.children} </div>;
}
export default Card;
and this is 'Card.css':
.card {
border-radius: 12px;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.25);
}
and finally this is 'ExpenseItem.css':
.expense-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem;
margin: 1rem 0;
background-color: #ff0000;
}
You need a space between card and the class name in the classes variable. Because there is no space, the className attribute in the card component is just cardexpense-item.
This is how it should look:
const classes = 'card '+props.className;
By the way, you can also use ES6 template literals feature (it's up to you but I prefer them more):
const classes = `card ${props.className}`;

How to keep a reference to component created within a loop?

I'm learning Svelte and I'm trying to make a component (a color palette). I blindly went for a solution where each ColorSelector (the color div you click on) is a Svelte component. (I'd gladly take an example where no child components are used)
I export a selected property in the ColorSelector.svelte component file. I'd like to set that property to false on every ColorSelectors instantiated when one of them is clicked except on the one that has been clicked.
However, I'm struggling to find how to keep a reference to an instantiated component in a loop. How can I achieve this?
<script lang="ts">
import { Colors, Color } from "./modules/colors";
import ColorSelector from "./ColorSelector.svelte";
const DEFAULT_COLOR = Colors.LIGHT_WHITE;
let selectedColor:Color = DEFAULT_COLOR;
function handleClick(event, i) {
selectedColor = event.detail.color;
// When clicked set ColorSelector.selected = false on evert ColorSelectors
// except the one that has been clicked
}
</script>
<div>
{#each Object.values(Colors) as color, i}
<ColorSelector on:selected={handleSelect} color={color}></ColorSelector>
{/each}
</div>
<style>
div {
display: flex;
}
</style>
To keep a reference to a component inside a loop you could use bind:this to an array. Have a look at this question Svelte how to bind div inside each lop to obtain a reference using this
To be able to set the property on the component the option must be activated with <svelte:options accessors={true}/> Here's a solution with the data flow I assume you were trying to build >> REPL
<script>
import ColorSelector from './ColorSelector.svelte'
import {Colors} from './Colors'
const DEFAULT_COLOR = Colors.LIGHT_WHITE;
let selectedColor = DEFAULT_COLOR
let colorSelectors = []
function handleSelect(e,i) {
selectedColor = e.detail.color
colorSelectors.forEach(cS => cS.selected=false)
colorSelectors[i].selected = true
}
</script>
<p><b>{selectedColor}</b></p>
<div>
{#each Object.values(Colors) as color, i}
<ColorSelector {color} bind:this={colorSelectors[i]}
selected={color === DEFAULT_COLOR ? true : false}
on:selected="{(e) => handleSelect(e,i)}"/>
{/each}
</div>
<style>
div {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
}
</style>
[ColorSelector.svelte]
<svelte:options accessors={true}/>
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let color, selected
function handleClick() {
dispatch('selected', {
color
});
}
</script>
<div class="color-selector"
class:selected
style:background={color}
on:click={handleClick}
></div>
<style>
.color-selector {
flex-basis: 200px;
flex-grow: 1;
height: 100px;
box-sizing: border-box;
}
.selected {
border: 5px solid black;
}
</style>
But I think these features are not really needed to build the selector nor is the selected = true/false flag because only the one selected color is important.
Here's a simpler solution with and without a component REPL
<script>
import ColorSelector from './ColorSelector.svelte'
import {Colors} from './Colors'
const DEFAULT_COLOR = Colors.LIGHT_WHITE;
let selectedColor = DEFAULT_COLOR;
</script>
<p><b>{selectedColor}</b></p>
<div>
{#each Object.values(Colors) as color, i}
<div class="color-selector"
class:selected-color={selectedColor === color}
style:background={color}
on:click={() => selectedColor = color}
></div>
{/each}
</div>
<hr>
<div>
{#each Object.values(Colors) as color, i}
<ColorSelector {color} bind:selectedColor />
{/each}
</div>
<style>
div {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
}
.color-selector {
flex-basis: 200px;
flex-grow: 1;
height: 100px;
}
.selected-color {
border: 5px solid black;
}
hr {
margin: 3rem;
}
</style>
[ColorSelector.svelte]
<script>
export let color, selectedColor
</script>
<div class="color-selector"
class:selected-color={selectedColor === color}
style:background={color}
on:click={() => selectedColor = color}
></div>
<style>
.color-selector {
flex-basis: 200px;
flex-grow: 1;
height: 100px;
box-sizing: border-box;
}
.selected-color {
border: 5px solid black;
}
</style>

create dot by span is not generated from react in css

I would like to create one component that included the dot between 2 elements. the code I have is like following, However, I tried to use span element then create css so I can display . between 2 span. but react does not generate the dot between 2 span. I also tried to use div and then dot did display but format of 2 element does not align at center
//html
import "./styles.css";
export default function App() {
return (
<div className="panel-section">
<div className="panel-header">
<div className="panel-title">
{/** use div format is not correct */}
<div>May 1st 5:31PM</div>
<div className="panel-dot"></div>
<div>Google</div>
{/** dot is not generated
<span>May 1st 5:31PM</span>
<span className="panel-dot"></span>
<span>Google</span>
*/}
</div>
</div>
</div>
);
}
//css
.panel {
width: 600px;
height: 500px;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
left: 0.5%;
right: 33.44%;
}
.panel-title {
padding: 8px;
color: #ffffff;
background-color: #3aac6f;
}
.panel-dot {
width: 4px;
height: 4px;
background: #3aac6f;
align-self: center;
}
codepen:
You can try this :
App.js
import React from 'react';
import './style.css';
export default function App() {
return (
<div className="panel-section">
<div className="panel-header">
<div className="panel-title">
<span>May 1st 5:31PM</span>
<span>Google</span>
</div>
</div>
</div>
);
}
style.css
.panel-title span:first-of-type::after {
content: '.';
}
Demo : Stackblitz
OR
App.js
import React from 'react';
import './style.css';
export default function App() {
return (
<div className="panel-section">
<div className="panel-header">
<div className="panel-title">
<span>May 1st 5:31PM</span>
<span>{"."}</span>
<span>Google</span>
</div>
</div>
</div>
);
}

React color background on event

I use the npm package use-dark-mode as the name implies, it makes it possible to change the theme to light or dark, The problem is that I want to change the background-color of some blocks when changing the theme to dark, and vice versa, return the old color when I switch to light mode, for example, my block background is orange, I switch to dark mode, it turns red and when I switch to light mode, it returns old orange
App.js
import React from 'react';
import './App.css'
import Content from "./components/Content/Content";
import Dark_Mode from "./components/Dark Mode/Dark_Mode";
const App = () => {
return(
<div>
<Dark_Mode />
<Content />
</div>
);
};
export default App;
Content.jsx
import React from 'react';
import './style.css'
const Content = () => {
return (
<>
<div className={"content_container"}>
<h3>Hello from React.JS</h3>
</div>
</>
);
};
export default Content;
Dark_Mode.jsx
import React from 'react';
import useDarkMode from 'use-dark-mode';
const DarkModeToggle = () => {
const darkMode = useDarkMode(false);
return (
<div>
<button type="button" onClick={darkMode.disable}>
☀
</button>
<button type="button" onClick={darkMode.enable}>
☾
</button>
</div>
);
};
export default DarkModeToggle;
style.css
#import '../../App.css';
.content_container {
margin: auto;
width: 500px;
max-width: 100%;
background: orange;
}
.content_container h3 {
text-align: center;
}
App.css
body.light-mode {
background-color: #fff;
color: #333;
transition: background-color 0.3s ease;
}
body.dark-mode {
background-color: #1a1919;
color: #999;
}
:root {
--color-orange: orange;
}
As you can see, I have App.css when the theme changes, it changes the background of the <body>, I still have Content.jsx when switching theme I want to change the background of the block with the className content_container which is connected to style.css, In addition, you may have noticed that I tried to use global styles, but I failed. Finally, I would like to show a screenshot on the site for a clear understanding of everything.
You could give the root element a class on theme change and use css variables in root, but be class specific:
Dark_mode.jsx:
function setTheme(themeName) {
document.documentElement.classList.remove('light-theme', 'dark-theme');
document.documentElement.classList.add(themeName);
}
const DarkModeToggle = () => {
const activateDarkTheme = () => setTheme('dark-theme');
const activateLightTheme = () => setTheme('light-theme');
return (
<div>
<button type="button" onClick={activateDarkTheme}>
☀
</button>
<button type="button" onClick={activateLightTheme}>
☾
</button>
</div>
);
};
Styles:
:root, // this is used for the default theme, will be overwritten by other styles with classes because of specifity
:root.dark-theme {
--color-bg: #000;
}
:root.light-theme {
--color-bg: #fff;
}
I found a more convenient solution! although it is my fault, I was a little inattentive and did not study the documentation of this package that I use in my project, here is a simple solution
Content.jsx
import './Content.css'
import useDarkMode from 'use-dark-mode';
export default function Content () {
const { value } = useDarkMode(false);
return <div>
<div className={value ? 'Dark_Mode' : 'Light_Mode'}>
<h3>Hello from React.JS</h3>
</div>
</div>
}
Content.css
.Dark_Mode {
margin: auto;
max-width: 100%;
width: 400px;
height: 275px;
background-color: orange;
}
.Light_Mode {
margin: auto;
max-width: 100%;
width: 400px;
height: 275px;
background-color: rgb(24, 106, 199);
}

react-monaco-editor text appears in middle of editor despite cursor being at the start of line

I created a simple react app to try and play with react-monaco-editor. Here is my code.
import React, { Component } from 'react';
import MonacoEditor from 'react-monaco-editor';
import './App.css';
const code = `
import React from "react";
class App extends React.Component {
render() {
return (
<span>I mean really come one</span>
);
}
}
export default App;
`;
class App extends Component {
onChange = (value) => {
console.log(value);
}
editorDidMount = (editor, monaco) => {
console.log('editorDidMount', editor);
editor.focus();
}
render() {
const options = {
selectOnLineNumbers: true
};
return (
<div className="App">
<MonacoEditor
height="600"
width="600"
language="javascript"
theme="vs-dark"
value={code}
onChange={this.onChange}
editorDidMount={this.editorDidMount}
/>
</div>
);
}
}
export default App;
For some reason tho, the text in the editor is showing up in the middle, and my cursor is as the start of line as expected.
Here is a screenshot of the issue.
This might be an old question but in React in the default App.css there is a line which sets the text-align to center.
If it looks similar to this:
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #09d3ac;
}
you can just delete this part:
.App {
text-align: center;
}

Categories

Resources