feat: implement product carousel component with thumbnail gallery and navigation controls
This commit is contained in:
@@ -1,13 +1,10 @@
|
||||
<div class="product-carousel d-flex flex-column gap-3">
|
||||
<!-- Active/Main Image Area -->
|
||||
<div class="product-carousel__main position-relative bg-light rounded overflow-hidden">
|
||||
<div class="product-carousel__main position-relative bg-light overflow-hidden">
|
||||
<!-- Main Image -->
|
||||
@if (images().length > 0) {
|
||||
<img
|
||||
[src]="images()[activeIndex()]"
|
||||
alt="Product active image"
|
||||
class="product-carousel__main-image w-100 h-100 object-fit-cover"
|
||||
/>
|
||||
<img [src]="images()[activeIndex()]" alt="Product active image"
|
||||
class="product-carousel__main-image w-100 h-100 object-fit-cover" />
|
||||
} @else {
|
||||
<!-- Placeholder -->
|
||||
<div class="product-carousel__placeholder w-100 h-100 d-flex align-items-center justify-content-center text-muted">
|
||||
@@ -17,28 +14,23 @@
|
||||
|
||||
<!-- Discount Badge -->
|
||||
@if (discount() && discount()! > 0) {
|
||||
<span class="product-carousel__discount-badge position-absolute top-0 end-0 bg-primary text-white px-3 py-2 fw-semibold">
|
||||
<span
|
||||
class="product-carousel__discount-badge position-absolute top-0 end-0 bg-primary text-white px-3 py-2 fw-semibold">
|
||||
-{{ discount() }}%
|
||||
</span>
|
||||
}
|
||||
|
||||
<!-- Navigation Arrows -->
|
||||
@if (images().length > 1) {
|
||||
<button
|
||||
type="button"
|
||||
<button type="button"
|
||||
class="product-carousel__nav-btn product-carousel__nav-btn--prev position-absolute top-50 translate-middle-y border-0 p-0 d-flex align-items-center justify-content-center"
|
||||
(click)="prevImage()"
|
||||
aria-label="Previous image"
|
||||
>
|
||||
(click)="prevImage()" aria-label="Previous image">
|
||||
<i class="fa-solid fa-chevron-left"></i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
<button type="button"
|
||||
class="product-carousel__nav-btn product-carousel__nav-btn--next position-absolute top-50 translate-middle-y border-0 p-0 d-flex align-items-center justify-content-center"
|
||||
(click)="nextImage()"
|
||||
aria-label="Next image"
|
||||
>
|
||||
(click)="nextImage()" aria-label="Next image">
|
||||
<i class="fa-solid fa-chevron-right"></i>
|
||||
</button>
|
||||
}
|
||||
@@ -48,13 +40,9 @@
|
||||
@if (images().length > 1) {
|
||||
<div class="product-carousel__thumbnails d-flex gap-3">
|
||||
@for (image of images(); track image; let idx = $index) {
|
||||
<button
|
||||
type="button"
|
||||
class="product-carousel__thumbnail border-0 p-0 rounded overflow-hidden bg-light"
|
||||
[class.product-carousel__thumbnail--active]="idx === activeIndex()"
|
||||
(click)="selectImage(idx)"
|
||||
[attr.aria-label]="'Select image ' + (idx + 1)"
|
||||
>
|
||||
<button type="button" class="product-carousel__thumbnail border-0 p-0 overflow-hidden bg-light"
|
||||
[class.product-carousel__thumbnail--active]="idx === activeIndex()" (click)="selectImage(idx)"
|
||||
[attr.aria-label]="'Select image ' + (idx + 1)">
|
||||
<img [src]="image" alt="Product thumbnail" class="w-100 h-100 object-fit-cover" />
|
||||
</button>
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
width: 100%;
|
||||
|
||||
&__main {
|
||||
aspect-ratio: 1 / 1;
|
||||
aspect-ratio: 463 / 489;
|
||||
width: 100%;
|
||||
background-color: #e0e0e0 !important; /* Matches grey placeholder in mock */
|
||||
border-radius: 8px;
|
||||
background-color: #e0e0e0 !important;
|
||||
/* Matches grey placeholder in mock */
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -63,8 +64,8 @@
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
aspect-ratio: 1 / 1;
|
||||
background-color: #e0e0e0 !important; /* Matches mock layout */
|
||||
border-radius: 4px;
|
||||
background-color: #e0e0e0 !important;
|
||||
/* Matches mock layout */
|
||||
padding: 0;
|
||||
transition: opacity 0.2s ease, border-color 0.2s ease;
|
||||
border: 3px solid transparent !important;
|
||||
|
||||
Reference in New Issue
Block a user