@brutalcomponent/react
Version:
Brutalist React components
114 lines (112 loc) • 4.2 kB
JavaScript
import { Button } from '../../chunk-E2BWEC67.mjs';
import { Icon } from '../../chunk-QB4EPFXT.mjs';
import '../../chunk-KMHX64YN.mjs';
import '../../chunk-7QJK2SK5.mjs';
import React from 'react';
import { clsx } from 'clsx';
import { FaHeart, FaShoppingCart } from 'react-icons/fa';
/**
* @brutalcomponent/react
* (c) David Heffler (https://dvh.sh)
* Licensed under MIT
*/
var ProductCard = ({
id,
name,
price,
originalPrice,
image,
imageAlt,
badge,
onAddToCart,
onToggleFavorite,
isFavorite = false,
href,
className
}) => {
const discount = originalPrice ? Math.round((1 - price / originalPrice) * 100) : 0;
return /* @__PURE__ */ React.createElement(
"div",
{
className: clsx(
"group relative bg-brutal-white border-4 border-brutal-black shadow-brutal",
"hover:shadow-brutal-md hover:-translate-y-0.5 transition-all duration-300",
className
)
},
badge && /* @__PURE__ */ React.createElement("div", { className: "absolute top-2 left-2 z-10 px-2 py-1 bg-brutal-pink border-2 border-brutal-black" }, /* @__PURE__ */ React.createElement("span", { className: "text-xs font-black uppercase" }, badge)),
onToggleFavorite && /* @__PURE__ */ React.createElement(
"button",
{
onClick: () => onToggleFavorite(id),
className: clsx(
"absolute top-2 right-2 z-10 p-2",
"bg-brutal-white border-2 border-brutal-black",
"hover:bg-brutal-pink transition-colors",
isFavorite && "bg-brutal-pink"
),
"aria-label": isFavorite ? "Remove from favorites" : "Add to favorites"
},
/* @__PURE__ */ React.createElement(
Icon,
{
icon: FaHeart,
size: "sm",
className: isFavorite ? "text-brutal-white" : "text-brutal-black"
}
)
),
/* @__PURE__ */ React.createElement("div", { className: "relative aspect-square overflow-hidden bg-brutal-gray-100" }, href ? /* @__PURE__ */ React.createElement("a", { href }, /* @__PURE__ */ React.createElement(
"img",
{
src: image,
alt: imageAlt || name,
className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
}
)) : /* @__PURE__ */ React.createElement(
"img",
{
src: image,
alt: imageAlt || name,
className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
}
)),
/* @__PURE__ */ React.createElement("div", { className: "p-4 border-t-4 border-brutal-black" }, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-black uppercase tracking-wider mb-2 line-clamp-2" }, href ? /* @__PURE__ */ React.createElement("a", { href, className: "hover:text-brutal-pink transition-colors" }, name) : name), /* @__PURE__ */ React.createElement("div", { className: "flex items-baseline gap-2 mb-4" }, /* @__PURE__ */ React.createElement("span", { className: "text-2xl font-black" }, "$", price), originalPrice && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "text-lg line-through text-brutal-gray-500" }, "$", originalPrice), /* @__PURE__ */ React.createElement("span", { className: "text-sm font-black text-brutal-coral uppercase" }, "-", discount, "%"))), onAddToCart && /* @__PURE__ */ React.createElement(
Button,
{
onClick: () => onAddToCart(id),
variant: "primary",
brutal: true,
size: "sm",
className: "w-full",
leftIcon: () => /* @__PURE__ */ React.createElement(FaShoppingCart, null)
},
"Add to Cart"
))
);
};
/**
* @file src/modules/commerce/ProductCard/ProductCard.tsx
* @author David (https://dvh.sh)
* @license MIT
*
* @created Thu Sep 11 2025
* @updated Fri Sep 12 2025
*
* @description
* E-commerce product display card
*/
/**
* @file src/modules/commerce/index.ts
* @author David (https://dvh.sh)
* @license MIT
*
* @created Thu Sep 11 2025
* @updated Fri Sep 12 2025
*
* @description
*
*/
export { ProductCard };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map