E-commerce Product Details Page Component
A comprehensive product details component for an e-commerce site. It features a responsive two-column layout with an image gallery on the left and product information on the right. Key functionalities include thumbnail image selection, color and storage variant options, quantity controls, and add-to-cart functionality.
LTR
RTL
<div
x-data="{
selectedImage: 'https://images.unsplash.com/photo-1592899677977-9c10ca588bbd?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
images: [
'https://images.unsplash.com/photo-1592899677977-9c10ca588bbd?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
'https://images.unsplash.com/photo-1589492477829-5e65395b66cc?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
'https://images.unsplash.com/photo-1565849904461-04a58ad377e0?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80',
'https://images.unsplash.com/photo-1605236453806-6ff36851218e?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80'
],
rating: 4.7,
colors: [
{ id: 1, name: 'Space Gray', value: '#4B5563' },
{ id: 2, name: 'Silver', value: '#E5E7EB' },
{ id: 3, name: 'Gold', value: '#FCD34D' },
{ id: 4, name: 'Blue', value: '#3B82F6' }
],
selectedColor: 1,
storageOptions: ['128GB', '256GB', '512GB'],
selectedStorage: '128GB',
quantity: 1,
activeTab: 'description',
addToCart() {
alert(`Added to cart: Smartphone X (${this.selectedStorage}) - Quantity: ${this.quantity}`);
}
}"
x-cloak
class="max-w-6xl mx-auto"
>
<!-- Breadcrumb -->
<nav class="mb-6 text-sm">
<ol class="flex items-center space-x-2 rtl:space-x-reverse">
<li><a href="#" class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300">Home</a></li>
<li class="flex items-center">
<span class="mx-2 text-gray-400 dark:text-gray-500">/</span>
<a href="#" class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300">Electronics</a>
</li>
<li class="flex items-center">
<span class="mx-2 text-gray-400 dark:text-gray-500">/</span>
<a href="#" class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300">Phones</a>
</li>
<li class="flex items-center">
<span class="mx-2 text-gray-400 dark:text-gray-500">/</span>
<span class="text-gray-700 dark:text-gray-300">Smartphone X</span>
</li>
</ol>
</nav>
<div class="equal-height-row grid grid-cols-1 md:grid-cols-2 md:gap-8">
<!-- Product Images -->
<div class="equal-height-col mb-6 md:mb-0">
<div class="equal-height-content bg-white dark:bg-gray-800 rounded-lg shadow-md p-4">
<div class="main-image-container mb-4">
<img
:src="selectedImage"
alt="Product Image"
class="max-h-[500px] w-full object-cover rounded-lg"
>
</div>
<div class="grid grid-cols-4 gap-2 w-full mt-auto">
<template x-for="(image, index) in images" :key="index">
<button
@click="selectedImage = image"
:class="selectedImage === image ? 'ring-2 ring-blue-500' : 'ring-1 ring-gray-300 dark:ring-gray-600'"
class="w-full h-20 rounded-md overflow-hidden focus:outline-none"
>
<img :src="image" :alt="'Thumbnail ' + (index + 1)" class="w-full h-full object-cover">
</button>
</template>
</div>
</div>
</div>
<!-- Product Info -->
<div class="equal-height-col">
<div class="equal-height-content bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
<h1 class="text-2xl font-bold mb-2 rtl:text-right">Smartphone X - 128GB</h1>
<div class="flex items-center mb-4">
<div class="flex text-yellow-400">
<template x-for="i in 5" :key="i">
<svg x-show="i <= rating" class="w-5 h-5 fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
</svg>
<svg x-show="i > rating" class="w-5 h-5 fill-current text-gray-300 dark:text-gray-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
</svg>
</template>
</div>
<span class="ml-2 rtl:mr-2 text-sm text-gray-600 dark:text-gray-400">(142 reviews)</span>
</div>
<div class="mb-6">
<span class="text-3xl font-bold text-gray-900 dark:text-white">$599.99</span>
<span class="ml-2 rtl:mr-2 text-lg text-gray-500 dark:text-gray-400 line-through">$699.99</span>
<span class="ml-2 rtl:mr-2 text-sm bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200 px-2 py-1 rounded">Save $100</span>
</div>
<div class="mb-6">
<h3 class="font-medium mb-2 rtl:text-right">Color</h3>
<div class="flex space-x-2 rtl:space-x-reverse">
<template x-for="color in colors" :key="color.id">
<button
@click="selectedColor = color.id"
:class="selectedColor === color.id
? 'ring-2 ring-blue-500'
: 'ring-1 ring-gray-300 dark:ring-gray-600'"
class="w-10 h-10 rounded-full focus:outline-none flex items-center justify-center"
:style="`background-color: ${color.value}`"
:title="color.name"
></button>
</template>
</div>
</div>
<div class="mb-6">
<h3 class="font-medium mb-2 rtl:text-right">Storage</h3>
<div class="flex flex-wrap gap-2">
<template x-for="storage in storageOptions" :key="storage">
<button
@click="selectedStorage = storage"
:class="selectedStorage === storage
? 'bg-blue-500 text-white'
: 'bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200'"
class="px-4 py-2 rounded-md focus:outline-none transition-colors"
>
<span x-text="storage"></span>
</button>
</template>
</div>
</div>
<div class="flex items-center mb-6">
<span class="mr-4 rtl:ml-4 font-medium rtl:text-right">Quantity:</span>
<div class="flex items-center border border-gray-300 dark:border-gray-600 rounded-md">
<button
@click="if(quantity > 1) quantity--"
class="px-3 py-1 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 focus:outline-none"
>
-
</button>
<span class="px-4 py-1" x-text="quantity"></span>
<button
@click="quantity++"
class="px-3 py-1 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 focus:outline-none"
>
+
</button>
</div>
</div>
<div class="flex flex-col sm:flex-row gap-3 mb-6">
<button
@click="addToCart()"
class="flex-1 bg-blue-500 hover:bg-blue-600 text-white py-3 px-6 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900"
>
Add to Cart
</button>
<button
class="flex-1 bg-gray-800 dark:bg-gray-700 hover:bg-gray-900 dark:hover:bg-gray-600 text-white py-3 px-6 rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900"
>
Buy Now
</button>
</div>
<div class="text-sm text-gray-600 dark:text-gray-400 rtl:text-right mt-auto">
<p class="mb-1">✓ Free shipping on orders over $50</p>
<p class="mb-1">✓ 30-day money-back guarantee</p>
<p>✓ 2-year warranty included</p>
</div>
</div>
</div>
</div>
</div>