What is the reason why the pagination style is not getting applied? I am trying to display lists in row but it is not working - reactjs

Pagination.jsx
import { Box } from "#chakra-ui/react";
import React, { useEffect, useState } from "react";
import ReactPaginate from "react-paginate";
import "./Pagination.css";
export function ReactPagination({ lastPage, filterData }) {
const [pageCount, setPageCount] = useState(0);
useEffect(() => {
setPageCount(lastPage);
}, [lastPage]);
// Invoke when user click to request another page.
const handlePageClick = (event) => {
filterData(event.selected + 1);
};
return (
<Box w="full">
<ReactPaginate
breakLabel="..."
nextLabel="next >"
onPageChange={handlePageClick}
pageRangeDisplayed={4}
pageCount={pageCount}
previousLabel="< previous"
renderOnZeroPageCount={null}
containerClassName="pagination"
previousLinkClassName="pagination__link"
nextLinkClassName="pagination__link"
disabledClassName="pagination__link--disabled"
activeClassName="pagination__link--active"
/>
</Box>
);
}
Pagination.css
//css for react paginate
.pagination {
list-style: none;
display: flex !important;
gap: 4px;
justify-content: space-between;
background: red;
}
.pagination a {
padding: 10px;
border-radius: 5px;
border: 1px solid #6c7ac9;
color: #6c7ac9;
}
.pagination__link {
font-weight: bold;
}
.pagination__link--active a {
color: #fff;
background: #6c7ac9;
}
.pagination__link--disabled a {
color: rgb(198, 197, 202);
border: 1px solid rgb(198, 197, 202);
}
The pagination className in containerClassName is not getting applied but it's strange that other styles like disabledClassName, activeClassName are applied. I am trying to display lists in row but it is not working. Is there any reason or any package updates that is causing this issue?

Related

Implementing animation when removing Toast

I have a working ToastList that enables me to click a button multiple times and generate a toast each time. On entry, I have an animation, but when I remove the toast, I do not get an animation. I am using Typescript and functional components.
My component is as follows:
import React, { useCallback, useEffect, useState } from 'react';
import * as Styled from './Toast.styled';
export interface ToastItem {
id: number;
title: string;
description: string;
backgroundColor: string;
}
export interface ToastProps {
toastList: ToastItem[];
setList: React.Dispatch<React.SetStateAction<ToastItem[]>>;
}
export default function Toast(props: ToastProps) {
const deleteToast = useCallback(
(id: number) => {
const toastListItem = props.toastList.filter((e) => e.id !== id);
props.setList(toastListItem);
},
[props.toastList, props.setList]
);
useEffect(() => {
const interval = setInterval(() => {
if (props.toastList.length) {
deleteToast(props.toastList[0].id);
}
}, 2000);
return () => {
clearInterval(interval);
};
}, [props.toastList, deleteToast]);
return (
<Styled.BottomRight>
{props.toastList.map((toast, i) => (
<Styled.Notification
key={i}
style={{ backgroundColor: toast.backgroundColor }}
>
<button onClick={() => deleteToast(toast.id)}>X</button>
<div>
<Styled.Title>{toast.title}</Styled.Title>
<Styled.Description>{toast.description}</Styled.Description>
</div>
</Styled.Notification>
))}
</Styled.BottomRight>
);
}
And my styling is done using styled-components and is as follows:
import styled, { keyframes } from 'styled-components';
export const Container = styled.div`
font-size: 14px;
position: fixed;
z-index: 10;
& button {
float: right;
background: none;
border: none;
color: #fff;
opacity: 0.8;
cursor: pointer;
}
`;
const toastEnter = keyframes`
from {
transform: translateX(100%);
}
to {
transform: translateX(0%);
}
}
`;
export const BottomRight = styled(Container)`
bottom: 2rem;
right: 1rem;
`;
export const Notification = styled.div`
width: 365px;
color: #fff;
padding: 15px 15px 10px 10px;
margin-bottom: 1rem;
border-radius: 4px;
box-shadow: 0 0 10px #999;
opacity: 0.9;
transition .1s ease;
animation: ${toastEnter} 0.5s;
&:hover {
box-shadow: 0 0 12px #fff;
opacity: 1;
}
`;
export const Title = styled.p`
font-weight: 700;
font-size: 16px;
text-align: left;
margin-bottom: 6px;
`;
export const Description = styled.p`
text-align: left;
`;
When I click a button, I just add an element to the state list, like:
toastProps = {
id: list.length + 1,
title: 'Success',
description: 'Sentence copied to clipboard!',
backgroundColor: '#5cb85c',
};
setList([...list, toastProps]);
My component is rendered like:
<Toast toastList={list} setList={setList}></Toast>
I would like to add animation when a toast exits, but do not know how. I have tried changing the style according to an additional prop I would send to the styled components, but this way all the toasts animate at the same time. My intuition is that I should use useRef(), but I am not sure how. Thanks in advance for any help you can provide.

