Skip to content
Snippets Groups Projects
Card.tsx 5.26 KiB
Newer Older
Toavina's avatar
Toavina committed
import React from "react"
import Image, { Iimage } from "./Image"
import { Link } from "@onegeo-suite/gatsby-theme-onegeo"
import { twMerge } from "tailwind-merge"
tovo's avatar
tovo committed

export interface ICard extends Iimage {
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
    children?: React.ReactNode
    name?: string
    description?: string
    url?: string
Toavina's avatar
Toavina committed
    anime?: boolean
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
    layout?: "top" | "left" | "full"
Julien MARGAIL's avatar
Julien MARGAIL committed
    size?: "xs" | "base" | "xl" | "full"
Julien MARGAIL's avatar
Julien MARGAIL committed
    options?: object
Julien MARGAIL's avatar
Julien MARGAIL committed
const layoutClass = {
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
    full_base: {
        main: "image-full ",
        title: "",
        description: "",
        image: "h-52",
    },
    top_base: {
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
        main: "",
        title: "",
        description: "h-24",
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
        image: "h-52",
Toavina's avatar
Toavina committed
    },
Tovo Ramontalambo's avatar
Tovo Ramontalambo committed
    top_xs: {
        main: "",
        title: "",
        description: "h-12",
        image: "h-28",
    },
    top_xl: {
        main: "",
        title: "",
        description: "h-32",
        image: "h-72",
    },
Julien MARGAIL's avatar
Julien MARGAIL committed
    top_full: {
        main: "rounded-none h-full w-full",
        title: "",
        description: "h-32",
        image: "h-72",
    },
    left_bcase: {
        main: "card-side h-52 w-full ",
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
        title: "",
        description: "",
Toavina's avatar
Toavina committed
        image: "min-w-[320px] max-w-[320px]",
    },
    left_xs: {
        main: "card-side h-28 w-full ",
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
        title: "",
        description: "line-clamp-2",
        image: "min-w-[80px] max-w-[100px]",
    },
Tovo Ramontalambo's avatar
Tovo Ramontalambo committed
    left_xl: {
metourneau's avatar
metourneau committed
        main: "card-side h-72 w-full lg:hover:scale-105 lg:hover:-translate-y-0",
Tovo Ramontalambo's avatar
Tovo Ramontalambo committed
        title: "",
        description: "line-clamp-2",
        image: "min-w-[450px] max-w-[450px]",
    },
tovo's avatar
tovo committed
}

const CardContent = (props: ICard) => {
Toavina's avatar
Toavina committed
    const {
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
        children,
        layout = "top",
        name,
        description,
        image,
        size = "base",
Toavina's avatar
Toavina committed
    } = props
Julien MARGAIL's avatar
Julien MARGAIL committed
    const options = props.options ?? {}
    const lClass = layoutClass[layout + "_" + size] || layoutClass["top_base"]

    // Options from Directus (config user)
Julien MARGAIL's avatar
Julien MARGAIL committed
    /*
    options : {
Julien MARGAIL's avatar
Julien MARGAIL committed
        class: {
            main:
            image
            imageComponent
            body
            title
            description
        }
    }
    */
    const oClass = options.class || {}
    const inlineSVG = options.inlineSVG
Toavina's avatar
Toavina committed
    return (
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
            {image ? (
metourneau's avatar
metourneau committed
                // <figure>
Julien MARGAIL's avatar
Julien MARGAIL committed
                //     <svg class='' ... />
                // </figure>
                // OR
                // <figure>
                //     <img src={image.publicURL} />
metourneau's avatar
metourneau committed
                // </figure>
Julien MARGAIL's avatar
Julien MARGAIL committed
                <figure>
Julien MARGAIL's avatar
Julien MARGAIL committed
                    {options.inlineSVG ? (
                        <div
                            className={twMerge(lClass.image, oClass.image)}
                            dangerouslySetInnerHTML={{
                                __html: options.inlineSVG,
                            }}
Julien MARGAIL's avatar
Julien MARGAIL committed
                        />
Julien MARGAIL's avatar
Julien MARGAIL committed
                    ) : (
                        <div className={twMerge(lClass.image, oClass.image)}>
                            <Image
                                image={image}
                                className={twMerge(
                                    "h-full w-full object-cover",
                                    oClass.imageComponent
                                )}
                            />
                        </div>
                    )}
metourneau's avatar
metourneau committed
                </figure>
Toavina's avatar
Toavina committed
            ) : null}
            <div className={twMerge("card-body", oClass.body)}>
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
                {name ? (
Julien MARGAIL's avatar
Julien MARGAIL committed
                    <h2
                        className={twMerge(
Julien MARGAIL's avatar
Julien MARGAIL committed
                            "card-title uppercase",
Julien MARGAIL's avatar
Julien MARGAIL committed
                            lClass.title,
                            oClass.title
Julien MARGAIL's avatar
Julien MARGAIL committed
                        )}
                    >
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
                        {name}
                    </h2>
                ) : null}
                {description ? (
                    <div
                        className={twMerge(
Julien MARGAIL's avatar
Julien MARGAIL committed
                            "overflow-hidden text-ellipsis text-justify ",
                            lClass.description,
                            oClass.description
                        )}
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
                        dangerouslySetInnerHTML={{ __html: description }}
                    />
                ) : null}
                {children}
            </div>
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
    )
}

const Card = (props: ICard) => {
    const {
        className = "",
        anime = true,
        layout = "top",
        size = "base",
        url,
Julien MARGAIL's avatar
Julien MARGAIL committed
        options = {},
    } = props

    const transition = anime
        ? "lg:transition duration-200 ease-in-out lg:hover:-translate-y-2 lg:hover:shadow-xl "
        : ""

    const lClass = layoutClass[layout + "_" + size] || layoutClass["top_base"]

Julien MARGAIL's avatar
Julien MARGAIL committed
    const oClass = options.class || {}
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed

    return url ? (
metourneau's avatar
metourneau committed
            className={twMerge(
metourneau's avatar
metourneau committed
                "card card-compact  bg-base-100 text-base-content shadow-lg",
Julien MARGAIL's avatar
Julien MARGAIL committed
                transition,
metourneau's avatar
metourneau committed
                lClass.main,
Julien MARGAIL's avatar
Julien MARGAIL committed
                className,
Julien MARGAIL's avatar
Julien MARGAIL committed
                oClass.main
Julien MARGAIL's avatar
Julien MARGAIL committed
            )}
        >
            <CardContent {...props} />
Toavina's avatar
Toavina committed
        </Link>
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
    ) : (
metourneau's avatar
metourneau committed
            className={twMerge(
Julien MARGAIL's avatar
Julien MARGAIL committed
                "card card-compact bg-base-100 text-base-content shadow-lg",
                transition,
metourneau's avatar
metourneau committed
                lClass.main,
Julien MARGAIL's avatar
Julien MARGAIL committed
                className,
Julien MARGAIL's avatar
Julien MARGAIL committed
                oClass.main
Julien MARGAIL's avatar
Julien MARGAIL committed
            )}
        >
            <CardContent {...props} />
        </div>
Toavina's avatar
Toavina committed
export default Card