app/shared/slider/slider.component.ts
changeDetection | ChangeDetectionStrategy.OnPush |
selector | div[slider] |
styleUrls | ./slider.component.scss |
templateUrl | ./slider.component.html |
Properties |
|
Methods |
|
Inputs |
constructor(doc: Document, detector: ChangeDetectorRef, constants: ConstantsService)
|
||||||||||||
Defined in app/shared/slider/slider.component.ts:46
|
||||||||||||
Parameters :
|
btnClass | |
Defined in app/shared/slider/slider.component.ts:19
|
columnSize | |
Type : "xl" | "lg" | "md"
|
|
Default value : 'xl'
|
|
Defined in app/shared/slider/slider.component.ts:17
|
nrOfElements | |
Defined in app/shared/slider/slider.component.ts:16
|
removeControls | |
Defined in app/shared/slider/slider.component.ts:18
|
Private configSwiperBehavior | ||||||
configSwiperBehavior(windowWidth: number)
|
||||||
Defined in app/shared/slider/slider.component.ts:75
|
||||||
Parameters :
Returns :
void
|
Private getAvailableSlots | ||||||
getAvailableSlots(windowWidth: number)
|
||||||
Defined in app/shared/slider/slider.component.ts:80
|
||||||
Parameters :
Returns :
number
|
Private inDesktopView | ||||||
inDesktopView(width: number)
|
||||||
Defined in app/shared/slider/slider.component.ts:104
|
||||||
Parameters :
Returns :
boolean
|
ngOnDestroy |
ngOnDestroy()
|
Defined in app/shared/slider/slider.component.ts:66
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Defined in app/shared/slider/slider.component.ts:54
|
Returns :
void
|
Private onResize | ||||||
onResize(windowWidth: number)
|
||||||
Defined in app/shared/slider/slider.component.ts:70
|
||||||
Parameters :
Returns :
void
|
Public config |
Type : SwiperConfigInterface
|
Default value : {
a11y: true,
lazy: false,
direction: 'horizontal',
slidesPerView: 'auto',
keyboard: true,
mousewheel: false,
scrollbar: false,
spaceBetween: 0,
freeMode: false,
grabCursor: true,
pagination: false,
navigation: this.navigation,
centeredSlides: false,
slidesOffsetBefore: 0,
slidesOffsetAfter: 0,
loop: false
}
|
Defined in app/shared/slider/slider.component.ts:29
|
Public navigation |
Type : SwiperNavigationInterface
|
Default value : {
nextEl: '.btn-swiper-next',
prevEl: '.btn-swiper-prev'
}
|
Defined in app/shared/slider/slider.component.ts:24
|
showSwiperControls |
Type : boolean
|
Defined in app/shared/slider/slider.component.ts:22
|
subscription |
Type : Subscription
|
Defined in app/shared/slider/slider.component.ts:21
|
import { Component, OnInit, Inject, OnDestroy, ChangeDetectorRef, Input, ChangeDetectionStrategy } from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';
import { map, debounceTime } from 'rxjs/operators';
import { ConstantsService } from '../constants/constants.service';
import { SwiperConfigInterface, SwiperNavigationInterface } from 'ngx-swiper-wrapper';
import { DOCUMENT } from '@angular/common';
@Component({
selector: 'div[slider]',
templateUrl: './slider.component.html',
styleUrls: ['./slider.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SliderComponent implements OnInit, OnDestroy {
@Input() nrOfElements;
@Input() columnSize: 'xl' | 'lg' | 'md' = 'xl';
@Input() removeControls;
@Input() btnClass;
subscription: Subscription;
showSwiperControls: boolean;
public navigation: SwiperNavigationInterface = {
nextEl: '.btn-swiper-next',
prevEl: '.btn-swiper-prev'
};
public config: SwiperConfigInterface = {
a11y: true,
lazy: false,
direction: 'horizontal',
slidesPerView: 'auto',
keyboard: true,
mousewheel: false,
scrollbar: false,
spaceBetween: 0,
freeMode: false,
grabCursor: true,
pagination: false,
navigation: this.navigation,
centeredSlides: false,
slidesOffsetBefore: 0,
slidesOffsetAfter: 0,
loop: false
};
constructor(
@Inject(DOCUMENT) private doc: Document,
private detector: ChangeDetectorRef,
private constants: ConstantsService,
) {}
ngOnInit(): void {
const resizeEvent = fromEvent(window, 'resize');
this.subscription = resizeEvent.pipe(map(() => {
return (window.innerWidth || this.doc.documentElement.clientWidth);
}), debounceTime(50)).subscribe(data => {
this.onResize(data);
});
const documentWidth = (window.innerWidth || this.doc.documentElement.clientWidth);
this.configSwiperBehavior(documentWidth);
}
ngOnDestroy(): void {
if (this.subscription) { this.subscription.unsubscribe(); }
}
private onResize(windowWidth: number): void {
this.configSwiperBehavior(windowWidth);
this.detector.detectChanges();
}
private configSwiperBehavior(windowWidth: number): void {
this.showSwiperControls = (!this.removeControls) && this.getAvailableSlots(windowWidth) !== 1 && (this.getAvailableSlots(windowWidth) < this.nrOfElements);
this.config.centeredSlides = !this.inDesktopView(windowWidth); // Center on mobile devices
}
private getAvailableSlots(windowWidth: number): number {
let slots: number;
// One object for each columnSize input, with the amount of slots for the different window widths.
const xl = { xl: 5, lg: 4, md: 3 };
const lg = { xl: 4, lg: 3, md: 2 };
const md = { xl: 3, lg: 2, md: 2 };
const slotsMap = { xl, lg, md };
if (windowWidth >= this.constants.BOOTSTRAP_BREAKPOINTS.XL) {
slots = slotsMap[this.columnSize].xl;
} else if (windowWidth >= this.constants.BOOTSTRAP_BREAKPOINTS.LG) {
slots = slotsMap[this.columnSize].lg;
} else if (windowWidth >= this.constants.BOOTSTRAP_BREAKPOINTS.MD) {
slots = slotsMap[this.columnSize].md;
} else if (windowWidth >= this.constants.BOOTSTRAP_BREAKPOINTS.SM) {
slots = 2;
} else {
slots = 1;
}
return slots;
}
private inDesktopView(width: number): boolean {
return width > this.constants.BOOTSTRAP_BREAKPOINTS.MD;
}
}
<div class="container">
<div class="row row-heading">
<div class="col-sm-10" [ngClass]="{'col-sm-12': !showSwiperControls}">
<ng-content select="[title]"></ng-content>
</div>
<div class="col-sm-2 pr-0 text-right" [ngClass]="showSwiperControls ? 'd-sm-block' : 'd-none'">
<div class="btn-group">
<button type="button" [ngClass]="btnClass" class="btn btn-sm mr-1 btn-swiper-prev">
<i class="icon-chevronPrev"></i>
</button>
<button type="button" [ngClass]="btnClass" class="btn btn-sm btn-swiper-next">
<i class="icon-chevronNext"></i>
</button>
</div>
</div>
</div>
</div>
<div class="swiper-container" [swiper]="config">
<div [ngClass]="['row','swiper-wrapper', columnSize]">
<ng-content select=[slider-element]></ng-content>
</div>
</div>
./slider.component.scss
@import '~swiper/dist/css/swiper.min.css';
@import 'src/app/styles/helpers';
div:host {
height: 100%;
}
.row-heading {
justify-content: center;
align-items: center;
.btn-extra-light-slate {
@include hover {
color: $white;
background-color: $blue;
}
}
button {
padding: calc-rem(7) calc-rem(14);
&:focus {
box-shadow: unset;
}
}
}
.swiper-container {
margin-top: calc-rem(60);
height: calc(100% - 112px); // 112px for margin top + title container height
.row {
flex-flow: row nowrap;
margin: 0;
}
.swiper-wrapper {
height: auto;
margin-bottom: calc-rem(48);
width: 80%;
@include media-breakpoint-up(sm) {
width: 85%;
}
@include media-breakpoint-up(md) {
width: 90%;
}
&.xl {
::ng-deep .col {
@include media-breakpoint-up(sm) {
flex: 0 0 50%; // Two columns
}
@include media-breakpoint-up(md) {
flex: 0 0 33.33333333333%; // Three columns
}
@include media-breakpoint-up(lg) {
flex: 0 0 25%; // Four columns
}
@include media-breakpoint-up(xl) {
flex: 0 0 20%; // Five columns
}
}
}
&.lg {
::ng-deep .col {
@include media-breakpoint-up(md) {
flex: 0 0 50%; // Two columns
}
@include media-breakpoint-up(lg) {
flex: 0 0 33.33333333333%; // Three columns
}
@include media-breakpoint-up(xl) {
flex: 0 0 25%; // Four columns
}
}
}
&.md {
::ng-deep .col {
@include media-breakpoint-up(md) {
flex: 0 0 50%; // Two columns
}
@include media-breakpoint-up(xl) {
flex: 0 0 33.33333333333%; // Three columns
}
}
}
::ng-deep .col {
padding: 0;
flex: 0 0 auto; // One column
}
::ng-deep .swiper-slide {
height: auto;
}
}
}