From bbb18282a0728e369ba196be993b57d7b5816132 Mon Sep 17 00:00:00 2001 From: Olivia Guyot Date: Thu, 12 Oct 2023 21:20:46 +0200 Subject: [PATCH] first version --- .../src/lib/carousel/carousel.component.css | 20 ++++++++ .../src/lib/carousel/carousel.component.html | 16 ++++++ .../lib/carousel/carousel.component.spec.ts | 21 ++++++++ .../carousel/carousel.component.stories.ts | 42 ++++++++++++++++ .../src/lib/carousel/carousel.component.ts | 50 +++++++++++++++++++ libs/ui/layout/src/lib/ui-layout.module.ts | 3 ++ package-lock.json | 6 +++ package.json | 1 + 8 files changed, 159 insertions(+) create mode 100644 libs/ui/layout/src/lib/carousel/carousel.component.css create mode 100644 libs/ui/layout/src/lib/carousel/carousel.component.html create mode 100644 libs/ui/layout/src/lib/carousel/carousel.component.spec.ts create mode 100644 libs/ui/layout/src/lib/carousel/carousel.component.stories.ts create mode 100644 libs/ui/layout/src/lib/carousel/carousel.component.ts diff --git a/libs/ui/layout/src/lib/carousel/carousel.component.css b/libs/ui/layout/src/lib/carousel/carousel.component.css new file mode 100644 index 0000000000..692a8be27f --- /dev/null +++ b/libs/ui/layout/src/lib/carousel/carousel.component.css @@ -0,0 +1,20 @@ +:host .carousel-container /deep/ > * { + flex-shrink: 0; +} +:host { + position: relative; +} +.carousel-step-dot { + width: 6px; + height: 6px; + border-radius: 6px; + position: relative; +} +.carousel-step-dot:after { + content: ''; + position: absolute; + left: -4px; + top: -4px; + width: 14px; + height: 14px; +} diff --git a/libs/ui/layout/src/lib/carousel/carousel.component.html b/libs/ui/layout/src/lib/carousel/carousel.component.html new file mode 100644 index 0000000000..e24c65971c --- /dev/null +++ b/libs/ui/layout/src/lib/carousel/carousel.component.html @@ -0,0 +1,16 @@ +
+ +
+
+ +
diff --git a/libs/ui/layout/src/lib/carousel/carousel.component.spec.ts b/libs/ui/layout/src/lib/carousel/carousel.component.spec.ts new file mode 100644 index 0000000000..5d09fb23f6 --- /dev/null +++ b/libs/ui/layout/src/lib/carousel/carousel.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { CarouselComponent } from './carousel.component' + +describe('CarouselComponent', () => { + let component: CarouselComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CarouselComponent], + }).compileComponents() + + fixture = TestBed.createComponent(CarouselComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it('should create', () => { + expect(component).toBeTruthy() + }) +}) diff --git a/libs/ui/layout/src/lib/carousel/carousel.component.stories.ts b/libs/ui/layout/src/lib/carousel/carousel.component.stories.ts new file mode 100644 index 0000000000..6086a98635 --- /dev/null +++ b/libs/ui/layout/src/lib/carousel/carousel.component.stories.ts @@ -0,0 +1,42 @@ +import type { Meta, StoryObj } from '@storybook/angular' +import { CarouselComponent } from './carousel.component' +import { componentWrapperDecorator } from '@storybook/angular' + +const meta: Meta = { + component: CarouselComponent, + title: 'Layout/CarouselComponent', + decorators: [ + componentWrapperDecorator( + (story) => + `
${story}
` + ), + ], +} +export default meta +type Story = StoryObj + +export const Primary: Story = { + args: {}, + render: (args) => ({ + props: args, + template: ` + +
+ First box +
+
+ Second box +
+
+ Third box +
+
+ Fourth box +
+
+ Fifth box +
+
+`, + }), +} diff --git a/libs/ui/layout/src/lib/carousel/carousel.component.ts b/libs/ui/layout/src/lib/carousel/carousel.component.ts new file mode 100644 index 0000000000..0d9c52897f --- /dev/null +++ b/libs/ui/layout/src/lib/carousel/carousel.component.ts @@ -0,0 +1,50 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ElementRef, + Input, + ViewChild, +} from '@angular/core' +import EmblaCarousel, { EmblaCarouselType } from 'embla-carousel' + +@Component({ + selector: 'gn-ui-carousel', + templateUrl: './carousel.component.html', + styleUrls: ['./carousel.component.css'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class CarouselComponent implements AfterViewInit { + @Input() containerClass = '' + @Input() stepsContainerClass = '' + @ViewChild('carouselOverflowContainer') + carouselOverflowContainer: ElementRef + steps: number[] = [] + selectedStep = -1 + emblaApi: EmblaCarouselType + + constructor(private changeDetector: ChangeDetectorRef) {} + + ngAfterViewInit() { + this.emblaApi = EmblaCarousel( + this.carouselOverflowContainer.nativeElement, + { + duration: 15, + } + ) + const refreshSteps = () => { + this.steps = this.emblaApi.scrollSnapList() + this.selectedStep = this.emblaApi.selectedScrollSnap() + this.changeDetector.detectChanges() + } + this.emblaApi + .on('init', refreshSteps) + .on('reInit', refreshSteps) + .on('select', refreshSteps) + } + + scrollToStep(stepIndex: number) { + this.emblaApi.scrollTo(stepIndex) + } +} diff --git a/libs/ui/layout/src/lib/ui-layout.module.ts b/libs/ui/layout/src/lib/ui-layout.module.ts index 4cc50c09b6..69a28b9c8b 100644 --- a/libs/ui/layout/src/lib/ui-layout.module.ts +++ b/libs/ui/layout/src/lib/ui-layout.module.ts @@ -6,6 +6,7 @@ import { StickyHeaderComponent } from './sticky-header/sticky-header.component' import { AnchorLinkDirective } from './anchor-link/anchor-link.directive' import { ExpandablePanelButtonComponent } from './expandable-panel-button/expandable-panel-button.component' import { MatIconModule } from '@angular/material/icon' +import { CarouselComponent } from './carousel/carousel.component' @NgModule({ imports: [CommonModule, MatIconModule, TranslateModule.forChild()], @@ -14,12 +15,14 @@ import { MatIconModule } from '@angular/material/icon' StickyHeaderComponent, AnchorLinkDirective, ExpandablePanelButtonComponent, + CarouselComponent, ], exports: [ ExpandablePanelComponent, StickyHeaderComponent, AnchorLinkDirective, ExpandablePanelButtonComponent, + CarouselComponent, ], }) export class UiLayoutModule {} diff --git a/package-lock.json b/package-lock.json index c45a142b5a..cd522bcd75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,7 @@ "date-fns": "^2.29.3", "document-register-element": "^1.14.10", "duration-relativetimeformat": "^2.0.3", + "embla-carousel": "^8.0.0-rc14", "express": "^4.17.1", "moment": "^2.29.4", "ng-table-virtual-scroll": "^1.4.1", @@ -17263,6 +17264,11 @@ "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", "dev": true }, + "node_modules/embla-carousel": { + "version": "8.0.0-rc14", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.0.0-rc14.tgz", + "integrity": "sha512-/NLkMFZ7xKryRVYeUjmhbfV63Vr07saPBDwAX2TPMbcaiWwfQfU5Xsc2AiCMZANtwmzsjRK6gSBa7hOy/VXu6g==" + }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", diff --git a/package.json b/package.json index 07d2583743..4f4f835af6 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "date-fns": "^2.29.3", "document-register-element": "^1.14.10", "duration-relativetimeformat": "^2.0.3", + "embla-carousel": "^8.0.0-rc14", "express": "^4.17.1", "moment": "^2.29.4", "ng-table-virtual-scroll": "^1.4.1",