Featured articales section - Card component

This commit is contained in:
“Salar 2022-08-30 14:05:37 +03:00
parent a2f80ad94f
commit a080bc4361
2 changed files with 229 additions and 25 deletions

View File

@ -1,5 +1,5 @@
import React, { Children } from "react";
import classNames from "classnames"; import classNames from "classnames";
import React from "react";
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Components */ /* Components */
@ -27,7 +27,7 @@ const Card = ({ children, className }: Props) => {
<div <div
className={classNames([ className={classNames([
className, className,
"inline-flex flex-col justify-between p-4 max-w-xs lg:max-w-sm h-52 items-start rounded border border-[#F0F0F0] gap-y-8 overflow-hidden", "inline-flex flex-col justify-between p-4 items-start rounded border border-gray-75 gap-y-8 overflow-hidden",
])} ])}
> >
{children} {children}
@ -35,69 +35,71 @@ const Card = ({ children, className }: Props) => {
); );
}; };
// Avatar props and function // Avatar function
type AvatarProps = { type AvatarProps = {
children?: React.ReactNode; children?: React.ReactNode;
}; };
Card.Avatar = function CardAvatar({ children }: AvatarProps) { Card.Avatar = function CardAvatar({ children }: AvatarProps) {
return <>{children}</>; return <div>{children}</div>;
}; };
// The end of Body props and function
// Title props and function // Title function
Card.Title = function CardTitle({ children, className }: Props) { Card.Title = function CardTitle({ children, className }: Props) {
return ( return (
<Heading className={classNames([className, "select-none leading-7"])}> <Heading className={classNames([className, "select-none "])}>
{children} {children}
</Heading> </Heading>
); );
}; };
// The end Title props and function
// Body props and function // SubTitle function
Card.SubTitle = function CardSubTitle({ children, className }: Props) {
return (
<Typography className={classNames([className, ""])}>{children}</Typography>
);
};
// Body function
Card.Body = function CardTitle({ children, className }: Props) { Card.Body = function CardTitle({ children, className }: Props) {
return ( return (
<Typography <Typography //
fontWeightVariant="normal" fontWeightVariant="normal"
className={classNames([className, "text-sm"])} className={classNames([className, "text-sm h-14 overflow-hidden "])}
> >
{children} {children}
</Typography> </Typography>
); );
}; };
// The end of Body props and function
// Cardheader props and function // Cardheader function
Card.Cardheader = function CardCardheader({ children, className }: Props) { Card.CardHeader = function CardCardHeader({ children, className }: Props) {
return ( return (
<div className={classNames([className, "first flex items-start gap-4"])}> <div className={classNames([className, "flex items-start gap-4"])}>
{children} {children}
</div> </div>
); );
}; };
// The end of Cardheader props and function
// Cardcontent props and function // Cardcontent function
Card.Cardcontent = function CardCardcontent({ children, className }: Props) { Card.CardContent = function CardCardContent({ children, className }: Props) {
return ( return (
<div className={classNames([className, "flex flex-col gap-y-4 "])}> <div className={classNames([className, "flex flex-col gap-y-4 "])}>
{children} {children}
</div> </div>
); );
}; };
// The end of Cardcontent props and function
// Cardaction props and function // Cardaction function
type CardactionProps = { type CardActionProps = {
children: React.ReactNode; children: React.ReactNode;
className?: string | undefined; className?: string | undefined;
href?: string; href?: string;
}; };
Card.Cardaction = function CardCardaction({ Card.CardAction = function CardCardAction({
children, children,
className, className,
href = "#", href = "#",
}: CardactionProps) { }: CardActionProps) {
return ( return (
<Link <Link
href={href} href={href}
@ -107,6 +109,20 @@ Card.Cardaction = function CardCardaction({
</Link> </Link>
); );
}; };
// The end of Cardaction props and function
// CardMedia function
type CardMediaProps = {
children?: React.ReactNode;
className?: string | undefined;
src?: string;
};
Card.CardMedia = function CardCardMedia({
className,
src = "#",
}: CardMediaProps) {
return (
<img src={src} className={classNames([className, "w-full h-32 rounded"])} />
);
};
export default Card; export default Card;

View File

@ -0,0 +1,188 @@
import { useRef } from "react";
/* -------------------------------------------------------------------------- */
/* Skeleton */
/* -------------------------------------------------------------------------- */
import "react-loading-skeleton/dist/skeleton.css";
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
import Typography from "./typography/Typography";
import SkeletonCard from "./SkeletonCard";
import AspectRatio from "./AspectRatio";
import Card from "./Card";
import Link from "./Link";
/* -------------------------------------------------------------------------- */
/* Data */
/* -------------------------------------------------------------------------- */
import Articales from "./Articales.json";
/* -------------------------------------------------------------------------- */
/* Icons */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGArrowRight } from "assets/svg/arrow-right.svg";
import { ReactComponent as SVGCaretRight } from "assets/svg/caret-right.svg";
import { ReactComponent as SVGArrowLeft } from "assets/svg/arrow-left.svg";
/* -------------------------------------------------------------------------- */
/* Swiper */
/* -------------------------------------------------------------------------- */
import { Swiper, SwiperSlide } from "swiper/react";
import SwiperCore, { Navigation } from "swiper";
import { Pagination } from "swiper";
import "swiper/css/pagination";
import "swiper/css/navigation";
import "./styles.css";
import "swiper/css";
/* -------------------------------------------------------------------------- */
/* How many Skeleton cards should be added to the design */
/* -------------------------------------------------------------------------- */
let twoCards: boolean = false;
let threeCards: boolean = false;
console.log(`Number of cards ${Articales.length}`);
if (Articales.length == 2) {
twoCards = true;
} else if (Articales.length == 3) {
threeCards = true;
}
SwiperCore.use([Navigation]);
const FeaturedArticales = () => {
const navigationPrevRef = useRef(null);
const navigationNextRef = useRef(null);
const paginationRef = useRef(null);
return (
<div className="slider-wrapper Articales">
<div className="flex justify-end gap-2 my-2">
<div
className="prev inline-flex justify-center items-center
w-9 h-9 bg-blue-600 rounded cursor-pointer
opacity-0 md:opacity-100"
ref={navigationPrevRef}
>
<SVGArrowLeft className="w-6 h-6 fill-white "></SVGArrowLeft>
</div>
<div
className="next inline-flex justify-center items-center
w-9 h-9 bg-blue-600 rounded cursor-pointer
opacity-0 md:opacity-100"
ref={navigationNextRef}
>
<SVGArrowRight className="w-6 h-6 fill-white "></SVGArrowRight>
</div>
</div>
<Swiper
slidesPerView={1.25}
slidesPerGroup={1}
loop={Articales.length > 4 ? true : false}
pagination={{ el: ".pagination", clickable: true }}
navigation={{
prevEl: ".prev",
nextEl: ".next",
}}
breakpoints={{
768: {
slidesPerView: 2,
slidesPerGroup: 2,
},
1024: {
slidesPerView: 2,
slidesPerGroup: 2,
},
1280: {
slidesPerView: 4,
slidesPerGroup: 4,
},
1580: {
slidesPerView: 4,
slidesPerGroup: 4,
},
}}
spaceBetween={25}
loopFillGroupWithBlank={true}
modules={[Pagination, Navigation]}
>
{Articales.map((Articale) => (
<SwiperSlide>
<Card className="flex-1">
<Card.CardContent>
<AspectRatio>
<AspectRatio.Content>
<img src={Articale.CoverImg} />
</AspectRatio.Content>
</AspectRatio>
<Card.Body className="h-14 overflow-hidden">
{Articale.Body}
</Card.Body>
</Card.CardContent>
<Card.CardAction href={Articale.Link}>
<Link>
<Typography className="text-blue-500 font-bold">
Read More
</Typography>
</Link>
<SVGCaretRight className="fill-blue-500 w-4 h-4" />
</Card.CardAction>
</Card>
</SwiperSlide>
))}
{twoCards && [
<SwiperSlide className="hidden xl:block">
<SwiperSlide>
<SkeletonCard className="flex-1">
<SkeletonCard.Content>
<SkeletonCard.Media />
<SkeletonCard.Body />
</SkeletonCard.Content>
<SkeletonCard.Action />
</SkeletonCard>
</SwiperSlide>
</SwiperSlide>,
<SwiperSlide className="hidden xl:block">
<SwiperSlide>
<SkeletonCard className="flex-1">
<SkeletonCard.Content>
<SkeletonCard.Media />
<SkeletonCard.Body />
</SkeletonCard.Content>
<SkeletonCard.Action />
</SkeletonCard>
</SwiperSlide>
</SwiperSlide>,
]}
{threeCards && [
<SwiperSlide className="hidden xl:block">
<SwiperSlide>
<SkeletonCard className="flex-1">
<SkeletonCard.Content>
<SkeletonCard.Media />
<SkeletonCard.Body />
</SkeletonCard.Content>
<SkeletonCard.Action />
</SkeletonCard>
</SwiperSlide>
</SwiperSlide>,
]}
</Swiper>
<div
className="pagination my-6 w-full h-2 flex justify-center items-center
opacity-0 md:opacity-100"
ref={paginationRef}
/>
</div>
);
};
export default FeaturedArticales;