Sitecore NextJs Carousel - next.js

I want to build a Carousel in Sitecore NextJs. I found a carousel package to do so, but it hardcodes the number of slides. Since the author will create the slides dynamically in Sitecore, my NextJs component should be smart enough to detect the number of "child slides" added to the Carousel and render them accordingly.
This is the example I found online:
import React, { Component } from 'react';
import "react-responsive-carousel/lib/styles/carousel.min.css";
import { Carousel } from 'react-responsive-carousel';
export default class NextJsCarousel extends Component {
render() {
return (
<div>
<h2>NextJs Carousel - GeeksforGeeks</h2>
<Carousel>
<div>
<img src="/1.png" alt="image1"/>
<p className="legend">Image 1</p>
</div>
<div>
<img src="/2.png" alt="image2" />
<p className="legend">Image 2</p>
</div>
<div>
<img src="/3.png" alt="image3"/>
<p className="legend">Image 3</p>
</div>
<div>
<img src="/4.png" alt="image4"/>
<p className="legend">Image 4</p>
</div>
<div>
<img src="/5.png" alt="image5"/>
<p className="legend">Image 5</p>
</div>
</Carousel>
</div>
);
}
};
Instead, I want the Slides within the Carousel to be dynamic and use a loop based on how many slides are added under my Carousel component in Sitecore.

I am using react-slick for my carousels you may follow something similar approach as i did for your react-responsive-carousel.
My Slider Component:
export const MainSlider: FC<SliderProps> = ({
settings,
data,
type,
className,
}) => {
if (!(data.length > 0)) return null;
return (
<Fragment>
<div className="mian-slider">
<div className="container cus-container">
<div className="main-sec-slider">
<div className="img-box-back" />
<SlickSlider {...settings} className={className}>
{data.map((value, index) => {
return (
<div key={index}>
{type === "main-carousel"
? InnerSlider.Main(value)
: InnerSlider.Article(value)}
</div>
);
})}
</SlickSlider>
</div>
</div>
</div>
</Fragment>
);
};
Inside map function you can pass another component as i did with name InnerSlider which contains html code for your carousel images.
In your case you need to pass this:
<div>
<img src="/1.png" alt="image1"/>
<p className="legend">Image 1</p>
</div>
at last pass props data for MainSlider component :
<MainSlider
settings={settings}
data={[YOUR_SLIDER_DATA_ARRAY]}
type="main-carousel"
className="slider-main-text"
/>

Related

Footer component isn't placed correctly

I have an AppLayout component which has:
A div with the h-full utility class, to make it take the full page height.
A Background component to make a background with blur. It has three main elements:
Navbar
Outlet, which dynamically changes height
Footer
import { Outlet } from 'react-router-dom';
import Background from '../components/Background';
import Footer from '../components/Footer';
import NewNavbar from '../components/NewNavbar';
export const AppLayout = () => (
<div className='h-full'>
<Background>
<div className='min-h-full backdrop-blur-2xl flex flex-col'>
<div>
<NewNavbar />
</div>
<div className='flex-auto'>
<Outlet />
</div>
<div className=''>
<Footer />
</div>
</div>
</Background>
</div>
);
As you see, I applied flex flex-col to my "wrapper" div and flex-auto to a div wrapping my Outlet component, but this is not working. When I use straight HTML and CSS, the footer is placed correctly at the bottom of the page, and it always works.
All was so simple.
export const AppLayout = () => (
<div className='h-full'>
<Background >
<div className='min-h-screen backdrop-blur-2xl flex flex-col'>
<div>
<NewNavbar />
</div>
<div className='flex-auto'>
<Outlet />
</div>
<div>
<Footer />
</div>
</div>
</Background>
</div>
);
Replace the min-h-full to min-h-screen

How to create Bootstrap rows in a React component?

