Range Slider with React and Typescript - reactjs

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);
}`;

Related

Media queries on styled-components not working until I save the js file

I'm a beginner at React.
I'm doing Netflix clone coding with CRA initial settings.
Media queries on styled-components not working until I save the js file.
And, It doesn't apply again every time I refresh browser.
import styled from 'styled-components';
const DeviceImgContainer = styled.div`
display: flex;
justify-content:stretch;
flex-grow: 1 2 1;
position: relative;
z-index: 50;
width: 60%;
height: 15%;
background-color: black;
border: 2px solid #222;
border-radius: 15px;
padding: 1%;
margin: -8.9em auto 0;
& img:nth-child(1) {
width: 22%;
}
#media (max-width: 940px) {
margin: -10em auto 0;
height: 70px;
width: 55%;
& img:nth-child(1) {
width: 16%;
}
}
`;
const TextInDevice = styled.div`
margin: 0;
padding: 1.5em 1em 0.5em;
width: 12em;
text-align: left;
& div:nth-child(1) {
font-size: 16px;
}
& div:nth-child(2) {
font-size: 12px;
color: #0071EB;
}
#media (max-width: 940px) {
width: 23.1em;
}
`;
const LoadingImg = styled.div`
background: url('https://assets.nflxext.com/ffe/siteui/acquisition/ourStory/fuji/desktop/download-icon.gif') 50% no-repeat;
background-size: 100%;
position: relative;
z-index: 51;
width: 50px;
`;
const CardSectionDiv = styled.div`
text-align: center;
height: 100%;
padding: 70px 30px;
background-color: black;
color: white;
border-bottom: 8px solid #222;
&>div {
display: flex;
flex-basis: 50%;
align-items: center;
justify-content: space-evenly;
margin: 0 auto;
max-width: 1100px;
}
#media only screen and (max-width: 940px) {
&>div {
display: block;
}
}
`;
const SectionTitleDiv = styled.div`
max-width: 540px;
min-width: 400px;
width: 40%;
color: white;
& h1 {
width: 100%;
font-size: 3rem;
margin: 0 0 8px 0;
text-align: left;
font-weight: 500;
}
& h2 {
font-size: 1.5rem;
font-weight: 500;
text-align: left;
width: 100%;
margin: 0.75rem 0 0.25rem 0;
}
#media only screen and (max-width: 940px) {
width: 100%;
margin: 0 auto;
text-align: center;
padding: 0;
& h1 {
margin: 0 auto;
text-align: center;
font-size: 2.8rem;
}
& h2 {
margin: 0 auto;
text-align: center;
font-size: 1.3rem;
}
}
`;
const ImgVideoWrapper = styled.div`
height: 70%;
max-width: 550px;
#media only screen and (max-width: 940px) {
width: 100%;
max-width: 750px;
}
`;
const ImgContainer = styled.div`
margin: 0 0 -30%;
height: 100%;
position: relative;
z-index: 3;
&>img {
border: 0;
width: 96%;
}
#media (max-width: 940px) {
margin: 0 0 -30%;
&>img {
width: 80%;
}
}
`;
const VideoContainer = styled.div`
height: 100%;
left: -3px;
transform: translate(0%, -70%);
position: relative;
video {
height: 85%;
width: 70%;
position: relative;
margin: 0
}
#media (max-width: 940px) {
video {
width: 59%;
height: 83%;
transform: translate(0%, 17%);
}
}
`;
const SecondCardSectionDiv = styled(CardSectionDiv)`
#media (max-width: 940px) {
&>div {
display: flex;
flex-direction: column-reverse;
}
}
`
const CardSection = () => {
return(
<>
<CardSectionDiv>
<div>
<SectionTitleDiv>
<h1>TV로 즐기세요</h1>
<h2>스마트 TV, playstation, XBOX, Chromecast, Apple TV, 블루레이 플레이어 등 다양한 디바이스에서 시청하세요.</h2>
</SectionTitleDiv>
<ImgVideoWrapper>
<ImgContainer>
<img alt="video-outline" src="https://assets.nflxext.com/ffe/siteui/acquisition/ourStory/fuji/desktop/tv.png" />
</ImgContainer>
<VideoContainer>
<video autoPlay playsInline muted loop>
<source src="https://assets.nflxext.com/ffe/siteui/acquisition/ourStory/fuji/desktop/video-tv-0819.m4v" type="video/mp4" />
</video>
</VideoContainer>
</ImgVideoWrapper>
</div>
</CardSectionDiv>
<SecondCardSectionDiv>
<div>
<ImgVideoWrapper>
<ImgContainer style={{ margin: "0" }}>
<img alt="stranger-things-woman" src="https://assets.nflxext.com/ffe/siteui/acquisition/ourStory/fuji/desktop/mobile-0819.jpg" />
</ImgContainer>
<DeviceImgContainer>
<img alt="black-box" src="https://assets.nflxext.com/ffe/siteui/acquisition/ourStory/fuji/desktop/boxshot.png" />
<TextInDevice>
<div>기묘한 이야기</div>
<div>저장 중...</div>
</TextInDevice>
<LoadingImg></LoadingImg>
</DeviceImgContainer>
</ImgVideoWrapper>
<SectionTitleDiv>
<h1>즐겨 보는 콘텐츠를 저장해 오프라인으로 시청하세요.</h1>
<h2>간편하게 저장하고 빈틈없이 즐겨보세요.</h2>
</SectionTitleDiv>
</div>
</SecondCardSectionDiv>
</>
);
}
export default CardSection;
This is part of it and media query does not apply to all components.
I don't know why this problem is happening.
How to solve it...?

react transition effect not work after async thunk

Although I have updated the todo status, the checkbox effect is not working correctly, as if no effect has been applied, what could be the reason for this? I don't think there is a problem with the api file, but the api request is taking a long time.I think it's because css doesn't render again, I can't think of anything else..
Thank you for helping
import React from "react";
import { useDispatch } from "react-redux";
import { toggleTodos } from "../redux/slice/thunkActions";
import styled from "styled-components";
const Content = styled.div`
color: #fff;
text-transform: capitalize;
`;
const Options = styled.div`
display: flex;
align-items: center;
justify-content: center;
gap: 2rem;
`;
const EditButton = styled.button`
cursor: pointer;
background-color: #ff6b81;
padding: 0.7rem 2rem;
color: #fff;
border-radius: 0.5rem;
font-weight: bold;
`;
const InputWrapper = styled.label`
position: relative;
`;
const Input = styled.input`
position: absolute;
left: -99999px;
top: -99999px;
&:checked + span {
background-color: #1890ff;
transition: 1s;
&:before {
left: calc(100% - 0.2rem);
transform: translateX(-100%);
}
}
`;
const Slider = styled.span`
display: flex;
width: 5rem;
height: 2.5rem;
cursor: pointer;
border-radius: 10rem;
background-color: #fcebb6;
transition: background-color 0.4s;
&:before {
content: "";
position: absolute;
top: 0.2rem;
left: 0.2rem;
width: 2.1rem;
height: 2.1rem;
border-radius: 2.1rem;
transition: 1s;
background-color: #fff;
}
`;
const Todo = ({ todo }) => {
const dispatch = useDispatch();
const handleChange = (todo) => {
dispatch(toggleTodos(todo));
};
return (
<li>
<Content>{todo.content}</Content>
<Options>
<EditButton type="button">Edit</EditButton>
<InputWrapper htmlFor={`todoContent${todo.id}`}>
<Input
id={`todoContent${todo.id}`}
type={"checkbox"}
onChange={() => handleChange(todo)}
checked={todo && todo.isCompleted}
/>
<Slider />
</InputWrapper>
</Options>
</li>
);
};
export default Todo;

Animation react Does not reset

I am working on animation in React app. I need animation starts working after hover off the button, the animation only works one time and after that for next time hover off the button does not make animation works.
I used
setTimeout(()=> {
e.target.classList.add(classes.hide);
}, 1);
to reset time to works again but it does not work out.
#keyframes rotate-before {
0% { right:0px; top:0px;}
25% { right:40px; top:0px;}
50% {bottom:10px; top:178px;right:40px;}
}
.content {
position: absolute;
inset: 30px;
z-index: 3;
display: flex;
flex-direction:column;
align-items: center;
justify-content: center;
}
.content:hover .button{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
visibility:visible;
position: relative;
}
.hover{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
visibility:visible;
position: relative;
animation: rotate-before 0.5s linear;
animation-iteration-count: 1;
}
.content .button{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
position: relative;
visibility:hidden;
}
.hide{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
position: relative;
visibility:hidden;
}
.content img {
position: absolute;
width: 100%;
height:100%;
object-fit: cover;
}
import "./App.css";
import { AnimatePresence, motion, useTransform } from "framer-motion/dist/framer-motion";
import classes from "./components/anm.module.css";
function App() {
const [isHovered, setHovered] = useState(false);
const change = (e) => {
e.target.classList.add(classes.hover);
setTimeout(()=> {
e.target.classList.add(classes.hide);
}, 1);
};
return (
<div className={classes.box}>
<div className={classes.content}>
<img
src="https://budgetreno.ca/wp-content/uploads/Pylon-25_compressed-thegem-portfolio-metro.jpg"
alt=""
/>
<motion.div className="square" onHoverEnd={change} whileHover={{}}>
<button id="test" className={classes.button}>
Follow
</button>
</motion.div>
</div>
</div>
);
}
export default App;

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;
}
}

target child element styled components

I'm trying to change the nth-child(2) background color of the ColorBox element by targeting it as a child of ImgGrid but I just can't seem to get it to work, I have tried multiple variations with different elements and nothing seems to be working
This will change the background color if I don't try to target an nth-child element
const ImgGrid = styled.div`
display: flex;
flex-wrap: wrap;
flex-direction: row;
${ColorBox} {
background: #ff00ff;
}
`
How can I target the nth-child(2) of the ColorBox element?
import React from 'react'
import styled from 'styled-components'
// import Img from '../../atoms/Img'
import { array, bool } from 'prop-types'
const Wrap = styled.div`
padding: 20px 0;
`
const BoxWrap = styled.div`
position: relative;
border: 1px solid #000;
height: auto;
padding: 20px;
`
const Title = styled.div`
position: absolute;
display: flex;
align-items: center;
top: -20px;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
height: 40px;
background: #f6f6f6;
padding: 10px;
`
const BoxInner = styled.div`
width: 100%;
height: 100%;
`
const ColorBox = styled.div`
height: 60px;
width: 100%;
background: #FFD700;
`
const ImgCell = styled.div`
flex: 0 0 25%;
padding: 5px;
`
const ImgGrid = styled.div`
display: flex;
flex-wrap: wrap;
flex-direction: row;
&:nth-child(2) ${ColorBox} {
background: #ff00ff;
}
`
const ImgCellInner = styled.div`
position: relative;
`
// const ImgText = styled.div`
// position: absolute;
// bottom: 0;
// left: 0;
// padding: 5px;
// width: 100%;
// background: rgba(0,0,0,0.7);
// color: #fff;
// `
const ImgWrap = styled.div`
width: 100%;
`
const ColorWrap = styled.div`
`
const Filter = ({ filterData, color }) => (
<Wrap>
<BoxWrap>
<Title>
For Women
</Title>
<BoxInner>
<ImgGrid>
{filterData.map(filter =>
<ImgCell>
<ImgCellInner>
<ImgWrap>
{color &&
<ColorWrap>
<ColorBox />
{filter.text}
</ColorWrap>
}
</ImgWrap>
</ImgCellInner>
</ImgCell>,
)}
</ImgGrid>
</BoxInner>
</BoxWrap>
</Wrap>
)
/* eslint-disable*/
Filter.propTypes = {
filterData: array,
color: bool,
}
Filter.defaultProps = {
filterData: array,
color: bool,
}
export default Filter
I can assume your code is not working because &:nth-child(2) means you are selecting ImgGrid which is second child itself. Try to specify ImgCell as nth-child(2):
const ImgGrid = styled.div`
display: flex;
flex-wrap: wrap;
flex-direction: row;
${ImgCell}:nth-child(2) ${ColorBox} {
background: #ff00ff;
}
`
I'm not sure about scoping, so probably you need to use & before:
const ImgGrid = styled.div`
display: flex;
flex-wrap: wrap;
flex-direction: row;
& ${ImgCell}:nth-child(2) ${ColorBox} {
background: #ff00ff;
}
`
If you stumble on this question looking for how to target all children elements, here is how;
const ParentDiv = styled.div`
>* {
background: white;
padding: 5px;
};
/* ...etc */
`;
I had the same problem. :focus-within in parent element worked for me, could solve your problem too.
Eg:
export const Parent = styled.div`
display: flex;
align-items: center;
border: 1px solid #000;
&:focus-within {
border: 1px solid #2ADCC6;
}
`;
export const Child = styled.input`
flex: 1;
border: none;
`;
Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-within

Resources