REACT + TypeScript Accordion transition doesn't works

Sup guys i have a problem, i would like to do an animated accordion, it should to have a transition animated when it opens and collapse, and in icon switching
I'm creating by myself an accordion in react + typescript but this transition doesnt works and idk why, code below:
This my index.tsx
import { useState } from "react";
import { AccordionButton, AccordionContent, Wrapper } from "./styles";
import { AccordionProps } from "./interfaces";
import { BsChevronDown, BsChevronUp } from "react-icons/bs";
export default function Accordion({ title, text }: AccordionProps) {
const [isOpen, setIsOpen] = useState(false);
const handleClick = () => {
setIsOpen(!isOpen);
returnIcon();
};
const returnIcon = () => {
return isOpen ? <BsChevronUp /> : <BsChevronDown />;
};
return (
<Wrapper>
<AccordionButton onClick={handleClick}>
{title} {returnIcon()}
</AccordionButton>
<AccordionContent isOpen={isOpen}>
<p>{text}</p>
</AccordionContent>
</Wrapper>
);
}
and this is my styled component below:
import styled from "styled-components";
import { AccordionContentProps } from "./interfaces";
export const AccordionButton = styled.button`
background-color: #606582;
color: #ffffff;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.6s;
&:hover {
background-color: #60658295;
}
> svg {
float: right;
}
`;
export const AccordionContent = styled.div<AccordionContentProps>`
display: ${(props) => (props.isOpen === false ? "none" : "block")};
padding: 0 18px;
background-color: white;
overflow: hidden;
`;
export const Content = styled.div`
padding: 10px 0px;
flex-wrap: wrap;
max-width: 750px;
margin-right: auto;
margin-left: auto;
#media only screen and (max-width: 600px) {
max-width: 80%;
}
`;
export const Wrapper = styled.div`
padding: 10px 0px;
`;
I've tried to add this code but still doesnt working
-webkit-transition: all 0.4s ease-in;
-moz-transition: all 0.4s ease-in;
-o-transition: all 0.4s ease-in;
transition: all 0.4s ease-in;
Try to replace the return block with the following:
return (
<Wrapper>
{isOpen && <AccordionButton onClick={handleClick}>
{title} <BsChevronUp />
</AccordionButton>}
{!isOpen && <AccordionButton onClick={handleClick}>
{title} <BsChevronDown />
</AccordionButton>}
<AccordionContent isOpen={isOpen}>
<p>{text}</p>
</AccordionContent>
</Wrapper>)
and we can also delete the function returnIcon - we don't need it

Custom arrow Swiper Slider + Next.js + Sass

