@gardev/components 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/gardev-components.mjs +575 -0
- package/fesm2022/gardev-components.mjs.map +1 -0
- package/package.json +25 -12
- package/types/gardev-components.d.ts +139 -0
- package/ng-package.json +0 -7
- package/src/lib/components/bottle/bottle.component.css +0 -4
- package/src/lib/components/bottle/bottle.component.html +0 -1
- package/src/lib/components/bottle/bottle.component.spec.ts +0 -23
- package/src/lib/components/bottle/bottle.component.ts +0 -164
- package/src/lib/components/caroussel/caroussel-menu/caroussel-menu.component.css +0 -23
- package/src/lib/components/caroussel/caroussel-menu/caroussel-menu.component.html +0 -5
- package/src/lib/components/caroussel/caroussel-menu/caroussel-menu.component.ts +0 -63
- package/src/lib/components/caroussel/caroussel-menu/caroussel-menu.spec.ts +0 -23
- package/src/lib/components/caroussel/caroussel.component.css +0 -11
- package/src/lib/components/caroussel/caroussel.component.html +0 -8
- package/src/lib/components/caroussel/caroussel.component.ts +0 -24
- package/src/lib/components/cronogram/cronogram.component.css +0 -58
- package/src/lib/components/cronogram/cronogram.component.html +0 -47
- package/src/lib/components/cronogram/cronogram.component.spec.ts +0 -23
- package/src/lib/components/cronogram/cronogram.component.ts +0 -99
- package/src/lib/components/stack-caroussel/stack-caroussel.css +0 -25
- package/src/lib/components/stack-caroussel/stack-caroussel.html +0 -4
- package/src/lib/components/stack-caroussel/stack-caroussel.spec.ts +0 -23
- package/src/lib/components/stack-caroussel/stack-caroussel.ts +0 -50
- package/src/lib/layouts/menu/menu.component.css +0 -50
- package/src/lib/layouts/menu/menu.component.html +0 -21
- package/src/lib/layouts/menu/menu.component.ts +0 -98
- package/src/lib/layouts/menu/menu.spec.ts +0 -23
- package/src/lib/layouts/navbar/navbar.component.css +0 -34
- package/src/lib/layouts/navbar/navbar.component.html +0 -10
- package/src/lib/layouts/navbar/navbar.component.spec.ts +0 -23
- package/src/lib/layouts/navbar/navbar.component.ts +0 -46
- package/src/lib/layouts/page-layout/page-layout.component.css +0 -13
- package/src/lib/layouts/page-layout/page-layout.component.html +0 -32
- package/src/lib/layouts/page-layout/page-layout.component.spec.ts +0 -23
- package/src/lib/layouts/page-layout/page-layout.component.ts +0 -13
- package/src/lib/layouts/scroll-reactive-section/scroll-reactive-section.component.css +0 -0
- package/src/lib/layouts/scroll-reactive-section/scroll-reactive-section.component.html +0 -10
- package/src/lib/layouts/scroll-reactive-section/scroll-reactive-section.component.spec.ts +0 -23
- package/src/lib/layouts/scroll-reactive-section/scroll-reactive-section.component.ts +0 -40
- package/src/lib/layouts/section/section.component.css +0 -0
- package/src/lib/layouts/section/section.component.html +0 -10
- package/src/lib/layouts/section/section.component.spec.ts +0 -23
- package/src/lib/layouts/section/section.component.ts +0 -12
- package/src/lib/theme.service.ts +0 -22
- package/src/public-api.ts +0 -14
- package/tsconfig.lib.json +0 -17
- package/tsconfig.lib.prod.json +0 -11
- package/tsconfig.spec.json +0 -15
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Component, Input } from '@angular/core';
|
|
2
|
-
import { NgForOf } from "@angular/common";
|
|
3
|
-
import { CarousselMenuComponent } from './caroussel-menu/caroussel-menu.component';
|
|
4
|
-
|
|
5
|
-
@Component({
|
|
6
|
-
selector: 'ard-caroussel',
|
|
7
|
-
imports: [NgForOf, CarousselMenuComponent],
|
|
8
|
-
templateUrl: './caroussel.component.html',
|
|
9
|
-
styleUrl: './caroussel.component.css',
|
|
10
|
-
})
|
|
11
|
-
export class CarousselComponent {
|
|
12
|
-
@Input() images: string[] = [];
|
|
13
|
-
|
|
14
|
-
index = 0;
|
|
15
|
-
|
|
16
|
-
next() {
|
|
17
|
-
this.index = (this.index + 1) % this.images.length;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
goTo(i: number) {
|
|
21
|
-
this.index = i;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
.left-container.odd {
|
|
2
|
-
padding: 0 1rem
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.right-container.even {
|
|
6
|
-
padding: 0 1rem;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.left-container,
|
|
10
|
-
.right-container {
|
|
11
|
-
padding: 0 1rem;
|
|
12
|
-
max-width: 35ch;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.general-container {
|
|
16
|
-
transition: opacity 0.6s;
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.line {
|
|
21
|
-
background: var(--color-text);
|
|
22
|
-
width: 100%;
|
|
23
|
-
position: absolute;
|
|
24
|
-
border-radius: 1rem 1rem 0 0;
|
|
25
|
-
animation-timing-function: ease-out;
|
|
26
|
-
width: 0.4rem
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.bullet {
|
|
30
|
-
width: 0.4rem;
|
|
31
|
-
min-height: 0.4rem;
|
|
32
|
-
background: var(--color-text);
|
|
33
|
-
outline: 3px solid var(--color-text);
|
|
34
|
-
border-radius: 2rem;
|
|
35
|
-
position: absolute;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.hidden {
|
|
39
|
-
opacity: 0;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.visible {
|
|
43
|
-
opacity: 1;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.center {
|
|
47
|
-
position: relative;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
.left-container {
|
|
53
|
-
display: flex;
|
|
54
|
-
justify-content: end;
|
|
55
|
-
text-align: end;
|
|
56
|
-
justify-self: end;
|
|
57
|
-
flex-flow: column
|
|
58
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
<h4>cronogram.component.ts</h4>
|
|
2
|
-
|
|
3
|
-
<p>
|
|
4
|
-
en la vista mobile, estarà tot en un mateix costat?
|
|
5
|
-
</p>
|
|
6
|
-
|
|
7
|
-
<div #wrapper>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@for(day of items; track day.date; let i = $index;) {
|
|
12
|
-
|
|
13
|
-
<div style="display: grid; grid-template-columns: 1fr 0fr 1fr;" class="general-container" #CronogramContent>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<div class="left-container" [ngClass]="i % 2 == 0 ? 'odd' : 'even'">
|
|
17
|
-
@if(i % 2 === 0) {
|
|
18
|
-
<h3>{{day.date}}</h3>
|
|
19
|
-
<p>lorem ipsum dolor sit amet, lorem ipsum dolor sit amet, lorem ipsum dolor sit amet, lorem ipsum dolor sit
|
|
20
|
-
amet, lorem ipsum dolor sit amet, lorem ipsum dolor sit amet,</p>
|
|
21
|
-
}
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<div class="center" style="height: 100%; display: flex; width: 1rem; flex-flow: column; position: relative">
|
|
26
|
-
<div class="bullet" style="z-index: 2">
|
|
27
|
-
</div>
|
|
28
|
-
|
|
29
|
-
@if (i == 0) {
|
|
30
|
-
<div class="line" #line>
|
|
31
|
-
|
|
32
|
-
</div>
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
</div>
|
|
36
|
-
<div class="right-container cronogram-content" [ngClass]="i % 2 == 0 ? 'odd' : 'even'">
|
|
37
|
-
@if(i % 2 !== 0) {
|
|
38
|
-
<h3>{{day.date}}</h3>
|
|
39
|
-
<p>lorem ipsum dolor sit amet, lorem ipsum dolor sit amet, lorem ipsum dolor sit amet, lorem ipsum dolor sit
|
|
40
|
-
amet, lorem ipsum dolor sit amet, lorem ipsum dolor sit amet,</p>
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
</div>
|
|
46
|
-
}
|
|
47
|
-
</div>
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { CronogramComponent } from './cronogram.component';
|
|
4
|
-
|
|
5
|
-
describe('CronogramComponent', () => {
|
|
6
|
-
let component: CronogramComponent;
|
|
7
|
-
let fixture: ComponentFixture<CronogramComponent>;
|
|
8
|
-
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
await TestBed.configureTestingModule({
|
|
11
|
-
imports: [CronogramComponent]
|
|
12
|
-
})
|
|
13
|
-
.compileComponents();
|
|
14
|
-
|
|
15
|
-
fixture = TestBed.createComponent(CronogramComponent);
|
|
16
|
-
component = fixture.componentInstance;
|
|
17
|
-
await fixture.whenStable();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should create', () => {
|
|
21
|
-
expect(component).toBeTruthy();
|
|
22
|
-
});
|
|
23
|
-
});
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { Component, ElementRef, HostListener, QueryList, ViewChild, ViewChildren } from '@angular/core';
|
|
2
|
-
import { NgClass } from "@angular/common";
|
|
3
|
-
|
|
4
|
-
@Component({
|
|
5
|
-
selector: 'ard-cronogram',
|
|
6
|
-
imports: [NgClass],
|
|
7
|
-
templateUrl: './cronogram.component.html',
|
|
8
|
-
styleUrl: './cronogram.component.css',
|
|
9
|
-
})
|
|
10
|
-
export class CronogramComponent {
|
|
11
|
-
@ViewChild('wrapper', { read: ElementRef }) wrapper!: ElementRef<HTMLElement>;
|
|
12
|
-
@ViewChild('line', { read: ElementRef }) line!: ElementRef<HTMLElement>;
|
|
13
|
-
|
|
14
|
-
@ViewChildren('CronogramContent', { read: ElementRef })
|
|
15
|
-
children!: QueryList<ElementRef>;
|
|
16
|
-
items = [
|
|
17
|
-
{ date: 2000, content: 'Lorem ipsum dolor sit amet', image: 'lorem' },
|
|
18
|
-
{ date: 2001, content: 'Lorem ipsum dolor sit amet', image: 'lorem' },
|
|
19
|
-
{ date: 2002, content: 'Lorem ipsum dolor sit amet', image: 'lorem' }
|
|
20
|
-
]
|
|
21
|
-
|
|
22
|
-
positionsY: number[] = []
|
|
23
|
-
|
|
24
|
-
ngAfterViewInit() {
|
|
25
|
-
this.positionsY = this.children.map(i => i.nativeElement.getBoundingClientRect().y)
|
|
26
|
-
|
|
27
|
-
this.line.nativeElement.style.maxHeight = `${this.wrapper.nativeElement.getBoundingClientRect().height}px`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
lastScrollY = window.scrollY;
|
|
31
|
-
|
|
32
|
-
@HostListener('window:scroll', [])
|
|
33
|
-
onScroll() {
|
|
34
|
-
const scrollPosition = window.scrollY;
|
|
35
|
-
|
|
36
|
-
if (scrollPosition > this.lastScrollY) {
|
|
37
|
-
this.onScrollDown(scrollPosition);
|
|
38
|
-
} else if (scrollPosition < this.lastScrollY) {
|
|
39
|
-
this.onScrollUp(scrollPosition);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
this.lastScrollY = scrollPosition;
|
|
43
|
-
|
|
44
|
-
this.line.nativeElement.style.height = `${this.visibleHeight(this.wrapper.nativeElement)}px`
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
onScrollDown(scrollPosition: number) {
|
|
49
|
-
let index = this.positionsY.findIndex(pos => pos > scrollPosition - 100);
|
|
50
|
-
|
|
51
|
-
if (index === -1) {
|
|
52
|
-
index = this.positionsY.length;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
this.children.forEach((child, i) => {
|
|
56
|
-
const el = child.nativeElement as HTMLElement;
|
|
57
|
-
|
|
58
|
-
if (i < index) {
|
|
59
|
-
el.classList.remove("hidden");
|
|
60
|
-
el.classList.add("visible");
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
this.line.nativeElement.style.transition = 'height 1.2s';
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
onScrollUp(scrollPosition: number) {
|
|
68
|
-
let index = this.positionsY.findIndex(pos => pos > scrollPosition - 50);
|
|
69
|
-
|
|
70
|
-
if (index === -1) {
|
|
71
|
-
index = this.positionsY.length;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
this.children.forEach((child, i) => {
|
|
75
|
-
const el = child.nativeElement as HTMLElement;
|
|
76
|
-
|
|
77
|
-
if (i >= index) {
|
|
78
|
-
el.classList.add("hidden");
|
|
79
|
-
el.classList.remove("visible");
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
this.line.nativeElement.style.transition = 'height 0s';
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
visibleHeight(el: HTMLElement) {
|
|
90
|
-
const rect = el.getBoundingClientRect();
|
|
91
|
-
const viewportHeight = window.innerHeight;
|
|
92
|
-
|
|
93
|
-
const topVisible = Math.max(rect.top, 0);
|
|
94
|
-
const bottomVisible = Math.min(rect.bottom, viewportHeight);
|
|
95
|
-
|
|
96
|
-
return Math.max(0, bottomVisible - topVisible);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
:host {
|
|
2
|
-
--anim-speed: 300ms;
|
|
3
|
-
/* VARIABLE DE VELOCITAT */
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.stack-container {
|
|
7
|
-
position: relative;
|
|
8
|
-
width: 400px;
|
|
9
|
-
height: 400px;
|
|
10
|
-
cursor: pointer;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.stack-image {
|
|
14
|
-
position: absolute;
|
|
15
|
-
width: 200px;
|
|
16
|
-
height: 200px;
|
|
17
|
-
object-fit: cover;
|
|
18
|
-
transition:
|
|
19
|
-
transform var(--anim-speed) ease,
|
|
20
|
-
opacity var(--anim-speed) ease;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.stack-image.move-out {
|
|
24
|
-
transform: translate(200px, 0px) !important;
|
|
25
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { StackCaroussel } from './stack-caroussel';
|
|
4
|
-
|
|
5
|
-
describe('StackCaroussel', () => {
|
|
6
|
-
let component: StackCaroussel;
|
|
7
|
-
let fixture: ComponentFixture<StackCaroussel>;
|
|
8
|
-
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
await TestBed.configureTestingModule({
|
|
11
|
-
imports: [StackCaroussel]
|
|
12
|
-
})
|
|
13
|
-
.compileComponents();
|
|
14
|
-
|
|
15
|
-
fixture = TestBed.createComponent(StackCaroussel);
|
|
16
|
-
component = fixture.componentInstance;
|
|
17
|
-
await fixture.whenStable();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should create', () => {
|
|
21
|
-
expect(component).toBeTruthy();
|
|
22
|
-
});
|
|
23
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { CommonModule } from '@angular/common';
|
|
2
|
-
import { Component, Input } from '@angular/core';
|
|
3
|
-
|
|
4
|
-
@Component({
|
|
5
|
-
selector: 'ard-stack-caroussel',
|
|
6
|
-
imports: [CommonModule],
|
|
7
|
-
templateUrl: './stack-caroussel.html',
|
|
8
|
-
styleUrl: './stack-caroussel.css',
|
|
9
|
-
})
|
|
10
|
-
export class StackCaroussel {
|
|
11
|
-
@Input() images: string[] = [];
|
|
12
|
-
@Input() atmospheric = false;
|
|
13
|
-
|
|
14
|
-
animating = false;
|
|
15
|
-
|
|
16
|
-
getOffset(index: number) {
|
|
17
|
-
return {
|
|
18
|
-
transform: `translate(${index * 16}px, ${index * 16}px)`,
|
|
19
|
-
zIndex: this.images.length - index,
|
|
20
|
-
opacity: this.atmospheric
|
|
21
|
-
? 1 - (this.images.length - index * 0.08)
|
|
22
|
-
: 1
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
rotateStack() {
|
|
27
|
-
if (this.animating || this.images.length === 0) return;
|
|
28
|
-
|
|
29
|
-
this.animating = true;
|
|
30
|
-
|
|
31
|
-
const last = this.images[this.images.length - 1];
|
|
32
|
-
const rest = this.images.slice(0, this.images.length - 1);
|
|
33
|
-
|
|
34
|
-
// Fase 1
|
|
35
|
-
const el = document.querySelector('.img-last') as HTMLElement;
|
|
36
|
-
if (el) {
|
|
37
|
-
el.classList.add('move-out');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
setTimeout(() => {
|
|
41
|
-
// Reordenem array
|
|
42
|
-
this.images = [last, ...rest];
|
|
43
|
-
|
|
44
|
-
setTimeout(() => {
|
|
45
|
-
this.animating = false;
|
|
46
|
-
}, 50);
|
|
47
|
-
|
|
48
|
-
}, 300);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
ul {
|
|
2
|
-
list-style-type: none;
|
|
3
|
-
display: flex;
|
|
4
|
-
margin: 0;
|
|
5
|
-
padding: 0;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
a {
|
|
9
|
-
color: var(--menu-text);
|
|
10
|
-
text-decoration: none;
|
|
11
|
-
font-weight: 400;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
a:hover {
|
|
15
|
-
text-decoration: underline;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
button {
|
|
19
|
-
display: flex;
|
|
20
|
-
justify-self: end;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
li::after {
|
|
24
|
-
content: '';
|
|
25
|
-
margin-left: 1rem;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
#menu-container {
|
|
29
|
-
width: 100%;
|
|
30
|
-
height: 100%;
|
|
31
|
-
overflow: hidden;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
:host {
|
|
35
|
-
width: 100%;
|
|
36
|
-
overflow: hidden;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
#dropdown {
|
|
40
|
-
li {
|
|
41
|
-
list-style-type: none;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
;
|
|
45
|
-
background: white;
|
|
46
|
-
border-radius: 1rem;
|
|
47
|
-
border: 1px solid black;
|
|
48
|
-
padding: 1rem;
|
|
49
|
-
margin: 0 1rem;
|
|
50
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
<div #menuContainer id="menu-container">
|
|
2
|
-
@if(!collapsed) {
|
|
3
|
-
<ul #unorderedList [style.flexFlow]="direction == 'horizontal' ? 'row' : 'column'"
|
|
4
|
-
[style.justifySelf]="justifySelf">
|
|
5
|
-
@for (i of menu; track i.label) {
|
|
6
|
-
<li><a [href]="i.path">{{i.label}}</a></li>
|
|
7
|
-
}
|
|
8
|
-
</ul>
|
|
9
|
-
} @else {
|
|
10
|
-
<button #overlayTrigger [style.justifySelf]="justifySelf" (click)="toggleMenu()">Menu</button>
|
|
11
|
-
|
|
12
|
-
<ng-template #menuOverlay>
|
|
13
|
-
<div id="dropdown">
|
|
14
|
-
@for (i of menu; track i.label) {
|
|
15
|
-
<li><a [href]="i.path">{{i.label}}</a></li>
|
|
16
|
-
}
|
|
17
|
-
</div>
|
|
18
|
-
</ng-template>
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
</div>
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { Inject, Component, ElementRef, HostListener, Input, ViewChild, AfterViewInit, ChangeDetectorRef, inject, TemplateRef, ViewContainerRef } from '@angular/core';
|
|
2
|
-
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
|
3
|
-
import { TemplatePortal } from '@angular/cdk/portal';
|
|
4
|
-
@Component({
|
|
5
|
-
selector: 'ard-menu',
|
|
6
|
-
templateUrl: './menu.component.html',
|
|
7
|
-
styleUrl: './menu.component.css',
|
|
8
|
-
})
|
|
9
|
-
export class MenuComponent implements AfterViewInit {
|
|
10
|
-
|
|
11
|
-
@Input() justifySelf: 'center' | 'end' | 'start' = 'end';
|
|
12
|
-
@Input() menu?: {
|
|
13
|
-
path: string;
|
|
14
|
-
label: string;
|
|
15
|
-
}[] = [
|
|
16
|
-
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
@Input() direction: 'horizontal' | 'vertical' = 'horizontal';
|
|
20
|
-
|
|
21
|
-
@ViewChild('menuContainer') menuContainer!: ElementRef<HTMLElement>;
|
|
22
|
-
@ViewChild('unorderedList') unorderedList!: ElementRef<HTMLElement>;
|
|
23
|
-
|
|
24
|
-
constructor(private cdr: ChangeDetectorRef) { }
|
|
25
|
-
|
|
26
|
-
collapsed = false;
|
|
27
|
-
listWidth = 0;
|
|
28
|
-
|
|
29
|
-
ngAfterViewInit() {
|
|
30
|
-
setTimeout(() => {
|
|
31
|
-
this.getWidth();
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
@HostListener('window:resize')
|
|
36
|
-
getWidth() {
|
|
37
|
-
const containerWidth =
|
|
38
|
-
this.menuContainer.nativeElement.getBoundingClientRect().width;
|
|
39
|
-
|
|
40
|
-
if (!this.collapsed) this.listWidth = this.unorderedList?.nativeElement?.scrollWidth;
|
|
41
|
-
|
|
42
|
-
this.collapsed = containerWidth < this.listWidth;
|
|
43
|
-
this.cdr.detectChanges();
|
|
44
|
-
console.log(containerWidth, this.listWidth, this.collapsed)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
//#region overlay
|
|
49
|
-
private overlay = inject(Overlay);
|
|
50
|
-
private overlayRef?: OverlayRef;
|
|
51
|
-
|
|
52
|
-
@ViewChild('menuOverlay') menuOverlay!: TemplateRef<any>; // Template del menú
|
|
53
|
-
@ViewChild('overlayTrigger', { read: ElementRef }) trigger!: ElementRef; // Botó
|
|
54
|
-
|
|
55
|
-
toggleMenu() {
|
|
56
|
-
console.log('toggleMenu');
|
|
57
|
-
this.overlayRef ? this.closeMenu() : this.openMenu();
|
|
58
|
-
}
|
|
59
|
-
private viewContainerRef = inject(ViewContainerRef);
|
|
60
|
-
|
|
61
|
-
openMenu() {
|
|
62
|
-
const positionStrategy = this.overlay
|
|
63
|
-
.position()
|
|
64
|
-
.flexibleConnectedTo(this.trigger)
|
|
65
|
-
.withPositions([
|
|
66
|
-
{
|
|
67
|
-
originX: 'start',
|
|
68
|
-
originY: 'bottom',
|
|
69
|
-
overlayX: 'start',
|
|
70
|
-
overlayY: 'top'
|
|
71
|
-
}
|
|
72
|
-
]);
|
|
73
|
-
|
|
74
|
-
this.overlayRef = this.overlay.create({
|
|
75
|
-
positionStrategy,
|
|
76
|
-
hasBackdrop: true,
|
|
77
|
-
backdropClass: 'cdk-overlay-transparent-backdrop',
|
|
78
|
-
scrollStrategy: this.overlay.scrollStrategies.reposition()
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
this.overlayRef.backdropClick().subscribe(() => this.closeMenu());
|
|
82
|
-
|
|
83
|
-
const portal = new TemplatePortal(this.menuOverlay, this.viewContainerRef); // ✅ SI
|
|
84
|
-
this.overlayRef.attach(portal);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
closeMenu() {
|
|
88
|
-
this.overlayRef?.dispose();
|
|
89
|
-
this.overlayRef = undefined;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
action(value: string) {
|
|
93
|
-
console.log(value);
|
|
94
|
-
this.closeMenu();
|
|
95
|
-
}
|
|
96
|
-
//#endregion overlay
|
|
97
|
-
|
|
98
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { MenuComponent } from './menu.component';
|
|
4
|
-
|
|
5
|
-
describe('MenuComponent', () => {
|
|
6
|
-
let component: MenuComponent;
|
|
7
|
-
let fixture: ComponentFixture<MenuComponent>;
|
|
8
|
-
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
await TestBed.configureTestingModule({
|
|
11
|
-
imports: [MenuComponent]
|
|
12
|
-
})
|
|
13
|
-
.compileComponents();
|
|
14
|
-
|
|
15
|
-
fixture = TestBed.createComponent(MenuComponent);
|
|
16
|
-
component = fixture.componentInstance;
|
|
17
|
-
await fixture.whenStable();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should create', () => {
|
|
21
|
-
expect(component).toBeTruthy();
|
|
22
|
-
});
|
|
23
|
-
});
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
:host {
|
|
2
|
-
width: 100%
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
#nav-container {
|
|
6
|
-
height: 0;
|
|
7
|
-
position: sticky;
|
|
8
|
-
top: 0;
|
|
9
|
-
will-change: transform, opacity;
|
|
10
|
-
|
|
11
|
-
nav {
|
|
12
|
-
will-change: transform, opacity;
|
|
13
|
-
position: relative;
|
|
14
|
-
bottom: 0;
|
|
15
|
-
will-change: transform;
|
|
16
|
-
display: flex;
|
|
17
|
-
flex-flow: column;
|
|
18
|
-
justify-content: end;
|
|
19
|
-
align-items: center;
|
|
20
|
-
border-bottom: 1px solid grey;
|
|
21
|
-
|
|
22
|
-
#nav-content {
|
|
23
|
-
will-change: transform, opacity;
|
|
24
|
-
min-height: fit-content;
|
|
25
|
-
display: flex;
|
|
26
|
-
width: 100%;
|
|
27
|
-
justify-content: center;
|
|
28
|
-
align-items: center;
|
|
29
|
-
flex: 1;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.nav_sticky--onScroll {}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
<div id="nav-container" style="z-index: 1">
|
|
2
|
-
<nav #nav [style.height]="navHeight" [style.minHeight]="sticky ? 'fit-content' : 0 "
|
|
3
|
-
[ngClass]="`nav_sticky--` + sticky">
|
|
4
|
-
<div #navContent id="nav-content">
|
|
5
|
-
<ng-content></ng-content>
|
|
6
|
-
</div>
|
|
7
|
-
</nav>
|
|
8
|
-
</div>
|
|
9
|
-
<div #navFiller id="nav-filler" [style.height]="navHeight">
|
|
10
|
-
</div>
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { NavbarComponent } from './navbar.component';
|
|
4
|
-
|
|
5
|
-
describe('Navbar', () => {
|
|
6
|
-
let component: NavbarComponent;
|
|
7
|
-
let fixture: ComponentFixture<NavbarComponent>;
|
|
8
|
-
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
await TestBed.configureTestingModule({
|
|
11
|
-
imports: [NavbarComponent]
|
|
12
|
-
})
|
|
13
|
-
.compileComponents();
|
|
14
|
-
|
|
15
|
-
fixture = TestBed.createComponent(NavbarComponent);
|
|
16
|
-
component = fixture.componentInstance;
|
|
17
|
-
await fixture.whenStable();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should create', () => {
|
|
21
|
-
expect(component).toBeTruthy();
|
|
22
|
-
});
|
|
23
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { NgClass } from '@angular/common';
|
|
2
|
-
import { Component, ElementRef, HostListener, Input, ViewChild } from '@angular/core';
|
|
3
|
-
|
|
4
|
-
@Component({
|
|
5
|
-
selector: 'ard-navbar',
|
|
6
|
-
imports: [NgClass],
|
|
7
|
-
templateUrl: './navbar.component.html',
|
|
8
|
-
styleUrl: './navbar.component.css',
|
|
9
|
-
standalone: true,
|
|
10
|
-
})
|
|
11
|
-
export class NavbarComponent {
|
|
12
|
-
@ViewChild('nav') nav!: ElementRef<HTMLElement>;
|
|
13
|
-
@ViewChild('navFiller') navFiller!: ElementRef<HTMLElement>;
|
|
14
|
-
@ViewChild('navContent') navContent!: ElementRef<HTMLElement>;
|
|
15
|
-
|
|
16
|
-
@Input() onScrollCallback?: (ratio: number) => void;
|
|
17
|
-
@Input() type: 'hero' | 'regular' = 'regular'
|
|
18
|
-
@Input() sticky: boolean | 'onScrollUp' = true;
|
|
19
|
-
@Input() navHeight: CSSStyleDeclaration["height"] = '100vhh'
|
|
20
|
-
|
|
21
|
-
private lastScrollY: number = 0;
|
|
22
|
-
private initialNavHeight!: number;
|
|
23
|
-
|
|
24
|
-
ngAfterViewInit() {
|
|
25
|
-
this.initialNavHeight = this.navFiller.nativeElement.offsetHeight
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@HostListener('window:scroll', [])
|
|
29
|
-
onScroll() {
|
|
30
|
-
|
|
31
|
-
if (this.type == 'hero') this.nav!.nativeElement.style.height = `calc(${this.navHeight} - ${window.scrollY}px)`;
|
|
32
|
-
|
|
33
|
-
if (this.sticky == 'onScrollUp') {
|
|
34
|
-
this.nav.nativeElement.style.minHeight = window.scrollY < this.lastScrollY
|
|
35
|
-
? this.navContent.nativeElement.clientHeight + 'px'
|
|
36
|
-
: '0px';
|
|
37
|
-
this.lastScrollY = window.scrollY
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
let navScrollRatio = window.scrollY / (this.initialNavHeight - 100); //100: alçada temptativa del navbar
|
|
41
|
-
navScrollRatio > 1 - this.nav.nativeElement.offsetHeight ? this.nav.nativeElement.style.transition = 'min-height 0.3s ease' : this.nav.nativeElement.style.transition = 'min-height 0s ease';
|
|
42
|
-
|
|
43
|
-
if (this.onScrollCallback) this.onScrollCallback(navScrollRatio);
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
}
|