Hello everyone i have a question according to my case, i have
index.js code bellow :
export default function Home({ productList }) {
return (
<div className={styles.container}>
<Head>
<title>OlResto UI Design With Next JS</title>
<meta name="description" content="This is stunning website build using next js" />
<link rel="icon" href="/favicon.ico" />
</Head>
<Featured />
<ProductList productList={ productList } />
</div>
);
};
export const getServerSideProps = async () => {
const res = await axios.get("http://localhost:3000/api/products");
return {
props: {
productList: res.data
}
}
};
the second one i have file call ProductList.jsx
code below:
const ProductList = ({ productList }) => {
return (
<div className={styles.container}>
<h1 className={styles.title}>THE BEST PIZZA IN TOWN</h1>
<p className={styles.desc}>Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint, nemo at, labore porro reiciendis rem ad tempora blanditiis adipisci a eum animi obcaecati, dignissimos non perspiciatis natus corrupti consectetur libero.</p>
<div className={styles.wrapper}>
{productList.map(product => (
<ProductCard key={product._id} product={product} />
))}
</div>
</div>
);
};
export default ProductList;
Those files produce an error like this :
TypeError: productList.map is not a function
<div className={styles.wrapper}>
{productList.map(product => (
^
<ProductCard key={product._id} product={product} />
))}
</div>
Sorry if my question messed up, hope you guys can help my problem, thank you in advance
Related
I am new to NextJs/ReactJs and I was trying to implement the Responsive slide with Swiperjs which is available in codepen.io
Here is the link to codepen.
Responsive slider timeline with Swiper
Below are my steps I carried out;
Installed JQuery (npm install)
Imported both swiper.min.css and swiper.min.js CDNs to my _Document.js file
Added the css files to Globals.css for time being
Created a TimelineComponent.js to have the swiper component separately.
imported TimelineComponent.js in the index.js
When I run the project it nicely shows you the expected output as below.
But when I resize my browser it behaves abnormally like below
import React, { useEffect } from 'react';
import $ from 'jquery';
function TimeLineComponent() {
function operateTimeline() {
var timelineSwiper = new Swiper('.timeline .swiper-container', {
direction: 'vertical',
loop: false,
speed: 1600,
pagination: '.swiper-pagination',
paginationBulletRender: function (swiper, index, className) {
var year = document
.querySelectorAll('.swiper-slide')
[index].getAttribute('data-year');
return '<span class="' + className + '">' + year + '</span>';
},
paginationClickable: true,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
breakpoints: {
768: {
direction: 'horizontal',
},
},
});
}
useEffect(() => {
$(window).on('load resize', operateTimeline);
operateTimeline();
return () => {
$(window).off('load resize');
};
}, []);
return (
<div className="timeline-container">
<div className="timeline">
<div className="swiper-container">
<div className="swiper-wrapper">
<div
className="swiper-slide"
style={{
backgroundImage: "url('https://unsplash.it/1920/500?image=11')",
}}
data-year="2011"
>
<div className="swiper-slide-content">
<span className="timeline-year">2011</span>
<h4 className="timeline-title">Our nice super title</h4>
<p className="timeline-text">
Lorem ipsum dolor site amet, consectetur adipscing elit, sed
do eisumod tempor incididut ut labore et dolore magna aliqua.
Ut enim ad mimim venjam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
<div
className="swiper-slide"
style={{
backgroundImage: "url('https://unsplash.it/1920/500?image=12')",
}}
data-year="2012"
>
<div className="swiper-slide-content">
<span className="timeline-year">2012</span>
<h4 className="timeline-title">Our nice super title</h4>
<p className="timeline-text">
Lorem ipsum dolor site amet, consectetur adipscing elit, sed
do eisumod tempor incididut ut labore et dolore magna aliqua.
Ut enim ad mimim venjam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
</div>
<div className="swiper-button-prev"></div>
<div className="swiper-button-next"></div>
<div className="swiper-pagination"></div>
</div>
</div>
</div>
);
}
export default TimeLineComponent;
Error can be replicated in the above codepen example as well. Most probably this is with the styling
Your help is much appreciated.
I've created an accordion with TailwindCSS and Alpine.js which works fine except that I also want to change the icon in the button that expands the content when it's clicked.
This is what I have:
<div x-data="{selected:null,open:true}">
<dl class="faqs mx-auto max-w-2xl">
<dt>
<span class="faq-q">Question</span>
<button
type="button"
class="faq-toggle"
#click="selected !== 1 ? selected = 1 : selected = null, open = open"
:class="{ 'faq-open': open, 'faq-close': !(open) }"
>
<span>+</span>
<span class="hidden">-</span>
</button>
</dt>
<dd
class="faq-a overflow-hidden transition-all max-h-0 duration-700"
style="" x-ref="container1" x-bind:style="selected == 1 ? 'max-height: ' + $refs.container1.scrollHeight + 'px' : ''"
>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
</div>
</dd>
</dl>
</div>
and a link to a CodePen.
What I want to do is toggle the class of the button from faq-open to faq-close when the button is clicked. Although I may actually need to toggle a class on the parent dt too.
At the moment, the accordion expands when you click on the button, but the class doesn't change.
The problem is on this line
#click="selected !== 1 ? selected = 1 : selected = null, open = open"
You never change value of open, it is always the value at initialization, and that is open: true.
You need to switch it:
#click="selected !== 1 ? selected = 1 : selected = null, open = !open"
By the way, you don't need extra variable selected to control the hidden text, just one open variable is enough. Something like this:
<div x-data="{open: true}">
<dl class="faqs mx-auto max-w-2xl">
<dt>
<span class="faq-q">Question</span>
<button
type="button"
class="faq-toggle"
#click="open = !open"
:class="open ? 'faq-open' : 'faq-close'"
>
<span :class="open ? '' : 'hidden'">+</span>
<span :class="open ? 'hidden' : ''">-</span>
</button>
</dt>
<dd
class="faq-a overflow-hidden transition-all max-h-0 duration-700"
style="" x-ref="container1" x-bind:style="open ? 'max-height: ' + $refs.container1.scrollHeight + 'px' : ''"
>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
</div>
</dd>
</dl>
import 'twin.macro';
import React, { useRef, useState } from 'react';
import { BiPlus, BiMinus } from 'react-icons/bi';
const Accordion = ({ title, children }) => {
const [active, setActive] = useState(false);
const [height, setHeight] = useState('0px');
const contentSpace = useRef(null);
function toggleAccordion() {
setActive(!active);
setHeight(active ? '0px' : `${contentSpace.current?.scrollHeight}px`);
}
return (
<div tw="flex flex-col outline-none" role="button" tabIndex={0}>
<div
tw="flex flex-row items-center justify-between py-4 border-b border-t border-black "
onClick={toggleAccordion}>
<h1 tw="cursor-pointer text-base font-bold">{title}</h1>
{active ? <BiMinus /> : <BiPlus />}
</div>
<div
ref={contentSpace}
style={{ maxHeight: `${height}` }}
tw="overflow-auto overflow-y-hidden duration-700 ease-in-out">
<p tw="my-4">{children}</p>
</div>
</div>
);
};
export default Accordion;
This question already has answers here:
Is there a CSS selector for elements containing certain text?
(20 answers)
Closed 1 year ago.
I have a lot of <p> tags on thousands of pages.
There are hundreds of <p> tags like below.
<p>Read: Example</p>
Those start with Read:.
I want t to apply some CSS to <p> tag only if the paragraph starts with Read:. Is it possible?
This is not posible with CSS alone, you would need Javascript to achieve this.
This example shows you...
#1. How to use Javascript to search your documents p tags and find strings where the 1st index of the string is set to the target string Read: using indexOf().
#2. How to then set an attribute, el.setAttribute(), on that tag that identifies that element as a Read: element containing the string we want to affect in our CSS.
#3. How to use CSS + elements attribute to then style the target elements in the DOM as you want them styled.
const p = [...document.getElementsByTagName('p')] -> create an
array of elements we can then loop over using tag.forEach()
tag.textContent.indexOf("Read:") === 0-> lets find elements that
have target string at the very beginning of the tag.textContent.
tag.setAttribute("data-read", true) -> set the tags data-read
attribute to true
p[data-read="true"] in CSS we style all elements that are p tags
and have the attribute <p data-read="true">
Using this method we are able to use CSS to style the tags and JS to find them.
const p = [...document.getElementsByTagName('p')]
p.forEach(tag=>tag.textContent.indexOf("Read:") === 0 ? tag.setAttribute("data-read", true) : false)
p[data-read="true"] {
background-color: lightgreen;
font-weight: bold;
color: darkgreen;
}
p[data-read="true"]:after {
content: ' *';
}
p[data-read="true"]:before {
content: '* ';
}
<div>
<p>Read: some info</p>
<p>Read: some info</p>
<p>p tag content</p>
<p>more ptag info</p>
<p>Perhaps the p content has a sentence that starts with the string and we do not want to get that one. Read: Speak: Listen:</p>
<p>Read: At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.</p>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<p>Read: More</p>
<p>Read: More</p>
<p>Hey</p>
<p>Hello</p>
<p>Lorem ipsum dolor sit amet, consectet Read: More</p>
<script>
let list = document.getElementsByTagName("p");
for (let i = 0; i < list.length; i++) {
if (list[i].textContent.startsWith("Read:")) {
list[i].style.color = "red";
}
}
</script>
</body>
</html>
I don't know if CSS have such selectors but you can still achieve your goal with JavaScript
let list = document.getElementsByTagName("p");
for (let i = 0; i < list.length; i++) {
if (list[i].textContent.startsWith("Read:")) {
list[i].style.color = "red";
}
}
I'm working on a project in Next.js (React) for the first time. It's a static site (only frontend).
Somehow I run into lots of problems related to the CSS transitions and I can't catch what am I missing.
When using some ready components, for example Modal from react-bootstrap, the transition seems to be working on Modal show, but not on hide. Transitions from Accordion, from the same module, work fine, but didn't work from other Accordion component I tried before that.
I will put some code here, but I have a filling, that there is some fundamental css/js related topic that I don't understand fully, but my searches didn't bring me the answer yet.
Here is the sample of the component, the related CSS is the default bootstrap-css (for the sake of simplicity):
Nav.tsx
import Link from 'next/link'
import navStyles from '../styles/Nav.module.css'
import homeStyles from "../styles/Home.module.css"
import {useState} from "react";
import Modal from "react-bootstrap/cjs/Modal"
import Button from "react-bootstrap/cjs/Button";
const MyVerticallyCenteredModal = (props) => {
return (
<Modal
{...props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
>
<Modal.Header>
<Button onClick={props.onHide}>X</Button>
</Modal.Header>
<Modal.Body>
<p style={{color: "white"}}>Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Aliquid at consequuntur cum ducimus enim fuga hic laudantium magni
maiores, molestias nesciunt nihil nisi nostrum pariatur perspiciatis rem rerum
suscipit, unde?</p>
</Modal.Body>
<Modal.Footer>
<Button onClick={props.onHide}>Close</Button>
</Modal.Footer>
</Modal>
);
}
const Nav = () => {
const [modalShow, setModalShow] = useState(false);
const NavComp = () => {
return (
<>
<div className={navStyles.wrapper}>
<div className={`${homeStyles.home} ${homeStyles.mobile}`}>
<div className={navStyles.footer}>
<button
className={`${navStyles.footerBtn}`}
onClick={() => setModalShow(true)}
style={{borderLeft: "1px rgba(70,70,70,0.5) solid"}}
>
Contact
</button>
<MyVerticallyCenteredModal
show={modalShow}
onHide={() => setModalShow(false)}
/>
</div>
</div>
</div>
</>
)
}
return (
<nav className={navStyles.nav}>
<div className={navStyles.container}>
<div className={navStyles.logo}>
<Link href='/'>
<div>
<p className={navStyles.kaveem}>KAVEEM</p>
</div>
</Link>
</div>
<NavComp/>
</div>
</nav>
);
};
export default Nav;
I'm trying to use a Carousel slider on my website but all of the images are not showing. I'm using an example provided by a library but it's not working.
I've linked the Bootstrap CDN in my HTML file but it does not help.
import React, { Component } from 'react';
import {Carousel,} from 'react-bootstrap';
import Carousel from 'nuka-carousel';
class Slider extends Component {
render() {
return (
<Carousel autoplay={true}>
<img src="../asset/img1.jpg" />
<img src="http://placehold.it/1000x400/ffffff/c0392b/&text=slide2" />
<img src="http://placehold.it/1000x400/ffffff/c0392b/&text=slide3" />
<img src="http://placehold.it/1000x400/ffffff/c0392b/&text=slide4" />
<img src="http://placehold.it/1000x400/ffffff/c0392b/&text=slide5" />
<img src="http://placehold.it/1000x400/ffffff/c0392b/&text=slide6" />
</Carousel>
);
}
}
export default Slider;
You are using 2 different Carousels from 2 different library's I'm sure this will cause some issues.
Remove import Carousel from 'nuka-carousel';
I would stick to using react-bootstrap version
install package: npm install --save react-bootstrap
Add stylesheet to your HTML:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
Make sure you are importing it properly like so:
import {Carousel} from 'react-bootstrap';
The example from the actual react-bootstrap
class ControlledCarousel extends React.Component {
constructor(props, context) {
super(props, context);
this.handleSelect = this.handleSelect.bind(this);
this.state = {
index: 0,
direction: null
};
}
handleSelect(selectedIndex, e) {
alert(`selected=${selectedIndex}, direction=${e.direction}`);
this.setState({
index: selectedIndex,
direction: e.direction
});
}
render() {
const { index, direction } = this.state;
return (
<Carousel
activeIndex={index}
direction={direction}
onSelect={this.handleSelect}
>
<Carousel.Item>
<img width={900} height={500} alt="900x500" src="/carousel.png" />
<Carousel.Caption>
<h3>First slide label</h3>
<p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
</Carousel.Caption>
</Carousel.Item>
<Carousel.Item>
<img width={900} height={500} alt="900x500" src="/carousel.png" />
<Carousel.Caption>
<h3>Second slide label</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</Carousel.Caption>
</Carousel.Item>
<Carousel.Item>
<img width={900} height={500} alt="900x500" src="/carousel.png" />
<Carousel.Caption>
<h3>Third slide label</h3>
<p>
Praesent commodo cursus magna, vel scelerisque nisl consectetur.
</p>
</Carousel.Caption>
</Carousel.Item>
</Carousel>
);
}
}
render(<ControlledCarousel />);