diff --git a/README.md b/README.md index 5025c9d..d9c8d51 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # up-window-angular -An Angular library designed to create dynamic, customizable windows and window-based components for web applications. With a simple and intuitive API, UpWindow enables developers to easily integrate responsive windows, popups, and floating windows into their projects. It provides full control over window size, position, animations, and behavior, offering a flexible solution for creating engaging user interfaces. +An Angular library designed to create dynamic, customizable windows and window-based components for web applications. With a simple and intuitive API, UpWindow enables developers to easily integrate responsive windows, popups, floating windows, and drawers into their projects. It provides full control over window size, position, animations, and behavior, offering a flexible solution for creating engaging user interfaces. ## Install @@ -93,6 +93,12 @@ export class WindowExampleComponent { ``` +- **`@Input() drawer: 'left' | 'right' | 'top' | 'bottom' = 'left';`** + - Example: Set the position of the drawer when in drawer mode. + ```html + + ``` + - **`@Input() confirmText: string = 'Confirm';`** - Example: Customize the confirm button text. ```html diff --git a/projects/up-window-angular/README.md b/projects/up-window-angular/README.md index 5025c9d..d9c8d51 100644 --- a/projects/up-window-angular/README.md +++ b/projects/up-window-angular/README.md @@ -1,6 +1,6 @@ # up-window-angular -An Angular library designed to create dynamic, customizable windows and window-based components for web applications. With a simple and intuitive API, UpWindow enables developers to easily integrate responsive windows, popups, and floating windows into their projects. It provides full control over window size, position, animations, and behavior, offering a flexible solution for creating engaging user interfaces. +An Angular library designed to create dynamic, customizable windows and window-based components for web applications. With a simple and intuitive API, UpWindow enables developers to easily integrate responsive windows, popups, floating windows, and drawers into their projects. It provides full control over window size, position, animations, and behavior, offering a flexible solution for creating engaging user interfaces. ## Install @@ -93,6 +93,12 @@ export class WindowExampleComponent { ``` +- **`@Input() drawer: 'left' | 'right' | 'top' | 'bottom' = 'left';`** + - Example: Set the position of the drawer when in drawer mode. + ```html + + ``` + - **`@Input() confirmText: string = 'Confirm';`** - Example: Customize the confirm button text. ```html diff --git a/projects/up-window-angular/src/lib/tests/mode.spec.ts b/projects/up-window-angular/src/lib/tests/mode.spec.ts index d46bf6d..0348a7e 100644 --- a/projects/up-window-angular/src/lib/tests/mode.spec.ts +++ b/projects/up-window-angular/src/lib/tests/mode.spec.ts @@ -97,4 +97,57 @@ describe('UpWindowAngularComponent', () => { const overlayElement = fixture.debugElement.query(By.css('.overlay')); expect(overlayElement.classes['grayscale']).toBeFalsy(); }); + + it('should open drawer from the left', () => { + component.drawer = 'left'; + component.isOpen.set(true); + fixture.detectChanges(); + + const windowElement = fixture.debugElement.query(By.css('.up-window')); + expect(windowElement.classes['drawer-left']).toBeTrue(); + expect(component.isOpen()).toBeTrue(); + }); + + it('should open drawer from the right', () => { + component.drawer = 'right'; + component.isOpen.set(true); + fixture.detectChanges(); + + const windowElement = fixture.debugElement.query(By.css('.up-window')); + expect(windowElement.classes['drawer-right']).toBeTrue(); + expect(component.isOpen()).toBeTrue(); + }); + + it('should open drawer from the top', () => { + component.drawer = 'top'; + component.isOpen.set(true); + fixture.detectChanges(); + + const windowElement = fixture.debugElement.query(By.css('.up-window')); + expect(windowElement.classes['drawer-top']).toBeTrue(); + expect(component.isOpen()).toBeTrue(); + }); + + it('should open drawer from the bottom', () => { + component.drawer = 'bottom'; + component.isOpen.set(true); + fixture.detectChanges(); + + const windowElement = fixture.debugElement.query(By.css('.up-window')); + expect(windowElement.classes['drawer-bottom']).toBeTrue(); + expect(component.isOpen()).toBeTrue(); + }); + + it('should close drawer when isOpenDrawerLeft is set to false', fakeAsync(() => { + component.drawer = 'left'; + component.isOpen.set(true); + fixture.detectChanges(); + expect(component.isOpen()).toBeTrue(); + + component.isOpen.set(false); + tick(600); + fixture.detectChanges(); + + expect(component.isOpen()).toBeFalse(); + })); }); diff --git a/projects/up-window-angular/src/lib/up-window-angular.component.scss b/projects/up-window-angular/src/lib/up-window-angular.component.scss index 838d49e..e0be48c 100644 --- a/projects/up-window-angular/src/lib/up-window-angular.component.scss +++ b/projects/up-window-angular/src/lib/up-window-angular.component.scss @@ -82,6 +82,35 @@ margin-top: auto; } } + + &.drawer { + position: fixed; + z-index: 1000; + } + + &.drawer-bottom { + bottom: 0; + border-radius: 1rem 1rem 0 0; + margin: 1rem 1rem 0 0; + } + + &.drawer-top { + top: 0; + border-radius: 0 0 1rem 1rem; + margin: 0 1rem; + } + + &.drawer-left { + left: 0; + border-radius: 0 1rem 1rem 0; + margin: 1rem 1rem 1rem 0; + } + + &.drawer-right { + right: 0; + border-radius: 1rem 0 0 1rem; + margin: 1rem 0 1rem 1rem; + } } .up-window-header { 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 35cf918..73a3033 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 @@ -30,7 +30,8 @@ export class UpWindowAngularComponent implements OnInit, OnDestroy { @Input() subtitle?: string; @Input() class: string | undefined; @Input() isOpen: WritableSignal = signal(false); - @Input() animation: string = 'fade'; + @Input() drawer: 'bottom' | 'top' | 'left' | 'right' | '' = ''; + @Input() animation: string = this.drawer ? this.drawer : 'fade'; @Input() restrictMode: boolean = false; @Input() fullScreen: boolean = false; @Input() blur: boolean = false; @@ -176,6 +177,7 @@ export class UpWindowAngularComponent implements OnInit, OnDestroy { ...(this.class ? { [this.class]: true } : {}), [this.animation]: this.openingAnimation && !this.closingAnimation, [`${this.animation}-out`]: this.closingAnimation, + [`drawer drawer-${this.drawer}`]: !!this.drawer, shake: this.shakeAnimation, fullscreen: this.fullScreen, blur: this.blur, diff --git a/src/app/examples/mode/mode.component.html b/src/app/examples/mode/mode.component.html index bfd64a5..82fa2e2 100644 --- a/src/app/examples/mode/mode.component.html +++ b/src/app/examples/mode/mode.component.html @@ -162,3 +162,84 @@

