Implements Initial Stack Slider
This commit is contained in:
@@ -26,13 +26,14 @@
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css",
|
||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"node_modules/normalize.css/normalize.css",
|
||||
"node_modules/cookieconsent/build/cookieconsent.min.css"
|
||||
"node_modules/bootstrap/dist/css/bootstrap.css",
|
||||
"node_modules/cookieconsent/build/cookieconsent.min.css",
|
||||
"node_modules/@glidejs/glide/dist/css/glide.core.css",
|
||||
"node_modules/@glidejs/glide/dist/css/glide.theme.css"
|
||||
],
|
||||
"scripts": [
|
||||
"node_modules/jquery/dist/jquery.min.js",
|
||||
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js",
|
||||
"node_modules/bootstrap/dist/js/bootstrap.bundle.js",
|
||||
"node_modules/cookieconsent/build/cookieconsent.min.js"
|
||||
],
|
||||
"serviceWorker": true,
|
||||
|
||||
112
package-lock.json
generated
112
package-lock.json
generated
@@ -24,6 +24,7 @@
|
||||
"@fortawesome/free-brands-svg-icons": "^6.1.1",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.1.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.1.1",
|
||||
"@glidejs/glide": "^3.6.0",
|
||||
"bootstrap": "^4.6.2",
|
||||
"cookieconsent": "^3.1.1",
|
||||
"cors": "^2.8.5",
|
||||
@@ -32,6 +33,7 @@
|
||||
"jquery": "^3.6.0",
|
||||
"ngx-cookie-service": "^16.0.1",
|
||||
"ngx-cookieconsent": "^4.0.2",
|
||||
"ngx-glide": "^16.0.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
"rxjs": "~7.5.0",
|
||||
"ts-interface-checker": "^1.0.2",
|
||||
@@ -778,12 +780,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.22.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz",
|
||||
"integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==",
|
||||
"version": "7.22.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
|
||||
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.22.10",
|
||||
"@babel/highlight": "^7.22.13",
|
||||
"chalk": "^2.4.2"
|
||||
},
|
||||
"engines": {
|
||||
@@ -977,22 +979,36 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-environment-visitor": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
|
||||
"integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
|
||||
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-function-name": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
|
||||
"integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
|
||||
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.22.5",
|
||||
"@babel/types": "^7.22.5"
|
||||
"@babel/template": "^7.22.15",
|
||||
"@babel/types": "^7.23.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-function-name/node_modules/@babel/template": {
|
||||
"version": "7.22.15",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
|
||||
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/parser": "^7.22.15",
|
||||
"@babel/types": "^7.22.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1154,9 +1170,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
|
||||
"integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1200,12 +1216,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight": {
|
||||
"version": "7.22.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz",
|
||||
"integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
|
||||
"integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.22.5",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"chalk": "^2.4.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
},
|
||||
@@ -1214,9 +1230,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.22.11",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.11.tgz",
|
||||
"integrity": "sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
|
||||
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@@ -2491,19 +2507,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.22.11",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz",
|
||||
"integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==",
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
|
||||
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.22.10",
|
||||
"@babel/generator": "^7.22.10",
|
||||
"@babel/helper-environment-visitor": "^7.22.5",
|
||||
"@babel/helper-function-name": "^7.22.5",
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/generator": "^7.23.0",
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-hoist-variables": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"@babel/parser": "^7.22.11",
|
||||
"@babel/types": "^7.22.11",
|
||||
"@babel/parser": "^7.23.0",
|
||||
"@babel/types": "^7.23.0",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
@@ -2512,12 +2528,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse/node_modules/@babel/generator": {
|
||||
"version": "7.22.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz",
|
||||
"integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
|
||||
"integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.22.10",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"@jridgewell/trace-mapping": "^0.3.17",
|
||||
"jsesc": "^2.5.1"
|
||||
@@ -2527,13 +2543,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.22.11",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz",
|
||||
"integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
|
||||
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.22.5",
|
||||
"@babel/helper-validator-identifier": "^7.22.5",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3102,6 +3118,11 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@glidejs/glide": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@glidejs/glide/-/glide-3.6.0.tgz",
|
||||
"integrity": "sha512-47Aa+JmYjY4xTFpTtYCwrqirmI1arnp1UZETwtWpbTPisXUAuxrdJxKJLH8KHFWMsSrLi9+AcfyfzDIuO75rEA=="
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
|
||||
@@ -12068,6 +12089,19 @@
|
||||
"rxjs": "^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ngx-glide": {
|
||||
"version": "16.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ngx-glide/-/ngx-glide-16.0.0.tgz",
|
||||
"integrity": "sha512-MVPTfYI+dSA1d/GmC6DVkAD5D3VWWLMzcZNAwrvRbMcj4+h4fWoxXlVNu2yLwFF+Nz0O2YhOFpvi6zlD8xg88Q==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=16.x",
|
||||
"@angular/core": ">=16.x",
|
||||
"@glidejs/glide": "3.x"
|
||||
}
|
||||
},
|
||||
"node_modules/nice-napi": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"@fortawesome/free-brands-svg-icons": "^6.1.1",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.1.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.1.1",
|
||||
"@glidejs/glide": "^3.6.0",
|
||||
"bootstrap": "^4.6.2",
|
||||
"cookieconsent": "^3.1.1",
|
||||
"cors": "^2.8.5",
|
||||
@@ -40,6 +41,7 @@
|
||||
"jquery": "^3.6.0",
|
||||
"ngx-cookie-service": "^16.0.1",
|
||||
"ngx-cookieconsent": "^4.0.2",
|
||||
"ngx-glide": "^16.0.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
"rxjs": "~7.5.0",
|
||||
"ts-interface-checker": "^1.0.2",
|
||||
|
||||
@@ -11,12 +11,14 @@ import { AppServiceWorkerModule } from './app-service-worker.module';
|
||||
import { ServiceWorkerModule } from '@angular/service-worker';
|
||||
import { environment } from '../environments/environment';
|
||||
import { FooterComponent } from './footer/footer.component';
|
||||
import {HomeModule} from "./home/home.module";
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent, HomeComponent, FooterComponent],
|
||||
declarations: [AppComponent, FooterComponent],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
HeaderModule,
|
||||
HomeModule,
|
||||
AppRouterModule,
|
||||
AppServiceWorkerModule,
|
||||
SharedModule,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
|
||||
background: rgb(46,46,46);
|
||||
background: linear-gradient(180deg, rgba(46,46,46,1) 65%, rgba(46,46,46,0.45) 100%);
|
||||
z-index: 50;
|
||||
|
||||
height: 10vh;
|
||||
|
||||
@@ -97,10 +97,10 @@
|
||||
.stack-section {
|
||||
background: rgb(241,241,241);
|
||||
/*background: linear-gradient(0deg, rgba(241,241,241,1) 80%, rgba(51,51,51,1) 100%);*/
|
||||
height: 90vh;
|
||||
height: 80vh;
|
||||
}
|
||||
.stack {
|
||||
height: 60%;
|
||||
height: 35%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
</div>
|
||||
|
||||
<div class="stack-slider">
|
||||
|
||||
<app-stack-slider>
|
||||
</app-stack-slider>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
21
src/app/home/home.module.ts
Normal file
21
src/app/home/home.module.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {HomeComponent} from "./home.component";
|
||||
import {StackSliderComponent} from "./stack-slider/stack-slider.component";
|
||||
import {StackCardComponent} from "./stack-slider/stack-card/stack-card.component";
|
||||
import {NgxGlideComponent} from "ngx-glide";
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
HomeComponent,
|
||||
StackSliderComponent,
|
||||
StackCardComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NgxGlideComponent
|
||||
]
|
||||
})
|
||||
export class HomeModule { }
|
||||
@@ -0,0 +1,40 @@
|
||||
.stack-card {
|
||||
width: 300px;
|
||||
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.stack-card-image {
|
||||
width: 100%;
|
||||
border-top-left-radius: 15px !important;
|
||||
border-top-right-radius: 15px !important;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.stack-card-body {
|
||||
padding: 10px;
|
||||
flex-grow: 1;
|
||||
|
||||
width: 250px;
|
||||
height: 130px;
|
||||
inline-size: 250px;
|
||||
}
|
||||
|
||||
.stack-card-text {
|
||||
word-break: break-all !important;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
|
||||
/*CARD STATE*/
|
||||
.active {
|
||||
opacity: 1;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.inactive {
|
||||
opacity: 0.85;
|
||||
width: 275px;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<div class="card stack-card inactive" [@cardAnimation]="cardState">
|
||||
<img class="card-img-top stack-card-image" [src]="stack.image" alt="Stack Image">
|
||||
<div class="card-body stack-card-body">
|
||||
<h5 class="card-title stack-card-title">{{stack.name}}</h5>
|
||||
<p class="card-text stack-card-text">{{stack.description}}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StackCardComponent } from './stack-card.component';
|
||||
|
||||
describe('StackCardComponent', () => {
|
||||
let component: StackCardComponent;
|
||||
let fixture: ComponentFixture<StackCardComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [StackCardComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(StackCardComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
35
src/app/home/stack-slider/stack-card/stack-card.component.ts
Normal file
35
src/app/home/stack-slider/stack-card/stack-card.component.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {Stack} from "../../../shared/model/stack/stack.model";
|
||||
import {animate, state, style, transition, trigger} from "@angular/animations";
|
||||
|
||||
@Component({
|
||||
selector: 'app-stack-card',
|
||||
templateUrl: './stack-card.component.html',
|
||||
styleUrls: ['./stack-card.component.css'],
|
||||
animations: [
|
||||
trigger('cardAnimation', [
|
||||
state('active', style({
|
||||
opacity: 1,
|
||||
width: '300px',
|
||||
})),
|
||||
state('inactive', style({
|
||||
opacity: 0.85,
|
||||
width: '275px',
|
||||
})),
|
||||
transition('* => *', [
|
||||
animate('0.1s')
|
||||
]),
|
||||
])
|
||||
],
|
||||
})
|
||||
export class StackCardComponent {
|
||||
@Input()
|
||||
stack!: Stack;
|
||||
|
||||
@Input()
|
||||
inFocus: boolean = false;
|
||||
|
||||
get cardState(): 'active'|'inactive' {
|
||||
return this.inFocus ? 'active' : 'inactive';
|
||||
}
|
||||
}
|
||||
5
src/app/home/stack-slider/stack-slider.component.css
Normal file
5
src/app/home/stack-slider/stack-slider.component.css
Normal file
@@ -0,0 +1,5 @@
|
||||
.slider-card {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
9
src/app/home/stack-slider/stack-slider.component.html
Normal file
9
src/app/home/stack-slider/stack-slider.component.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<ng-container class="container" *ngIf="stacks && stacks.length > 0">
|
||||
<ngx-glide #ngxGlide>
|
||||
<ng-container *ngFor="let stack of stacks">
|
||||
<app-stack-card class="slider-card" [stack]="stack"
|
||||
[inFocus]="isInFocus(stack)">
|
||||
</app-stack-card>
|
||||
</ng-container>
|
||||
</ngx-glide>
|
||||
</ng-container>
|
||||
21
src/app/home/stack-slider/stack-slider.component.spec.ts
Normal file
21
src/app/home/stack-slider/stack-slider.component.spec.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StackSliderComponent } from './stack-slider.component';
|
||||
|
||||
describe('StackSliderComponent', () => {
|
||||
let component: StackSliderComponent;
|
||||
let fixture: ComponentFixture<StackSliderComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [StackSliderComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(StackSliderComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
76
src/app/home/stack-slider/stack-slider.component.ts
Normal file
76
src/app/home/stack-slider/stack-slider.component.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import {AfterViewInit, ChangeDetectorRef, Component, ViewChild} from '@angular/core';
|
||||
import {NgxGlideComponent} from "ngx-glide";
|
||||
import {Stack} from "../../shared/model/stack/stack.model";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-stack-slider',
|
||||
templateUrl: './stack-slider.component.html',
|
||||
styleUrls: ['./stack-slider.component.css']
|
||||
})
|
||||
export class StackSliderComponent implements AfterViewInit {
|
||||
@ViewChild('ngxGlide')
|
||||
ngxGlide!: NgxGlideComponent;
|
||||
|
||||
stacks: Stack[] = [
|
||||
{
|
||||
name: 'Angular',
|
||||
image: 'https://picsum.photos/id/1/100/100',
|
||||
description: 'Angular is a platform for building mobile and desktop web applications.',
|
||||
},
|
||||
{
|
||||
name: 'React',
|
||||
image: 'https://picsum.photos/id/2/100/100',
|
||||
description: 'React is a JavaScript library for building user interfaces.',
|
||||
},
|
||||
{
|
||||
name: 'Vue',
|
||||
image: 'https://picsum.photos/id/3/100/100',
|
||||
description: 'Vue is a progressive framework for building user interfaces.',
|
||||
},
|
||||
{
|
||||
name: 'Svelte',
|
||||
image: 'https://picsum.photos/id/4/100/100',
|
||||
description: 'Svelte is a radical new approach to building user interfaces.',
|
||||
},
|
||||
{
|
||||
name: 'Ember',
|
||||
image: 'https://picsum.photos/id/5/100/100',
|
||||
description: 'Ember.js is an open-source JavaScript web framework.',
|
||||
},
|
||||
{
|
||||
name: 'Preact',
|
||||
image: 'https://picsum.photos/id/6/100/100',
|
||||
description: 'Preact is a fast 3kB alternative to React with the same modern API.',
|
||||
}
|
||||
]
|
||||
|
||||
constructor(private cd: ChangeDetectorRef) { }
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
if (this.ngxGlide)
|
||||
this.buildCarousel();
|
||||
|
||||
this.cd.detectChanges();
|
||||
}
|
||||
|
||||
buildCarousel(): void {
|
||||
this.ngxGlide.showArrows = false;
|
||||
this.ngxGlide.showBullets = false;
|
||||
this.ngxGlide.type = 'carousel';
|
||||
this.ngxGlide.perView = 5;
|
||||
this.ngxGlide.focusAt = 'center';
|
||||
this.ngxGlide.gap = 10;
|
||||
this.ngxGlide.autoplay = 3000;
|
||||
|
||||
this.ngxGlide.recreate();
|
||||
}
|
||||
|
||||
get currentIndex(): number {
|
||||
return this.ngxGlide?.getIndex();
|
||||
}
|
||||
|
||||
isInFocus(stack: Stack): boolean {
|
||||
return this.stacks.indexOf(stack) === this.currentIndex;
|
||||
}
|
||||
}
|
||||
5
src/app/shared/model/stack/stack.model.ts
Normal file
5
src/app/shared/model/stack/stack.model.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface Stack {
|
||||
name: string;
|
||||
image: string;
|
||||
description: string;
|
||||
}
|
||||
Reference in New Issue
Block a user