File

projects/storefrontlib/cms-components/product/product-images/product-images.component.ts

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector cx-product-images
templateUrl ./product-images.component.html

Index

Properties
Methods

Constructor

constructor(currentProductService: CurrentProductService)
Parameters :
Name Type Optional
currentProductService CurrentProductService No

Methods

Private createThumbs
createThumbs(product: Product)

Return an array of CarouselItems for the product thumbnails. In case there are less then 2 thumbs, we return null.

Parameters :
Name Type Optional
product Product No
Returns : Observable[]
getActive
getActive(thumbs: any[])

find the index of the main media in the list of media

Parameters :
Name Type Optional
thumbs any[] No
Returns : Observable<number>
isActive
isActive(thumbnail: ImageGroup)
Parameters :
Name Type Optional
thumbnail ImageGroup No
Returns : Observable<boolean>
openImage
openImage(item: any)
Parameters :
Name Type Optional
item any No
Returns : void

Properties

mainImage$
Default value : combineLatest([this.product$, this.mainMediaContainer]).pipe( map(([, container]) => container) )
Protected mainMediaContainer
Default value : new BehaviorSubject<any>(null)
Protected product$
Type : Observable<Product>
Default value : this.currentProductService .getProduct() .pipe( filter(isNotNullable), distinctUntilChanged(), tap((p: Product) => { this.mainMediaContainer.next(p.images?.PRIMARY ? p.images.PRIMARY : {}); }) )
thumbs$
Type : Observable<any[]>
Default value : this.product$.pipe( map((p: Product) => this.createThumbs(p)) )
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ImageGroup, isNotNullable, Product } from '@spartacus/core';
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
import { distinctUntilChanged, filter, map, tap } from 'rxjs/operators';
import { CurrentProductService } from '../current-product.service';

@Component({
  selector: 'cx-product-images',
  templateUrl: './product-images.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProductImagesComponent {
  protected mainMediaContainer = new BehaviorSubject<any>(null);

  protected product$: Observable<Product> = this.currentProductService
    .getProduct()
    .pipe(
      filter(isNotNullable),
      distinctUntilChanged(),
      tap((p: Product) => {
        this.mainMediaContainer.next(p.images?.PRIMARY ? p.images.PRIMARY : {});
      })
    );

  thumbs$: Observable<any[]> = this.product$.pipe(
    map((p: Product) => this.createThumbs(p))
  );

  mainImage$ = combineLatest([this.product$, this.mainMediaContainer]).pipe(
    map(([, container]) => container)
  );

  constructor(protected currentProductService: CurrentProductService) {}

  openImage(item: any): void {
    this.mainMediaContainer.next(item);
  }

  isActive(thumbnail: ImageGroup): Observable<boolean> {
    return this.mainMediaContainer.pipe(
      filter(Boolean),
      map((container: any) => {
        return (
          container.zoom &&
          container.zoom.url &&
          thumbnail.zoom &&
          thumbnail.zoom.url &&
          container.zoom.url === thumbnail.zoom.url
        );
      })
    );
  }

  /** find the index of the main media in the list of media */
  getActive(thumbs: any[]): Observable<number> {
    return this.mainMediaContainer.pipe(
      filter(Boolean),
      map((container: any) => {
        const current = thumbs.find(
          (t) =>
            t.media &&
            container.zoom &&
            t.media.container &&
            t.media.container.zoom &&
            t.media.container.zoom.url === container.zoom.url
        );
        return thumbs.indexOf(current);
      })
    );
  }

  /**
   * Return an array of CarouselItems for the product thumbnails.
   * In case there are less then 2 thumbs, we return null.
   */
  private createThumbs(product: Product): Observable<any>[] {
    if (
      !product.images ||
      !product.images.GALLERY ||
      product.images.GALLERY.length < 2
    ) {
      return [];
    }

    return (<any[]>product.images.GALLERY).map((c) => of({ container: c }));
  }
}
<ng-container *ngIf="mainImage$ | async as main">
  <cx-media [container]="main"></cx-media>
</ng-container>

<ng-container *ngIf="thumbs$ | async as thumbs">
  <cx-carousel
    *ngIf="thumbs.length"
    class="thumbs"
    [items]="thumbs"
    itemWidth="120px"
    [hideIndicators]="false"
    [template]="thumb"
  ></cx-carousel>
</ng-container>

<ng-template #thumb let-item="item">
  <cx-media
    [container]="item.container"
    tabindex="0"
    (focus)="openImage(item.container)"
    [class.is-active]="isActive(item.container) | async"
    format="product"
  >
  </cx-media>
</ng-template>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""