I'm using the slider swiper in a project developed in Next.JS and I'm using Sass to do the styling. But when I'm going to use the swiper classes, as mandated by the documentation, to style the arrows, it doesn't work.
I need the arrows to be outside the component, not overlapping.
CSS
.swiper-button-next,
.swiper-button-prev {
background: red;
position: absolute;
top: 50%;
width: calc(var(--swiper-navigation-size) / 44 * 27);
height: var(--swiper-navigation-size);
margin-top: calc(0px - (var(--swiper-navigation-size) / 2));
z-index: 10;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--swiper-navigation-color, var(--swiper-theme-color));
}
.swiper-button-next.swiper-button-disabled,
.swiper-button-prev.swiper-button-disabled {
opacity: 0.35;
cursor: auto;
pointer-events: none;
}
.swiper-button-next:after,
.swiper-button-prev:after {
background: red;
font-family: swiper-icons;
font-size: var(--swiper-navigation-size);
text-transform: none !important;
letter-spacing: 0;
text-transform: none;
font-variant: initial;
line-height: 1;
}
.swiper-button-prev,
.swiper-container-rtl .swiper-button-next {
left: 10px;
right: auto;
}
.swiper-button-prev:after,
.swiper-container-rtl .swiper-button-next:after {
content: "prev";
color: #000;
}
.swiper-button-next,
.swiper-container-rtl .swiper-button-prev {
right: 10px;
left: auto;
}
.swiper-button-next:after,
.swiper-container-rtl .swiper-button-prev:after {
content: "next";
}
.swiper-button-next.swiper-button-white,
.swiper-button-prev.swiper-button-white {
--swiper-navigation-color: #ffffff;
}
.swiper-button-next.swiper-button-black,
.swiper-button-prev.swiper-button-black {
--swiper-navigation-color: #000000;
}
.swiper-button-lock {
display: none;
}
I've tried changing the styles, but nothing reflects on the component. If I change styles by browser it works normally.
Changing the basic arrows styles is pretty simple - take a look at the following codesandbox: https://codesandbox.io/s/stoic-shaw-q35wq?file=/src/styles.scss
.swiper-button-prev, .swiper-button-next {
top: 45%;
width: 40px;
height: 40px;
background: #fff;
border: 1px solid gray;
border-radius: 50%;
color: blue;
font-weight: 700;
outline: 0;
transition: background-color .2s ease, color .2s ease;
&::after {
font-size: 16px;
}
}
.swiper-button-prev {
&:after {
position: relative;
left: -1px;
}
}
.swiper-button-next {
&:after {
position: relative;
left: 1px;
}
}
.swiper-button-prev, .swiper-container-rtl .swiper-button-next {
left: 10px;
right: auto;
}
.swiper-button-next, .swiper-container-rtl .swiper-button-prev {
right: 10px;
left: auto;
}
.swiper-button-prev.swiper-button-disabled, .swiper-button-next.swiper-button-disabled {
opacity: 0;
cursor: auto;
pointer-events: none;
}
Moving the arrows outside, however, is a bit more tricky. In the example above I've used a little CSS tricks (negative margin and corresponding padding) and some overflows to get it working but it might not be enough for your use case.
You would have to create your own next/previous elements:
import React from "react";
import { Navigation, Pagination, Scrollbar, A11y, Controller } from "swiper";
import { Swiper, SwiperSlide } from "swiper/react";
// Import Swiper styles
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "swiper/css/scrollbar";
import "./styles.scss";
const image = "https://source.unsplash.com/featured/300x201";
export default function App() {
const images = new Array(6).fill({ url: image });
const [swiper, setSwiper] = React.useState();
const prevRef = React.useRef();
const nextRef = React.useRef();
React.useEffect(() => {
if (swiper) {
console.log("Swiper instance:", swiper);
swiper.params.navigation.prevEl = prevRef.current;
swiper.params.navigation.nextEl = nextRef.current;
swiper.navigation.init();
swiper.navigation.update();
}
}, [swiper]);
return (
<div className="App">
<div className="carousel-container">
<div className="swiper-button" ref={prevRef}>
prev
</div>
<Swiper
modules={[Navigation, Pagination, Scrollbar, A11y, Controller]}
className="external-buttons"
spaceBetween={24}
slidesPerView={1}
navigation={{
prevEl: prevRef?.current,
nextEl: nextRef?.current
}}
updateOnWindowResize
observer
observeParents
initialSlide={2}
onSwiper={setSwiper}
>
{images.map((image, index) => (
<SwiperSlide key={index}>
<img
height="200"
width="300"
alt="img"
className="image"
src={image.url}
/>
</SwiperSlide>
))}
</Swiper>
<div className="swiper-button" ref={nextRef}>
next
</div>
</div>
</div>
);
}
Complete example - https://codesandbox.io/s/prod-darkness-o483y?file=/src/App.js
Important - the examples are using Swiper v7
Here is the best way to add custom arrows:
import React, { useRef } from "react";
// For Typescript
// import SwiperCore from "swiper";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
const SliderComponent = () => {
const swiperRef = useRef();
// For Typescript!
// const swiperRef = useRef<SwiperCore>();
const sliderSettings = {
440: {
slidesPerView: 1,
spaceBetween: 30,
},
680: {
slidesPerView: 2,
spaceBetween: 30,
},
1024: {
slidesPerView: 3,
spaceBetween: 30,
},
};
return (
<div>
<button onClick={() => swiperRef.current?.slidePrev()}>Prev</button>
<Swiper
slidesPerView={3}
breakpoints={sliderSettings}
onBeforeInit={(swiper) => {
swiperRef.current = swiper;
}}
>
<SwiperSlide>
Slide 1
</SwiperSlide>
<SwiperSlide>
Slide 2
</SwiperSlide>
<SwiperSlide>
Slide 3
</SwiperSlide>
<SwiperSlide>
Slide 4
</SwiperSlide>
<SwiperSlide>
Slide 5
</SwiperSlide>
</Swiper>
<button onClick={() => swiperRef.current?.slideNext()}>Next</button>
</div>
);
};
export default SliderComponent;
hamza liaqat's answer is correct, but for typescript you need to add
import { Swiper as SwiperCore } from 'swiper/types';

React input checkbox checked

