#1896 Weitere Medien werden über Rand angezeigt

This commit is contained in:
Lorenz Hilpert
2021-06-17 15:33:40 +02:00
parent 68a877eff5
commit b29f34f4a8
7 changed files with 133 additions and 109 deletions

View File

@@ -157,7 +157,7 @@
<div class="product-formats" *ngIf="item.family?.length > 0">
<span class="label">Auch verfügbar als</span>
<ui-slider [scrollDistance]="200">
<ui-slider [scrollDistance]="250">
<a class="product-family" *ngFor="let format of item.family" [routerLink]="['/product', 'details', 'ean', format.product.ean]">
<span class="format-detail">
<img [src]="'/assets/images/OF_Icon_' + format.product?.format + '.svg'" alt="format icon" />

View File

@@ -191,22 +191,17 @@
}
.product-formats {
@apply flex flex-row whitespace-nowrap items-center px-5 h-px-40 mb-16 pb-8;
@apply grid whitespace-nowrap items-center px-5 h-px-40 mb-16 pb-8;
grid-template-rows: auto;
grid-template-columns: auto 1fr;
max-width: 100%;
.label {
@apply mr-2;
}
ui-slider {
width: 735px;
::ng-deep button {
height: auto;
}
}
.product-family {
@apply mr-4 text-active-customer font-bold no-underline mt-4;
@apply mr-4 text-active-customer font-bold no-underline px-2;
.format-detail {
@apply flex items-center;

View File

@@ -31,11 +31,6 @@ export class AppComponent implements OnInit, OnDestroy {
return this.ssoService.isAuthenticated();
}
@HostBinding('class.desktop')
get isDesktop() {
return this.deviceDetectorService.isDesktop();
}
constructor(
private config: AppConfiguration,
private ssoService: SsoService,
@@ -84,6 +79,8 @@ export class AppComponent implements OnInit, OnDestroy {
if (this.includeGoogleAnalytics) {
this.initGoogleAnalytics();
}
this.renderer.addClass(this.document.body, this.deviceDetectorService.deviceType);
}
ngOnDestroy() {

View File

@@ -1,25 +1,13 @@
<div class="slider-wrapper" (mouseenter)="calcVisibility()">
<div
class="cta-prev-wrapper"
*ngIf="!startReached"
(mouseenter)="changeVisibility(false, true)"
(mouseleave)="changeVisibility(false, false)"
>
<button class="cta-slider-prev" (click)="prev()" *ngIf="showPrevSliderButtons$ | async">
<ui-icon class="slider-icon" rotate="180deg" icon="arrow" size="15px"></ui-icon>
</button>
</div>
<div class="slider-container" #sliderContainer>
<ng-content></ng-content>
</div>
<div
class="cta-next-wrapper"
*ngIf="!endReached"
(mouseenter)="changeVisibility(true, false)"
(mouseleave)="changeVisibility(false, false)"
>
<button class="cta-slider-next" (click)="next()" *ngIf="showNextSliderButtons$ | async">
<ui-icon class="slider-icon" icon="arrow" size="15px"></ui-icon>
</button>
</div>
<div class="prev-wrapper" *ngIf="!isStartVisible">
<button type="button" (click)="scrollLeft()">
<ui-icon class="slider-icon" rotate="180deg" icon="arrow" size="15px"></ui-icon>
</button>
</div>
<div #sliderWrapper class="ui-slider-wrapper">
<ng-content></ng-content>
</div>
<div class="next-wrapper" *ngIf="!isEndVisible">
<button type="button" (click)="scrollRight()">
<ui-icon class="slider-icon" icon="arrow" size="15px"></ui-icon>
</button>
</div>

View File

@@ -1,31 +1,73 @@
.slider-wrapper {
@apply relative flex flex-row items-center px-2;
.cta-slider-next,
.cta-slider-prev {
@apply outline-none border-none bg-white rounded-card h-full opacity-80;
width: 55px;
box-shadow: 3px 0 14px 8px white;
// .slider-wrapper {
// @apply relative flex flex-row items-center px-2;
// .cta-slider-next,
// .cta-slider-prev {
// @apply outline-none border-none bg-white rounded-card h-full opacity-80;
// width: 55px;
// box-shadow: 3px 0 14px 8px white;
// }
// .cta-next-wrapper {
// @apply flex absolute right-0 w-14 h-full pl-4 items-center justify-center;
// }
// .cta-prev-wrapper {
// @apply flex absolute left-0 w-14 h-full pr-4 items-center justify-center;
// }
// .slider-icon {
// @apply items-center justify-center;
// width: 40px;
// height: 40px;
// border-radius: 50%;
// background-color: #e9f0f8;
// color: #0f1542;
// }
// .slider-container {
// @apply flex flex-row overflow-scroll;
// scroll-behavior: smooth;
// width: calc(100% + 1rem);
// }
// }
.ui-slider {
@apply grid relative;
min-height: 40px;
grid-template-columns: auto 1fr auto;
.ui-slider-wrapper {
@apply flex overflow-scroll items-center;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
.cta-next-wrapper {
@apply flex absolute right-0 w-14 h-full pl-4 items-center justify-center;
.prev-wrapper,
.next-wrapper {
@apply absolute hidden justify-center items-center;
button {
@apply rounded-full grid content-center justify-center bg-glitter text-ucla-blue border-none outline-none;
width: 40px;
height: 40px;
}
}
.cta-prev-wrapper {
@apply flex absolute left-0 w-14 h-full pr-4 items-center justify-center;
.prev-wrapper {
@apply top-0 left-0 bottom-0;
background: rgb(0, 0, 0);
background: linear-gradient(270deg, rgba(0, 0, 0, 0) 0%, rgba(255, 255, 255, 0.7) 50%);
}
.slider-icon {
@apply items-center justify-center;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #e9f0f8;
color: #0f1542;
}
.slider-container {
@apply flex flex-row overflow-scroll;
scroll-behavior: smooth;
width: calc(100% + 1rem);
.next-wrapper {
@apply top-0 right-0 bottom-0;
background: rgb(0, 0, 0);
background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(255, 255, 255, 0.7) 50%);
}
}
.desktop .ui-slider:hover .prev-wrapper,
.desktop .ui-slider:hover .next-wrapper {
display: grid;
}

View File

@@ -1,67 +1,69 @@
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
import { NativeContainerService } from 'native-container';
import { BehaviorSubject } from 'rxjs';
import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
HostBinding,
Input,
OnDestroy,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
@Component({
selector: 'ui-slider',
templateUrl: 'slider.component.html',
styleUrls: ['slider.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class SliderComponent implements AfterViewInit {
@ViewChild('sliderContainer', { static: false }) sliderContainer: ElementRef<HTMLDivElement>;
export class UiSliderComponent implements AfterViewInit, OnDestroy {
@HostBinding('class') clazz = 'ui-slider';
/* @internal */
showPrevSliderButtons$ = new BehaviorSubject<boolean>(false);
@Input() scrollDistance = 200;
/* @internal */
showNextSliderButtons$ = new BehaviorSubject<boolean>(false);
@ViewChild('sliderWrapper', { read: ElementRef, static: true })
slideWrapper: ElementRef;
/* @internal */
scrollDistance$ = new BehaviorSubject<number>(100);
hideButtons: boolean;
startReached: boolean;
endReached: boolean;
@Input()
get scrollDistance(): number {
return this.scrollDistance$.value;
get slideWrapperNativeElement(): HTMLElement {
return this.slideWrapper?.nativeElement;
}
set scrollDistance(value) {
if (this.scrollDistance !== value) {
this.scrollDistance$.next(value);
}
get isStartVisible() {
const { scrollLeft } = this.slideWrapperNativeElement;
return scrollLeft === 0;
}
constructor(private nativeContainer: NativeContainerService) {}
get isEndVisible() {
const { scrollLeft, clientWidth, scrollWidth } = this.slideWrapperNativeElement;
return scrollLeft + clientWidth === scrollWidth;
}
private subscriptions = new Subscription();
constructor(private cdr: ChangeDetectorRef) {}
ngAfterViewInit(): void {
this.hideButtons = this.nativeContainer.isUiWebview()?.isNative;
this.changeVisibility(false, false);
this.cdr.markForCheck();
this.subscriptions.add(
fromEvent(this.slideWrapperNativeElement, 'scroll')
.pipe(debounceTime(100))
.subscribe(() => this.cdr.markForCheck())
);
}
prev() {
this.sliderContainer.nativeElement.scrollLeft -= this.scrollDistance;
this.changeVisibility(false, true);
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
calcVisibility() {
this.startReached = this.sliderContainer.nativeElement.scrollLeft === 0;
this.endReached =
this.sliderContainer.nativeElement.scrollWidth - this.sliderContainer.nativeElement.offsetWidth ===
this.sliderContainer.nativeElement.scrollLeft;
scrollLeft() {
this.slideWrapperNativeElement.scrollTo({ left: this.slideWrapperNativeElement.scrollLeft - this.scrollDistance, behavior: 'smooth' });
}
changeVisibility(next: boolean, prev: boolean) {
this.calcVisibility();
this.showPrevSliderButtons$.next(!this.hideButtons && prev && !this.startReached);
this.showNextSliderButtons$.next(!this.hideButtons && next && !this.endReached);
}
next() {
this.sliderContainer.nativeElement.scrollLeft += this.scrollDistance;
this.changeVisibility(true, false);
scrollRight() {
this.slideWrapperNativeElement.scrollTo({ left: this.slideWrapperNativeElement.scrollLeft + this.scrollDistance, behavior: 'smooth' });
}
}

View File

@@ -1,11 +1,11 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { UiIconModule } from '@ui/icon';
import { SliderComponent } from './slider.component';
import { UiSliderComponent } from './slider.component';
@NgModule({
declarations: [SliderComponent],
declarations: [UiSliderComponent],
imports: [CommonModule, UiIconModule],
exports: [SliderComponent],
exports: [UiSliderComponent],
})
export class UiSliderModule {}