Shared/ProductBundleBadge
Bundle
Not Bundle
product-bundle-badge.tsx
/**
* BUNDLE badge overlay for product listing images.
*
* Renders a diagonal ribbon at TOP-RIGHT of the thumbnail for the 5 ADDAC120
* system bundles. Positioned at TOP-RIGHT to avoid clashing with the
* `ProductStatusBadge` incoming-status ribbon which occupies TOP-LEFT.
*
* Gate: render only when `isBundle` is true (`bundle != null` on the product).
* Never gates on `brandBasedCategory` — that would incorrectly include the
* 7 ADDAC120 modules and the frame.
*/
interface ProductBundleBadgeProps {
isBundle: boolean;
}
export function ProductBundleBadge({ isBundle }: ProductBundleBadgeProps) {
if (!isBundle) return null;
return (
<div className="absolute top-0 left-0 w-full h-full overflow-hidden pointer-events-none">
<div className="absolute top-[12px] right-[-35px] sm:top-[18px] sm:right-[-40px] md:top-[22px] md:right-[-45px] w-[140px] sm:w-[160px] md:w-[180px] bg-zd-warning text-zd-black text-center py-[3px] md:py-[4px] text-[10px] sm:text-[11px] md:text-xs leading-normal font-bold font-futura transform rotate-45">
BUNDLE
</div>
</div>
);
}
product-bundle-badge.stories.tsx
import { ProductBundleBadge } from './product-bundle-badge';
/**
* ProductBundleBadge Component
*
* BUNDLE marker overlay for product listing images. Renders a flat orange
* diagonal corner-ribbon at TOP-RIGHT for the 5 ADDAC120 system bundles
* (master-data `bundle != null`). Positioned at TOP-RIGHT to avoid clashing
* with the `ProductStatusBadge` incoming-status ribbon at TOP-LEFT.
*/
export const meta = {
title: 'Shared/ProductBundleBadge',
};
const ImageBox = ({ children }: { children: preact.ComponentChildren }) => (
<div className="relative w-[200px] h-[200px] border border-zd-white bg-zd-gray/20 overflow-hidden">
<img
src="https://placehold.co/200x200/333/ccc?text=Product"
alt="placeholder"
className="w-full h-full object-cover"
/>
{children}
</div>
);
/**
* Bundle product — flat orange BUNDLE ribbon at top-right
*/
export const Bundle = () => (
<ImageBox>
<ProductBundleBadge isBundle={true} />
</ImageBox>
);
/**
* Non-bundle product — renders nothing
*/
export const NotBundle = () => (
<ImageBox>
<ProductBundleBadge isBundle={false} />
</ImageBox>
);