how to increase number animation using styled component - reactjs

I want to implement an animation that increases the number using a styled component.
const Info = styled.div`
margin-left: 35rem;
margin-top: -15rem;
p {
display: inline-block;
width: 25rem;
padding: 1rem;
white-space: nowrap;
overflow: hidden;
font-weight: 500;
strong {
font-weight: 600;
#property --num {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
}
}
animation: ${ImgFade} 0.7s linear;
animation-delay: 0.1s;
`
<Info>
<p>
<strong>350</strong>User
</p>
</Info>
I'm using #property(css property), it seems not work..

Related

There is an error when using conditional rendering in styled-components

I'm trying to make toggle menu by using state. I want to hide component when the value of state is false. So I made conditional rendering in styled-component but there is an error. It says "'isChecked' is not defined no-undef". I want to fix this error but don't know how to fix it and where is wrong. I'd appreciate it if you let me know Thanks!
This is my code. The cord was long, so I erased the irrelevant part. It's still a long code, but I think you just need to look at the part I commented on
import React, { useState } from 'react'
import styled from 'styled-components';
const Body3LeftStart = styled.div`
flex-basis: 66.66666667% !important;
max-width: 66.66666667%;
box-sizing: border-box;
flex: 0 0 auto;
padding-left: 8px;
padding-right: 8px;
`
const Body3LeftSection = styled.div`
margin-bottom: 8px;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #000a12;
box-sizing: border-box;
#Body3Section1 {
display: flex;
align-items: flex-end;
margin-bottom: 8px;
}
#Body3Section1::before {
display: block;
margin-top: -71px;
padding-top: 71px;
visibility: hidden;
content: " ";
z-index: 0;
}
#Body3Section1Span {
margin-right: 8px;
line-height: 1.45;
letter-spacing: -.3px;
color: #343a40;
font-size: 22px;
font-weight: 700;
}
#Body3Section1Span2 {
line-height: 1.5;
letter-spacing: -.3px;
font-size: 16px;
color: #adb5bd;
font-weight: 500;
}
`
const Body3LeftSection2 = styled.div`
display: flex;
margin-bottom: 20px;
align-items: flex-end;
#Body3LeftSection2Text {
font-weight: 400;
line-height: 1.47;
letter-spacing: -.3px;
font-size: 15px;
margin-right: 12px;
color: #495057;
word-break: keep-all;
}
`
const Body3LeftToggle = styled.div`
overflow: hidden;
border: 1px solid #e9ecef;
border-radius: 4px;
`
const Body3LeftToggle1 = styled.div`
box-sizing: border-box;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
`
const Body3LeftToggleTitle = styled.div`
border-top: unset;
display: flex;
align-items: center;
padding: 15px 20px;;
border-bottom: 1px solid #f1f3f5;
background-color: #f8f9fa;
cursor: pointer;
#Body3LeftToggleButton {
display: inline-flex;
margin-right: 8px;
width: 16px;
height: 16px;
align-items: center;
justify-content: center;
transition: background-color .15s ease;
}
`
const Body3LeftToggleTitleText = styled.div`
line-height: 1.47;
letter-spacing: -.3px;
font-size: 15px;
color: #343a40;
font-weight: 700;
font-style: inherit;
`
const Body3LeftToggleTitleText2 = styled.div`
font-weight: 400;
line-height: 1.47;
letter-spacing: -.3px;
font-size: 15px;
margin-left: auto;
color: #343a40;
`
//This is the component I want to put in a toggle. I used conditional rendering here.
const Body3LeftToggleContent = styled.div`
max-height: 50px;
overflow: hidden;
${isChecked===false}{
display: none;
}
`
const Body3LeftToggleContentWrap = styled.div`
display: flex;
align-items: center;
padding: 14px 20px;
`
function Body3Left() {
// I made useState here
const [isChecked,setChecked] = useState(false)
return (
<Body3LeftStart>
<Body3LeftSection>
<div id='Body3Section1'>
<span id='Body3Section1Span'>
커리큘럼
</span>
<span id='Body3Section1Span2'>
총 39
개 ˙ 5시간 2분의 수업
</span>
</div>
<Body3LeftSection2>
<span id='Body3LeftSection2Text'>
이 강의는 영상, 수업 노트가 제공됩니다. 미리보기를 통해 콘텐츠를 확인해보세요.
</span>
<button id='Body3LeftSection2Button'>
모두 접기
</button>
</Body3LeftSection2>
<Body3LeftToggle>
<Body3LeftToggle1>
<Body3LeftToggleTitle>
// I used button here. I erased it because the svg code was long, but there is an arrow picture in it. I changed the value every time I pressed the button
<span id='Body3LeftToggleButton'>
<svg onClick={()=>{setChecked(!isChecked)}} style={{display:isChecked===true&&'none' ,width:'16', height:'16'}}></svg>
<svg onClick={()=>{setChecked(!isChecked)}} style={{display:isChecked===false&&'none' ,width:'16', height:'16'}}></svg>
</span>
<Body3LeftToggleTitleText>
섹션 0. 소개
</Body3LeftToggleTitleText>
<Body3LeftToggleTitleText2>
1강 ∙ 4분
</Body3LeftToggleTitleText2>
</Body3LeftToggleTitle>
<Body3LeftToggleContent>
<Body3LeftToggleContentWrap>
<span id='Body3LeftToggleContentText1'>
강의 소개
</span>
<span id='Body3LeftToggleContentText2'>
<span id='Body3LeftToggleContentText3'>
04:41
</span>
</span>
</Body3LeftToggleContentWrap>
</Body3LeftToggleContent>
</Body3LeftToggle1>
</Body3LeftToggle>
</Body3LeftSection>
</Body3LeftStart>
)
}
export default Body3Left;
you have to pass the state as props to the styled component as
const Body3LeftToggleContent = styled.div`
max-height: 50px;
overflow: hidden;
display: ${props => props.isChecked ? "block" : "none"}; // get prop value as so
`;
from the JSX as
</Body3LeftToggleTitle>
<Body3LeftToggleContent isChecked={isChecked}> // like so
<Body3LeftToggleContentWrap>
only added the parts of the code to alter ....
for reference on passing props