Additional Tips for Fullscreen Mode

+ +
+

Drawer

+
+ + + + + + + + + + Content for top drawer! + + + + Content for bottom drawer! + + + + Content for left drawer! + + + + Content for right drawer! + +
+
diff --git a/src/app/examples/mode/mode.component.ts b/src/app/examples/mode/mode.component.ts index 0627667..7de5c75 100644 --- a/src/app/examples/mode/mode.component.ts +++ b/src/app/examples/mode/mode.component.ts @@ -14,6 +14,12 @@ export class ModeComponent { isWindowOpenBlur: WritableSignal = signal(false); isWindowOpenGrayscale: WritableSignal = signal(false); isWindowOpenBlurGrayscale: WritableSignal = signal(false); + isWindowOpenDrawerBottom: WritableSignal = signal(false); + isWindowOpenDrawerTop: WritableSignal = signal(false); + isWindowOpenDrawerLeft: WritableSignal = signal(false); + isWindowOpenDrawerRight: WritableSignal = signal(false); + drawerPosition: 'bottom' | 'top' | 'left' | 'right' = 'bottom'; + openWindowExample(type: string) { this.isWindowOpenRestrict.set(false); @@ -21,6 +27,10 @@ export class ModeComponent { this.isWindowOpenBlur.set(false); this.isWindowOpenGrayscale.set(false); this.isWindowOpenBlurGrayscale.set(false); + this.isWindowOpenDrawerBottom.set(false); + this.isWindowOpenDrawerTop.set(false); + this.isWindowOpenDrawerLeft.set(false); + this.isWindowOpenDrawerRight.set(false); switch (type) { case 'restrict': @@ -38,6 +48,22 @@ export class ModeComponent { case 'blurGrayscale': this.isWindowOpenBlurGrayscale.set(true); break; + case 'drawer-left': + this.drawerPosition = 'left'; + this.isWindowOpenDrawerLeft.set(true); + break; + case 'drawer-right': + this.drawerPosition = 'right'; + this.isWindowOpenDrawerRight.set(true); + break; + case 'drawer-top': + this.drawerPosition = 'top'; + this.isWindowOpenDrawerTop.set(true); + break; + case 'drawer-bottom': + this.drawerPosition = 'bottom'; + this.isWindowOpenDrawerBottom.set(true); + break; } } }