I have a Hit const which displays products (from Algolia). I use it in my main component. I would like to display the products in a row, however, I don't know how to do that, since if I write the row class around the const (in the main component) it doesn't work.
The Hit const is in a way mapping multiple products and I can't create a row from it, because placing row around Hit in the main component treats it as if it were one item and placing row inside of Hit treats each product as one row.
How could each product from Hit be displayed as a column inside a row?
This is the Hit const:
const Hit = ({ hit }) => (
<div className="col-6 col-sm-4 col-md-3">
<a className="mb-5 d-block font-color-black cursor-pointer">
<div
className="mb-3"
style={{
paddingBottom: "125%",
background: `url("${hit.image}") center center/cover`,
}}
></div>
<p className="font-size-subheader mb-2 font-weight-medium">
{hit.product}
</p>
<p className="font-size-subheader font-weight-medium pb-2 borderbottom border-color-black">
{hit.cena} <span className="hit-em">€</span>{" "}
</p>
</a>
</div>
);
This is the return of the main component, where Hit is used:
return (
<InstantSearch
searchClient={searchClient}
indexName="Besedilo"
searchState={props.searchState}
createURL={props.createURL}
onSearchStateChange={props.onSearchStateChange}
>
<div className="py-5 my-5">
<div className="py-4">
{/* Main Content */}
<div className="custom-container">
<div className="row">
<div className="col-12 col-lg-10 offset-lg-2">
<div className="collection">
<div className="row mb-5 collection-1">
<Hits hitComponent={Hit} /> //this is how Hit is used
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</InstantSearch>
);

React Component css in JS

I am new at react and I can understand the difference between React.Component and a function.
In these two pictures I have the same HTML and the same CSS but my CSS is done in the javascript file. When I use the CSS in a function, it works, but in a react component it does not.
Component
render() {
const classes = useStyles();
return (
<div style={section}>
<div style={container}>
<div>
<div style={title}>
<h1>TEste</h1>
</div>
</div>
</div>
</div>
)
}
Function
const classes = useStyles();
return (
<div className={classes.section}>
<div className={classes.container}>
<div>
<div className={classes.title}>
<h1>1</h1>
</div>
</div>
</div>
</div>
);

Eliminate space between two bootstrap columns

I started creating a blog like react application and using bootstrap grid system.
There seems to be a big space between my two columns. Is there a way to get rid of this?
A screen shot is attached.
import React from 'react';
import ReactDom from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
import faker from 'faker';
//Now create a new component
const App = () => {
const myCustomStyle = {color:'green', fontSize:'50px'}
return (
<div className="container">
<div className="row">
<div class="col-3">
<img alt="avatar" src={faker.image.avatar()}></img>
</div>
<div class="col-9" >
<p><b>Alex</b><span>Today at 5.00pm</span></p>
<p>Great blog post!</p>
</div>
</div>
</div>
)
}
ReactDom.render(<App />, document.querySelector('#root'))
Use the Bootstrap 4 auto layout columns instead...
col-auto - flex shrink
col - flex grow
<div class="container">
<div class="row">
<div class="col-auto">
<img alt="avatar" src="//placehold.it/100" />
</div>
<div class="col">
<p><b>Alex</b><span>Today at 5.00pm</span></p>
<p>Great blog post!</p>
</div>
</div>
</div>
https://www.codeply.com/go/ZHoBi8rAHB

How to a use bootstrap grid for an array created by a map method in react?

I am pulling data from an api and mapping over the JSON array to display the results, how do I use bootstrap grid to make the elements show one beside another instead of like a list?
//App.js
<div>
<FileHeader/>
{this.state.films.map(film=>(
<div className="container">
<div key={film.id} id='cardItem' className=''>
<MovieCard film={film}/>
</div>
</div>
))}
</div>
And this is the MovieCard Component
render() {
var film = this.props.film;
return(
<div className='card' style={{width:'18rem'}}>
<div className="card-body">
<h5 className="card-title">{film.title}</h5>
<h6 className='card-subtitle mb-2 text-muted'>{film.release_date}</h6>
<p className='card-text'>{film.description}</p>
</div>
</div>
)
}
How do I use the grid element to display the cards side by side?
You should only have 1 container for your items, so get it out of the map(), then insert a row in which you'll inject the card elements. You'll have to decide how much items you want on each row. In the example below you'll have 12 items per row as a row is made of 12 columns and col-xs-1 means each item will take 1 column in the row.
You can decide it per each screen size using col-xs, col-sm etc...
<div className="container">
<div className="row">
{this.state.films.map(film => (
<div key={film.id} id="cardItem" className="col-xs-1">
<MovieCard film={film} />
</div>
))}
</div>
</div>
Please try this....
<div className="container">
<div className='row'>
<FileHeader/>
{this.state.films.map(film=>(
<div key={film.id} id='cardItem' className="col-sm-3"><MovieCard film={film}/>
</div>
))}
</div>
</div>
Moviecard component...
render() {
var film = this.props.film;
return(
<div className='card' style={{width:'18rem'}}>
<div className="card-body">
<h5 className="card-title">{film.title}</h5>
<h6 className='card-subtitle mb-2 text-muted'>{film.release_date}</h6>
<p className='card-text'>{film.description}</p>
</div>
</div>
)
}

Resources