<div class="flex flex-col space-y-4 ">
<a href="#" class="block relative aspect-square overflow-hidden bg-gray-100 rounded-lg group hover:after:!h-0 noAbsolute">
<div class="relative w-full h-full">
<img src="/img/hero/videoLeft.jpg" alt="Product Name" class="w-full h-full object-cover transition-all duration-300 absolute inset-0 group-hover:opacity-0 ">
<img src="/img/hero/videoRight.jpg" alt="Product Name - Vue alternative" class="w-full h-full object-cover transition-all duration-300 absolute inset-0 opacity-0 group-hover:opacity-100">
</div>
<div class="absolute bottom-4 right-1/2 flex space-x-4 translate-x-2/4 duration-300 z-20">
<button type="button" class="group-hover:!btn-dark-ghost btn btn-light-ghost btn-size-sm btn-only-icon">
<svg class=" shrink-0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 4.25C3.87665 4.25 1.75 6.37665 1.75 9V15C1.75 17.6234 3.87665 19.75 6.5 19.75H12.5C14.7589 19.75 16.6495 18.1732 17.1312 16.0603L19.8501 17.1478C20.9996 17.6076 22.25 16.7611 22.25 15.523V12V8.47706C22.25 7.239 20.9996 6.39242 19.8501 6.85223L17.1312 7.93976C16.6495 5.82679 14.7589 4.25 12.5 4.25H6.5ZM17.25 9.5078L20.4072 8.24494C20.5714 8.17925 20.75 8.30019 20.75 8.47706V12V15.523C20.75 15.6999 20.5714 15.8208 20.4072 15.7551L17.25 14.4923V9.5078ZM15.75 9.33854V14.6615V15C15.75 16.7949 14.2949 18.25 12.5 18.25H6.5C4.70507 18.25 3.25 16.7949 3.25 15V9C3.25 7.20507 4.70507 5.75 6.5 5.75H12.5C14.2949 5.75 15.75 7.20507 15.75 9V9.33854Z" fill="currentColor" />
</svg>
</button>
</div>
</a>
<div class="px-2">
<p class="text-xxs font-semibold text-neutral-500">Brand Name</p>
<h3 class="font-semibold text-neutral-800 pt-0.5">Product Name</h3>
<p class="text-xs text-neutral-500 pt-1">Product description goes here with some details about the item.</p>
<div class="pt-3">
<p class="text-[9px] text-neutral-500">Prix web</p>
<div class="flex items-center gap-2">
<p class="font-semibold text-neutral-800">
99.99 €
</p>
</div>
</div>
</div>
</div>
{# components/slide/slideCard.twig #}
<div
class="flex flex-col space-y-4 {{ class }}"
>
<a
href="{{ slide.url }}"
class="block relative aspect-square overflow-hidden bg-gray-100 rounded-lg group hover:after:!h-0 noAbsolute"
{% if slide.openInNewTab %}target="_blank"{% endif %}
>
<div class="relative w-full h-full">
<img
src="{{ slide.image }}"
alt="{{ slide.name }}"
class="w-full h-full object-cover transition-all duration-300 absolute inset-0 {% if slide.hoverImage is defined and slide.hoverImage %} group-hover:opacity-0 {% endif %}"
>
{% if slide.hoverImage is defined and slide.hoverImage %}
<img
src="{{ slide.hoverImage }}"
alt="{{ slide.name }} - Vue alternative"
class="w-full h-full object-cover transition-all duration-300 absolute inset-0 opacity-0 group-hover:opacity-100"
>
{% endif %}
</div>
<div class="absolute bottom-4 right-1/2 flex space-x-4 translate-x-2/4 duration-300 z-20">
{% if slide.showActionButtons is not defined or slide.showActionButtons %}
{% if slide.showFavoriteButton is not defined or slide.showFavoriteButton %}
{% render "@template-button" with {
color: slide.buttonColor ~ "-ghost",
size: "sm",
type: "only-icon",
icon: {
name: "library--like-outline"
},
button_class: "group-hover:!btn-" ~ slide.buttonColorHover ~ "-ghost"
} %}
{% endif %}
{% if slide.showQuickViewButton is not defined or slide.showQuickViewButton %}
{% render "@template-button" with {
color: "light-ghost",
size: "sm",
type: "only-icon",
icon: {
name: "library--camera"
},
button_class: "group-hover:!btn-dark-ghost"
} %}
{% endif %}
{% endif %}
</div>
</a>
<div class="px-2">
{% if slide.brand is defined and slide.brand %}
<p class="text-xxs font-semibold text-neutral-500" {{ slide.alpineAttribute.slideInfo.brand }}>{{ slide.brand }}</p>
{% endif %}
{% if slide.inlinePrice is defined and slide.inlinePrice %}
<div class="flex justify-between items-end py-2">
{% if slide.name is defined and slide.name %}
<h3 class="font-semibold text-neutral-800 pt-0.5" {{ slide.alpineAttribute.slideInfo.name }}>{{ slide.name }}</h3>
{% endif %}
<div class="flex flex-col text-right">
{% if slide.webLabel is defined and slide.webLabel %}
<span class="text-[9px] text-neutral-500 leading-[0] uppercase" {{ slide.alpineAttribute.slideInfo.webLabel }}>{{ slide.webLabel }}</span>
{% endif %}
{% if slide.price is defined and slide.price %}
<span class="font-semibold text-neutral-800" {{ slide.alpineAttribute.slideInfo.price }}>
{{ slide.price }} €
</span>
{% endif %}
</div>
</div>
{% else %}
{% if slide.name is defined and slide.name %}
<h3 class="font-semibold text-neutral-800 pt-0.5" {{ slide.alpineAttribute.slideInfo.name }}>{{ slide.name }}</h3>
{% endif %}
{% endif %}
{% if slide.description is defined and slide.description %}
<p class="text-xs text-neutral-500 pt-1" {{ slide.alpineAttribute.slideInfo.description }}>{{ slide.description }}</p>
{% endif %}
{% if slide.colors is defined and slide.colors %}
<p class="text-xs text-neutral-500 pt-2" {{ slide.alpineAttribute.slideInfo.colors }}>{{ slide.colors }}</p>
{% endif %}
{% if not (slide.inlinePrice is defined and slide.inlinePrice) %}
<div class="pt-3">
<p class="text-[9px] text-neutral-500" {{ slide.alpineAttribute.slideInfo.webLabel }}>{{ slide.webLabel }}</p>
<div class="flex items-center gap-2">
<p class="font-semibold text-neutral-800" {{ slide.alpineAttribute.slideInfo.price }}>
{{ slide.price }} €
</p>
{% if slide.oldPrice and slide.discountText %}
<p class="text-neutral-500 text-xs line-through">
{{ slide.oldPrice }} €
</p>
<p class="text-green-700 text-xs">
{{ slide.discountText }}
</p>
{% endif %}
</div>
</div>
{% endif %}
{% if slide.addCart is defined and slide.addCart %}
<div class="flex justify-center">
{% render "@template-button" with {
label: "Ajouter au panier",
color: "dark-ghost",
size:"sm"
} %}
</div>
{% endif %}
</div>
</div>
{
"slide": {
"id": "123",
"url": "#",
"image": "/img/hero/videoLeft.jpg",
"hoverImage": "/img/hero/videoRight.jpg",
"brand": "Brand Name",
"name": "Product Name",
"description": "Product description goes here with some details about the item.",
"color": "3 couleurs disponibles",
"webLabel": "Prix web",
"price": "99.99",
"openInNewTab": false,
"showActionButtons": true,
"showFavoriteButton": false,
"showQuickViewButton": true,
"class": "",
"buttonColor": "light",
"buttonColorHover": "dark"
}
}
The Product Card component is used to display product information in a standardized layout. It is particularly suited for product grids, carousels, and recommendation lists.
The component displays:
meta: {
layout_wrapper_class: 'inline-grid grid-cols-1 md:grid-cols-3 xl:grid-cols-6 gap-10'
}
This configuration displays product cards in a responsive grid:
Prop | Type | Required | Default | Description |
---|---|---|---|---|
id | string | Yes | - | Unique product identifier |
url | string | Yes | ‘#’ | URL of the product page |
image | string | Yes | - | URL of the main image |
hoverImage | string | No | null | URL of the image displayed on hover |
brand | string | Yes | - | Brand name |
name | string | Yes | - | Product name |
description | string | No | - | Short product description |
color | string | No | - | Text indicating available colors |
webLabel | string | No | - | Price label (e.g., “Web Price”) |
price | string | Yes | - | Product price |
openInNewTab | boolean | No | false | Opens the link in a new tab |
showActionButtons | boolean | No | true | Enables/disables all action buttons |
showFavoriteButton | boolean | No | true | Enables/disables the favorite button |
showQuickViewButton | boolean | No | true | Enables/disables the quick view button |
class | string | No | “” | Additional CSS classes |
context: {
product: {
id: '123',
url: '#',
image: '/img/hero/videoLeft.jpg',
hoverImage: '/img/hero/videoRight.jpg',
brand: 'Brand Name',
name: 'Product Name',
description: 'Product description goes here with some details about the item.',
color: '3 colors available',
webLabel: 'Web Price',
price: '99.99',
openInNewTab: false,
showActionButtons: true,
showFavoriteButton: true,
showQuickViewButton: true,
class: ""
}
}
{% render "@product-card" with { product: product } %}
{% render "@product-card--without-buttons" with { product: product } %}
{% render "@product-card" with {
product: {
...product,
class: "my-custom-class"
}
} %}
Hover Image
hoverImage
is definedhoverImage
, a zoom effect is applied to the main imageAction Buttons
showActionButtons
is trueshowFavoriteButton
and showQuickViewButton
Navigation
openInNewTab