File

app/shared/slider/slider.component.ts

Implements

OnInit OnDestroy

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector div[slider]
styleUrls ./slider.component.scss
templateUrl ./slider.component.html

Index

Properties
Methods
Inputs

Constructor

constructor(doc: Document, detector: ChangeDetectorRef, constants: ConstantsService)
Parameters :
Name Type Optional
doc Document No
detector ChangeDetectorRef No
constants ConstantsService No

Inputs

btnClass
columnSize
Type : "xl" | "lg" | "md"
Default value : 'xl'
nrOfElements
removeControls

Methods

Private configSwiperBehavior
configSwiperBehavior(windowWidth: number)
Parameters :
Name Type Optional
windowWidth number No
Returns : void
Private getAvailableSlots
getAvailableSlots(windowWidth: number)
Parameters :
Name Type Optional
windowWidth number No
Returns : number
Private inDesktopView
inDesktopView(width: number)
Parameters :
Name Type Optional
width number No
Returns : boolean
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Private onResize
onResize(windowWidth: number)
Parameters :
Name Type Optional
windowWidth number No
Returns : void

Properties

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 }
Public navigation
Type : SwiperNavigationInterface
Default value : { nextEl: '.btn-swiper-next', prevEl: '.btn-swiper-prev' }
showSwiperControls
Type : boolean
subscription
Type : Subscription
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;
        }
    }
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""