diff --git a/projects/up-window-angular/src/lib/up-window-angular.component.html b/projects/up-window-angular/src/lib/up-window-angular.component.html
index 2b5519a..39ae8ae 100644
--- a/projects/up-window-angular/src/lib/up-window-angular.component.html
+++ b/projects/up-window-angular/src/lib/up-window-angular.component.html
@@ -39,22 +39,25 @@
@if(!hiddenActions) {
}
diff --git a/projects/up-window-angular/src/lib/up-window-angular.component.ts b/projects/up-window-angular/src/lib/up-window-angular.component.ts
index f3bbb21..35cf918 100644
--- a/projects/up-window-angular/src/lib/up-window-angular.component.ts
+++ b/projects/up-window-angular/src/lib/up-window-angular.component.ts
@@ -11,6 +11,7 @@ import {
ElementRef,
ViewChild,
effect,
+ ChangeDetectorRef,
} from '@angular/core';
@Component({
@@ -55,7 +56,7 @@ export class UpWindowAngularComponent implements OnInit, OnDestroy {
@ViewChild('modal') modal!: ElementRef;
- constructor() {
+ constructor(private cdr: ChangeDetectorRef) {
effect(() => {
if (this.isOpen()) {
this.addModalToBody();
@@ -86,6 +87,7 @@ export class UpWindowAngularComponent implements OnInit, OnDestroy {
this.focusableElements[this.focusableElements.length - 1];
}
}
+ this.cdr.detectChanges();
}
addModalToBody() {
@@ -137,6 +139,11 @@ export class UpWindowAngularComponent implements OnInit, OnDestroy {
document.removeEventListener('keydown', this.handleKeydown.bind(this));
}
+ hasFooterContent(): boolean {
+ const footerContent = this.modal?.nativeElement.querySelector('[footer]');
+ return !!footerContent && footerContent.childNodes.length > 0;
+ }
+
startOpeningAnimation() {
this.openingAnimation = true;
setTimeout(() => {
diff --git a/projects/up-window-angular/src/lib/up-window-angular.custom-footer.spec.ts b/projects/up-window-angular/src/lib/up-window-angular.custom-footer.spec.ts
new file mode 100644
index 0000000..9cffcd6
--- /dev/null
+++ b/projects/up-window-angular/src/lib/up-window-angular.custom-footer.spec.ts
@@ -0,0 +1,69 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { UpWindowAngularComponent } from './up-window-angular.component';
+import { By } from '@angular/platform-browser';
+import { Component, signal, WritableSignal } from '@angular/core';
+
+@Component({
+ template: `
+
+
+
+
+ Close
+
+
+
+ `,
+})
+class HostComponentWithCustomFooter {
+ isWindowOpenFooter: WritableSignal = signal(true);
+}
+
+describe('UpWindowAngularComponent HostComponentWithCustomFooter', () => {
+ let fixture: ComponentFixture;
+ let component: HostComponentWithCustomFooter;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [UpWindowAngularComponent, HostComponentWithCustomFooter],
+ }).compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HostComponentWithCustomFooter);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should not render default footer buttons when custom footer is provided', () => {
+ const confirmButton = fixture.debugElement.query(By.css('.btn-confirm'));
+ const cancelButton = fixture.debugElement.query(By.css('.btn-cancel'));
+
+ expect(confirmButton).toBeNull();
+ expect(cancelButton).toBeNull();
+ });
+
+ it('should render custom footer content when ng-content is used', () => {
+ fixture.detectChanges();
+
+ const footerTemplate = fixture.debugElement.query(
+ By.css('.up-window-footer')
+ );
+ expect(footerTemplate).toBeTruthy();
+
+ const projectedFooter = footerTemplate.query(By.css('.custom-footer'));
+ console.log('projectedFooter', projectedFooter);
+
+ expect(projectedFooter).toBeTruthy();
+ expect(projectedFooter.nativeElement.textContent).toContain(
+ 'Custom Footer Content'
+ );
+ });
+});
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 192eca3..3fd0af7 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -28,6 +28,7 @@
+
diff --git a/src/app/examples/actions/actions.component.html b/src/app/examples/actions/actions.component.html
index 84842ab..e3e75cb 100644
--- a/src/app/examples/actions/actions.component.html
+++ b/src/app/examples/actions/actions.component.html
@@ -1 +1,34 @@
-actions works!
+
+
Actions
+
+
+ Custom Footer
+
+
+
+
+ This window features a custom footer that provides tailored actions for
+ your convenience. You can use the buttons below to either close the
+ window or perform the designated action as per your requirement.
+
+
+
+ Close
+
+
+ Perform Action
+
+ Custom footer example text.
+
+
+
+
diff --git a/src/app/examples/actions/actions.component.scss b/src/app/examples/actions/actions.component.scss
index e69de29..7b75c25 100644
--- a/src/app/examples/actions/actions.component.scss
+++ b/src/app/examples/actions/actions.component.scss
@@ -0,0 +1,34 @@
+$close-color: #dc3545;
+$close-hover-color: #c82333;
+$confirm-color: #007bff;
+$confirm-hover-color: #0056b3;
+
+.custom-btn {
+ padding: 8px 12px;
+ margin: 5px;
+ cursor: pointer;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ transition: background-color 0.3s;
+
+ &.close {
+ background-color: $close-color;
+
+ &:hover {
+ background-color: $close-hover-color;
+ }
+ }
+
+ &.confirm {
+ background-color: $confirm-color;
+
+ &:hover {
+ background-color: $confirm-hover-color;
+ }
+ }
+
+ &:hover {
+ opacity: 0.9;
+ }
+}
diff --git a/src/app/examples/actions/actions.component.ts b/src/app/examples/actions/actions.component.ts
index e00855d..3dae8c5 100644
--- a/src/app/examples/actions/actions.component.ts
+++ b/src/app/examples/actions/actions.component.ts
@@ -1,12 +1,22 @@
-import { Component } from '@angular/core';
+import { Component, signal, WritableSignal } from '@angular/core';
+import { UpWindowAngularModule } from '../../../../projects/up-window-angular/src/public-api';
@Component({
selector: 'examples-actions',
standalone: true,
- imports: [],
+ imports: [UpWindowAngularModule],
templateUrl: './actions.component.html',
styleUrl: './actions.component.scss'
})
export class ActionsComponent {
+ isWindowOpenFooter: WritableSignal = signal(false);
+ openWindowExample(type: string) {
+ this.isWindowOpenFooter.set(false);
+ switch (type) {
+ case 'footer':
+ this.isWindowOpenFooter.set(true);
+ break;
+ }
+ }
}