setState and changing style conditionally don't work together

I got some issues with the following code:
//FIRST PAGE
import React from "react";
import './index.css'
import Boxx from "./Boxx";
export default function WindowZero (prop){
//
// FETCH COMING DATA
const fetchData = async () =>{
const data = await prop.data
return data
}
// FUNCTION FIRST PAGE
function RenderZero (){
return (<div className="Zero--">
<h1 className="Zero--h" > Welcome to Quizzly</h1>
<p className="Zero--p">click the start button to start</p>
<button className="Zero--start" onClick={()=>{ prop.setZero()}}>Quiz Me</button>
</div>)
}
// CONDITIONAL RENDERING
if(prop.zero){
return <RenderZero/>
}
else{
return <Boxx dataI={fetchData()}/>
}
}
This is the first page. It supposes to show the user a button when it was clicked, it renders the other page which shows a page of questions:
// THE OTHER PAGE
import React from "react";
import './index.css'
import {useState, useEffect} from 'react'
export default function Boxx (prop) {
// STATES & VARIABLES INITIALIZAITION
var sAnswersA = []
for(let i = 0; i<5; i++){
sAnswersA.push({id:i, value:'', correct:null})
}
var [selectedAnswers,setSelectedAnswers] = useState(sAnswersA)
var [truth,setTruth] = useState(true)
var [comingData, setComingData] = useState([])
// FETCHING FUNCTION::
let fetching = async()=>{
let x = await prop.dataI;
return x;
}
// USEEFFECT & FETCHE INSIDE::
useEffect(()=>{
fetching().then((result)=>{
var array = result.slice()
if(array[0].incorrect_answers.length != 4){
array.map(item=>{
item.incorrect_answers.push(item.correct_answer)
shuffle(item.incorrect_answers)
})}
for(let i = 0; i< array.length; i++){
array[i]= {...array[i], id:i}
}
setComingData(array)
})
},[])
// SHUFFLE FUNCTION::
function shuffle(array) {
let currentIndex = array.length, randomIndex ;
// While there remain elements to shuffle.
while (currentIndex != 0) {
// Pick a remaining element.
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
// EVENTLISTENERS::
const handler = (e,obj) =>{
var targetD = e.target
console.log(targetD)
console.log(obj)
obj.incorrect_answers.map(item=>{
if(item===targetD.innerText){
console.log('true')
let nodess = targetD.parentNode.childNodes;
nodess.forEach(i=>{
if(i.classList.contains('selected-')){
i.classList.remove('selected-')
}
})
targetD.classList.add('selected-')
}
})
}
// FUNCTION TO SUM ANSWERS::
const sumAnswers = (e,obj) =>{
// console.log(selectedAnswers[0].id)
setSelectedAnswers(prev=>{
return prev.map(it=>{
return obj.id === it.id ? {...it, value:e.target.innerText} : {...it}
})
})
}
// SHUFFLE DATA === Done
// ADD EVENT LISTENERS; STYLES; SUBMIT BTN; COLLECT ANSWERS; CHECK ANSWERS; SHOW RESULT;
//console area...
console.log(selectedAnswers)
// FUNCTION RUN = CREATE THE DOM ELEMENTS::
const Run = () => {
return comingData.map(item=>{
return(
<div key={Math.random()*9} className="questionBody--" id={item.id}>
<p className="qB--question">{item.question}</p>
<div className="answers--" id={item.id}>
<p className="qB--answer" id="0" onClick={(e)=>handler(e,item)}>{item.incorrect_answers[0]}</p>
<p className="qB--answer" id="1" onClick={(e)=>handler(e,item)}>{item.incorrect_answers[1]}</p>
<p className="qB--answer" id="2" onClick={(e)=>handler(e,item)}>{item.incorrect_answers[2]}</p>
<p className="qB--answer" id="3" onClick={(e)=>handler(e,item)}>{item.incorrect_answers[3]}</p>
</div>
</div>
)
})
}
return(<Run/>)
}
here is my App.js:
import './App.css';
import WindowZero from './windowZeroComponent';
import React, {useState,useEffect} from 'react';
function App() {
var [zero, setZero] = useState(true)
//
var [dataI, setDataI] = useState([])
//
useEffect(()=>{
fetcData()
},[])
const fetcData = async () =>{
const getData = await fetch('https://opentdb.com/api.php?amount=5&category=27&type=multiple')
const getDataJson = await getData.json()
setDataI(getDataJson.results)
}
return (
<div className='App--'>
hi
<WindowZero data = {dataI} zero={zero} setZero = {()=>setZero(prev=>!prev)}/>
</div>
);
}
export default App;
CSS file:
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
*{
box-sizing:border-box;
padding: 0 ;
margin: 0 ;
}
/* */
.Zero--{
background-image: linear-gradient(#37f,#3af);
height:100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 10% 5%;
}
.Zero--h{
text-transform: uppercase;
font-size: 28px;
font-weight: 500;
color: #f0f0ff;
padding: 12px;
}
.Zero--p{
font-size: 20px;
font-weight: 300;
padding: 8px;
color: #f0f0f0;
}
.Zero--start{
border: none;
padding: 10px 16px;
margin: 4px;
font-size: 22px;
font-weight: 700;
text-transform: uppercase;
border-radius: 16px;
background-color: #0ff;
color: #333333;
cursor: pointer;
}.Zero--start:hover{
transition:all ease-in-out 400ms;
transform: scale(1.11);
}
/* */
.questionBody--{
display: flex;
flex-direction: column;
background-color: transparent;
border-bottom: 1px solid #a0a0a0;
margin: 30px 0px;
}
.qB--question{
color: #007;
outline-color: #333333;
font-size: 26px;
font-weight: 600;
padding: 4px;
margin-left: 12px;
text-shadow: 0px 0px 1px #111;
}
.answers--{
display: flex;
flex-direction: row;
background-color: transparent;
}
.qB--answer{
padding: 0px 16px;
margin: 12px;
border-radius: 10px;
border:1px solid #999;
text-align: center;
/* color: #22f; */
font-size: 18px;
font-weight: 500;
text-shadow: 0px 0px 1px #111;
display: flex;
justify-content: center;
align-items: center;
}.qB--answer:hover{
transition: all ease-in 400ms;
background-color: #007;
color: #fff;
cursor: pointer;
}
/* */
.Main--{
padding: 25px 15%;
min-height: 100vh;
background-image: url('./background--.jpg');
background-repeat: no-repeat;
background-size: cover;
}
.submit--{
display: flex;
flex-direction: row;
align-items: baseline;
justify-content: center;
}
.submit--button{
padding: 2px 26px;
background-color: #007;
color: #fff;
font-size: 20px;
font-weight: 600;
border-radius: 12px;
margin: 0px 15px;
border: none;
}.submit--button:hover{
transition: all ease-in 400ms;
color: #007;
cursor:pointer;
background-color: #fff;
}
.conclusion--{
font-size:18px;
font-weight: 600;
}
.selected-{
background-color:#0ff;
color: #700;
}
My problem is that on the Other page (Boxx.js), specifically in //EVENENTLISTENERS => handler function: I'm trying to put sumAnswers(e,obj){which collects the clicked answers and add it to a state} inside of it, but when I do, the handler() stops adding the style to the clicked answer. I tried to put both of them inside of a function that runs after clicking on each answer but that didn't work too.
hope someone could help.
thx for reading, sorry for my English.

Range Slider with React and Typescript

I have created range slider but when we change the min value then it will not work. I want dynamic range Slider with ticks and moving label with respect to thumb without using any package.
This is my code below. i am expecting to create a dynamic range slider without using any package and also slider have ticks and movable thumbs which shows value with respect to thumbs
import { useCallback } from 'react';
import { Styles } from './range-slider-style';
interface IVersionSliderProps {
latestVersion: number;
olderVersion: number;
onChange: (val: any) => void;
}
export function VersionSlider(props: IVersionSliderProps) {
const setValue = useCallback((e) => {
console.log(e.target.value);
const newVal = e.target.value;
const negNewVal = -10 * Number(newVal);
console.log(negNewVal);
(document.querySelector('.range-text') as HTMLDivElement).style.left = (newVal + '%'); //Set range left position
(document.querySelector('.range-text') as HTMLDivElement).style.transform = 'translate(' + negNewVal + '%, 20px)'; //Set range translate to correct
(document.querySelector('.range-text') as HTMLDivElement).innerHTML = newVal; //Set range text equal to input position
}, []);
return (
<Styles>
<div className="input-container">
<input
id='#input'
type="range"
min={olderVersion}
max={latestVersion}
//value="1"
onChange={setValue}
step='.01' />
<div className="range-text">0</div>
</div>
</Styles>
);
}
//Css part below:
import styled from 'styled-components';
export const Styles = styled.div`
align-items: center;
display: "flex";
height: 100px;
color: #888;
margin-top: 2rem;
flex-direction:column;
margin-bottom: 2rem;
width: 1200px;
.value {
font-size: 1rem;
}
.input-container {
position: relative;
height:10px;
display: flex;
background: border-box;
width: 100%;
padding: 0;
}
.marking {
height:20xp;
widht:100%;
background-color: "black";
margin-top: 20px;
}
input[type="range"] {
appearance: none;
background-color: #56B0C9;
width: 100%;
height: 8px;
padding: 0;
}
input[type="range"]::-webkit-slider-thumb {
-moz-appearance: none !important;
appearance: none !important;
position: relative;
height: 20px;
width: 100px;
background: transparent;
cursor: ew-resize;
z-index: 2;
}
input[type="range"]::-moz-range-thumb {
-moz-appearance: none !important;
appearance: none !important;
position: relative;
height: 20px;
width: 100px;
background: transparent;
cursor: pointer;
z-index: 2;
}
.range-text {
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
background: white;
text-align: center;
line-height: 1;
height: 18px;
width: 60px;
transform: translate(0, 2px);
}`;

Is it possible to use the same React component with different CSS, using css modules?

I found the React CSS modules usefull, but having problem when I tried to reuse the same component with a little modified css I stuck. For example I created Neon glowing button, but now need to change only the width of the Button and some additional small changes in the css.
The only option I see is component without css and for every different case need to rewrite the whole css. Is there a smarter way?
import React from "react";
import styles from "./index.module.css";
import { Link } from "react-router-dom";
const GlowingButton = ({ title, path }) => {
return (
<div className={styles.buttonWrapper}>
<Link className={styles.button} to={path}>
<button className={styles["glow-on-hover"]}>{title}</button>
</Link>
</div>
);
};
export default GlowingButton;
And here is index.module.css
.buttonWrapper {
margin: 0px;
padding: 0px;
display: flex;
justify-content: center;
align-items: center;
background: transparent;
font-family: "consolas";
}
.button {
margin: 0;
padding: 0;
width: 80%;
height: 8vh;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: #100f;
text-decoration: none;
}
.glow-on-hover {
width: 400px;
height: 50px;
border: none;
outline: none;
color: #fff;
background: #111;
cursor: pointer;
position: relative;
z-index: 0;
border-radius: 10px;
}
.glow-on-hover:before {
content: "";
background: linear-gradient(
45deg,
#ff0000,
#ff7300,
#fffb00,
#48ff00,
#00ffd5,
#002bff,
#7a00ff,
#ff00c8,
#ff0000
);
position: absolute;
top: -2px;
left: -2px;
background-size: 400%;
z-index: -1;
filter: blur(5px);
width: calc(100% + 4px);
height: calc(100% + 4px);
animation: glowing 20s linear infinite;
opacity: 0;
transition: opacity 0.3s ease-in-out;
border-radius: 10px;
}
.glow-on-hover:active {
color: #000;
}
.glow-on-hover:active:after {
background: transparent;
}
.glow-on-hover:hover:before {
opacity: 1;
}
.glow-on-hover:after {
z-index: -1;
content: "";
position: absolute;
width: 100%;
height: 100%;
background: #111;
left: 0;
top: 0;
border-radius: 10px;
}
#keyframes glowing {
0% {
background-position: 0 0;
}
50% {
background-position: 400% 0;
}
100% {
background-position: 0 0;
}
}

css grid + react component challenge

Working on a css grid challenge with React in codepen.
This is the original codepen: https://codepen.io/tallys/pen/bvwZee/
What I have so far: https://codepen.io/al2613/pen/QmOyKo
.grid-container {
border: 2px dashed goldenrod;
display: inline-grid;
padding: 10px;
grid-template-columns: auto auto;
height: 100vh;
grid-gap: 30px;
}
So I got main content area to span across the grid container. However, I'm stuck as to how I can make the aside always 150px and the grid container align nicely with the div at the top?
I'm new to grid very nice first try. I think this is a little bit hacky, but...it does the job (I guess)
I don't think the CSS on this snippet will work, but nevertheless, here's the Pen...
//Don't edit the JS for the CSS Grid challenge!
class App extends React.Component {
state = {
sidebarActive: false,
}
toggleSidebar() {
this.setState({sidebarActive: !this.state.sidebarActive})
}
render() {
const buttonText = this.state.sidebarActive ? 'Toggle Sidebar Off' : 'Toggle Sidebar On';
const {sidebarActive} = this.state
return (
<div>
<h1 className="heading">CSS Grid when some sections don't render!</h1>
<div className="instructions">
<p>The challenge: Fix the CSS Grid so that the main area takes up all of the available space when the sidebar react component does not render. </p>
<button onClick={this.toggleSidebar.bind(this)}>{buttonText}</button>
</div>
<div className="grid-container">
{sidebarActive && <aside className="sidebar">Sometimes renders!</aside>}
<main className="main">Main content area that should always take up the rest of the space in the container. </main>
</div>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
// Variables
$brand-color: darkblue;
$brand-section-color: white;
$brand-text-color: #222;
$react-accent: #61dafb;
$react-background: #292c34;
$breakpoint: 768px;
$font-heading: 'Permanent Marker', sans-serif;
$font-default: 'Oswald', sans-serif;
// Styles
body {
font-family: $font-default;
margin: 10vh 10vw;
color: $react-accent;
background: $react-background;
}
.heading {
font-family: $font-heading;
}
.instructions {
padding: 5px 12px 20px 12px;
margin-bottom: 20px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
background: lighten(adjust-hue($react-background, 30), 7);
font-size: 1.15rem;
button {
border: none;
background: $react-accent;
font-family: $font-default;
padding: 20px;
border-radius: 0;
cursor: pointer;
transition: .4s ease;
&:hover, &:active, &:focus {
background: adjust-hue($react-accent, 210);
}
}
}
.grid-container {
border: 2px dashed goldenrod;
display: inline-grid;
grid-template-columns: 150px repeat(1, 1fr);
height: 100vh;
width: 100%;
grid-gap: 30px;
}
.sidebar {
background: lighten($react-background, 7);
padding: 10px;
& ~ .main{
grid-column: auto !important;
}
}
.main {
background: darken($react-background, 7);
display: grid;
grid-column: span 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<main id="app"></main>
I know it's a really late response, but I remembered this challenge... and I couldn't resist.
My approach is fixing the main to the second column, while setting the sidebar width on the item itself (and a margin-right to fake the grid-gap), allowing for the first column to be declared as minmax(0, auto).
.grid-container {
grid-template-columns: minmax(0, auto) 1fr;
/*grid-gap: 30px;*/
}
.main {
grid-column: 2;
}
.sidebar {
margin-right: 30px;
width: 150px;
}
https://codepen.io/facundocorradini/pen/eKgVzP
That way the first column will have a zero width if the sidebar is not loaded, and get to the 150px sidebar with when it loads.

Resources