I have use React-redux and styled components for my app. I store my initial state theme as a string which is light and dark. then I connect my styled components intial light theme and dark theme in my root app. My dark mood works fine when i used select options but when i used input checkbox it does not work. I never used input checkbox, after reading couple example I used checked and put my initial theme(which is coming from my redux store), then in my handleChange I did, if the event target has dark then dispatch the dark theme. But nothing happening in that handle change. don't know what i am doing wrong.
Here is my toggle component
import React, { useState } from 'react';
import styled from 'styled-components';
import { useDispatch, useSelector } from 'react-redux';
import { appSettings } from '../../state/appSettings';
import { TRootState } from '../../state/index';
export default function Toggle({ }: IProp) {
const dispatch = useDispatch();
const { "appSettings": appSettingState } = useSelector((state: TRootState) => state);
const { theme } = appSettingState || {};
console.log(theme); // inital state which is "light".
return (
<>
{/* This input checkbox does not work */}
<CheckBoxWrapper>
<CheckBox
onChange={(e) => { // This function does not work
e.target.value === `dark` ?
dispatch(appSettings?.actions?.enableDarkTheme()) :
dispatch(appSettings?.actions?.enableLightTheme());
}}
id="toggleSwitch"
type="checkbox"
Checked={theme === `light`}
/>
<CheckBoxLabel htmlFor="toggleSwitch" />
</CheckBoxWrapper>
<br></br>
{/* THIS SELECT OPTIONS WORK FINE. AND I CAN GET DARK AND LIGHT THEME */}
<h2>Theme</h2>
<select
name="theme"
id="theme-select"
value={theme}
onChange={(e) => {
if (e.target.value === `dark`) {
dispatch(appSettings?.actions?.enableDarkTheme());
} else {
dispatch(appSettings?.actions?.enableLightTheme());
}
}}
>
<option value="dark">Dark</option>
<option value="light">Light</option>
</select>
</>
);
}
// This toogle input styled
const CheckBoxWrapper = styled.div`
position: fixed;
top:10px;
right:10px;
`;
const CheckBoxLabel = styled.label`
position: absolute;
top: 0;
left: 0;
width: 42px;
height: 26px;
border-radius: 15px;
background: #bebebe;
cursor: pointer;
&::after {
content: "";
display: block;
border-radius: 50%;
width: 18px;
height: 18px;
margin: 3px;
background: #ffffff;
box-shadow: 1px 3px 3px 1px rgba(0, 0, 0, 0.2);
transition: 0.2s;
}
`;
const CheckBox = styled.input`
opacity: 0;
z-index: 1;
border-radius: 15px;
width: 42px;
height: 26px;
&:checked + ${CheckBoxLabel} {
background: #4fbe79;
&::after {
content: "";
display: block;
border-radius: 50%;
width: 18px;
height: 18px;
margin-left: 21px;
transition: 0.2s;
}
}
`;
Check the change event's checked property. e.target.checked
<CheckBox
onChange={(e: any) => {
e.target.checked
? dispatch(appSettings?.actions?.enableDarkTheme())
: dispatch(appSettings?.actions?.enableLightTheme());
}}
id="toggleSwitch"
type="checkbox"
Checked={theme === `light`}
/>

Why child Styled-components is not applying styles?

I have a Notification component :
import React, { useContext } from "react"
import Wrapper from "./Wrapper"
import context from "./context"
import Close from "./Close"
const Notification = ({ children }) => {
const { type } = useContext(context)
return (<Wrapper type={type}>
<Close /> {// This component does not apply styles !!}
{children}
</Wrapper>)
}
export default Notification
My Wrapper :
import styled from "styled-components"
const Wrapper = styled.div`
position:absolute;
bottom:0;
right:0;
margin-right:1.2em;
margin-bottom:1.2em;
background-color: #fff;
padding:15px;
min-width:350px;
min-height:100px;
border-radius:20px;
box-shadow: 0px 4px 30px 0px ${({ type }) => pickShadowColor(type)}}`
const pickShadowColor = (type) => {
switch (type) {
case "info": return "rgba(51,153,255,0.3)";
case "warning": return "rgba(255,157,0,0.3)";
case "success": return "rgba(0,216,0,0.3)";
case "error": return "rgba(255,0,0,0.3)";
default: return "rgba(190,190,190,0.3)";
}
}
export default Wrapper
The result is :
The problem is with Close component while it has a custom style but it still shows the default style of button.
Close component :
import React from 'react';
import { Button } from './Button';
const Close = () => (
<Button>close</Button>
)
export default Close;
and the styled Button :
import styled from 'styled-components';
export const Button = styled.button({
'background-color': 'red'
})
Expected Behavior
The button should be red.
Actual Behavior
The button has a default style.
Additional Info
Navigator: Chrome.
The button does not accept any styles.
The problem its on box-shadow. You are missing a ; and have an extra {
Change it FROM:
box-shadow: 0px 4px 30px 0px ${({ type }) => pickShadowColor(type)}}`;
TO:
box-shadow: 0px 4px 30px 0px ${({ type }) => pickShadowColor(type)};`;
The complete style:
const Wrapper = styled.div`
position: absolute;
bottom: 0;
right: 0;
margin-right: 1.2em;
margin-bottom: 1.2em;
background-color: #fff;
padding: 15px;
min-width: 350px;
min-height: 100px;
border-radius: 20px;
box-shadow: 0px 4px 30px 0px ${({ type }) => pickShadowColor(type)};
`;

Resources