Skip to content

Commit

Permalink
feat(window): add window buttons configuration (#2762)
Browse files Browse the repository at this point in the history
  • Loading branch information
andreipadolin authored Jun 16, 2021
1 parent bcf7b65 commit 9dcd40e
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 12 deletions.
6 changes: 6 additions & 0 deletions src/app/playground-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,12 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [
component: 'WindowsBackdropComponent',
name: 'Windows Backdrop',
},
{
path: 'window-controls.component',
link: '/window/window-controls.component',
component: 'WindowControlsComponent',
name: 'Window Controls',
},
],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
.buttons {
width: 9.5rem;
display: flex;
justify-content: space-evenly;
justify-content: flex-end;

[nbButton] {
flex: 0 0 3rem;
Expand Down
41 changes: 31 additions & 10 deletions src/framework/theme/components/window/window.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,24 @@ import { NbWindowRef } from './window-ref';
<div cdkFocusInitial class="title" tabindex="-1">{{ config.title }}</div>
<div class="buttons">
<button nbButton ghost (click)="minimize()">
<nb-icon icon="minus-outline" pack="nebular-essentials"></nb-icon>
</button>
<button nbButton ghost *ngIf="isFullScreen" (click)="maximize()">
<nb-icon icon="collapse-outline" pack="nebular-essentials"></nb-icon>
</button>
<button nbButton ghost *ngIf="minimized || maximized" (click)="maximizeOrFullScreen()">
<nb-icon icon="expand-outline" pack="nebular-essentials"></nb-icon>
</button>
<ng-container *ngIf="showMinimize">
<button nbButton ghost (click)="minimize()">
<nb-icon icon="minus-outline" pack="nebular-essentials"></nb-icon>
</button>
</ng-container>
<ng-container *ngIf="showMaximize">
<button nbButton ghost *ngIf="isFullScreen" (click)="maximize()">
<nb-icon icon="collapse-outline" pack="nebular-essentials"></nb-icon>
</button>
</ng-container>
<ng-container *ngIf="showFullScreen">
<button nbButton ghost *ngIf="minimized || maximized" (click)="maximizeOrFullScreen()">
<nb-icon icon="expand-outline" pack="nebular-essentials"></nb-icon>
</button>
</ng-container>
<button nbButton ghost (click)="close()">
<nb-icon icon="close-outline" pack="nebular-essentials"></nb-icon>
</button>
Expand Down Expand Up @@ -66,6 +75,18 @@ export class NbWindowComponent implements OnInit, AfterViewChecked, OnDestroy {
return this.windowRef.state === NbWindowState.MINIMIZED;
}

get showMinimize(): boolean {
return this.config.buttons.minimize;
}

get showMaximize(): boolean {
return this.config.buttons.maximize;
}

get showFullScreen(): boolean {
return this.config.buttons.fullScreen;
}

@ViewChild(NbOverlayContainerComponent) overlayContainer: NbOverlayContainerComponent;

protected focusTrap: NbFocusTrap;
Expand Down Expand Up @@ -127,7 +148,7 @@ export class NbWindowComponent implements OnInit, AfterViewChecked, OnDestroy {
}

maximizeOrFullScreen() {
if (this.windowRef.state === NbWindowState.MINIMIZED) {
if (this.windowRef.state === NbWindowState.MINIMIZED && this.showMaximize) {
this.maximize();
} else {
this.fullScreen();
Expand Down
22 changes: 22 additions & 0 deletions src/framework/theme/components/window/window.options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ export interface NbWindowStateChange {
newState: NbWindowState;
}

export interface NbWindowControlButtonsConfig {
minimize: boolean;
maximize: boolean;
fullScreen: boolean;
}

export const NB_WINDOW_DEFAULT_BUTTONS_CONFIG: NbWindowControlButtonsConfig = {
minimize: true,
maximize: true,
fullScreen: true,
}

/**
* Window configuration options.
*/
Expand Down Expand Up @@ -67,8 +79,18 @@ export class NbWindowConfig {
*/
viewContainerRef: ViewContainerRef = null;

/**
* Windows control buttons can be hidden by setting according property to false.
*/
buttons: Partial<NbWindowControlButtonsConfig> = {};

constructor(...configs: Partial<NbWindowConfig>[]) {
Object.assign(this, ...configs);
this.applyDefaultButtonConfig();
}

protected applyDefaultButtonConfig() {
Object.assign(this, { buttons: { ...NB_WINDOW_DEFAULT_BUTTONS_CONFIG, ...this.buttons } });
}
}

Expand Down
30 changes: 30 additions & 0 deletions src/framework/theme/components/window/window.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
NbOverlayContainerAdapter,
NB_DOCUMENT,
NbThemeModule,
NbWindowControlButtonsConfig,
} from '@nebular/theme';

const WINDOW_CONTENT = 'window content';
Expand Down Expand Up @@ -289,4 +290,33 @@ describe('window-service', () => {
const windowContent = document.getElementById('window-content');
expect(document.body.contains(windowContent)).toEqual(true);
}));

it('should render all control buttons by default', () => {
const windowRef = windowService.open(NbTestWindowComponent);
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: ElementRef<HTMLElement> = windowRef.componentRef.injector.get(ElementRef);
expect(windowElement.nativeElement.querySelectorAll('button').length).toBe(3);
});

it('should render only close button', () => {
const config: NbWindowControlButtonsConfig = { minimize: false, maximize: false, fullScreen: false };
const windowRef = windowService.open(NbTestWindowComponent, { buttons: config});
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: ElementRef<HTMLElement> = windowRef.componentRef.injector.get(ElementRef);
const closeButton = windowElement.nativeElement.querySelectorAll('button')[0];
expect(closeButton.getElementsByTagName('nb-icon')[0].getAttribute('icon')).toBe('close-outline');
});

it('should render minimize and close button', () => {
const config: NbWindowControlButtonsConfig = { minimize: true, maximize: false, fullScreen: false };
const windowRef = windowService.open(NbTestWindowComponent, { buttons: config});
windowRef.maximize();
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: ElementRef<HTMLElement> = windowRef.componentRef.injector.get(ElementRef);
const buttons = Array.from(windowElement.nativeElement.querySelectorAll('button'));
const icons = buttons.map(e => e.getElementsByTagName('nb-icon')[0].getAttribute('icon'));
expect(icons.sort()).toEqual(['minus-outline', 'close-outline'].sort());
});


});
4 changes: 4 additions & 0 deletions src/framework/theme/components/window/window.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ import { NB_DOCUMENT } from '../../theme.options';
* You can read about all available options on [API tab](docs/components/window/api#nbwindowconfig).
*
* @stacked-example(Configuration, window/windows-backdrop.component)
*
* You can configure which buttons are available in a window via the `buttons` property of the window config.
* @stacked-example(Control buttons, window/window-controls.component)
*
*/
@Injectable()
export class NbWindowService {
Expand Down
12 changes: 12 additions & 0 deletions src/playground/with-layout/window/window-controls.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<nb-card>
<nb-card-body>

<p class="subtitle config-title">Buttons config:</p>
<nb-checkbox [(checked)]="minimize">Minimize</nb-checkbox>
<nb-checkbox [(checked)]="maximize">Maximize</nb-checkbox>
<nb-checkbox [(checked)]="fullScreen">Full Screen</nb-checkbox>

<button (click)="openWindow()" nbButton class="open-window">Open window</button>

</nb-card-body>
</nb-card>
12 changes: 12 additions & 0 deletions src/playground/with-layout/window/window-controls.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.config-title {
margin-top: 0;
margin-bottom: 0.25rem;
}

nb-checkbox {
display: block;
}

.open-window {
margin-top: 1rem;
}
28 changes: 28 additions & 0 deletions src/playground/with-layout/window/window-controls.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NbWindowControlButtonsConfig, NbWindowService } from '@nebular/theme';

import { FormComponent } from './components/form.component';

@Component({
templateUrl: 'window-controls.component.html',
styleUrls: ['./window.scss', './window-controls.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class WindowControlsComponent {

minimize = true;
maximize = true;
fullScreen = true;

constructor(private windowService: NbWindowService) { }

openWindow() {
const buttonsConfig: NbWindowControlButtonsConfig = {
minimize: this.minimize,
maximize: this.maximize,
fullScreen: this.fullScreen,
};

this.windowService.open(FormComponent, { title: `Window`, buttons: buttonsConfig });
}
}
5 changes: 5 additions & 0 deletions src/playground/with-layout/window/window-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { RouterModule, Route} from '@angular/router';
import { TemplateWindowComponent } from './template-window.component';
import { WindowShowcaseComponent } from './window-showcase.component';
import { WindowsBackdropComponent } from './windows-backdrop.component';
import { WindowControlsComponent } from './window-controls.component';

const routes: Route[] = [
{
Expand All @@ -23,6 +24,10 @@ const routes: Route[] = [
path: 'windows-backdrop.component',
component: WindowsBackdropComponent,
},
{
path: 'window-controls.component',
component: WindowControlsComponent,
},
];

@NgModule({
Expand Down
7 changes: 6 additions & 1 deletion src/playground/with-layout/window/window.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@
*/

import { NgModule } from '@angular/core';
import { NbButtonModule, NbInputModule, NbWindowModule } from '@nebular/theme';
import { NbButtonModule, NbCardModule, NbCheckboxModule, NbInputModule, NbWindowModule } from '@nebular/theme';

import { WindowRoutingModule } from './window-routing.module';
import { TemplateWindowComponent } from './template-window.component';
import { WindowShowcaseComponent } from './window-showcase.component';
import { WindowsBackdropComponent } from './windows-backdrop.component';
import { FormComponent } from './components/form.component';
import { WindowControlsComponent } from './window-controls.component';

@NgModule({
declarations: [
TemplateWindowComponent,
WindowShowcaseComponent,
WindowsBackdropComponent,
FormComponent,
WindowControlsComponent,
],
imports: [
NbWindowModule.forRoot(),
NbButtonModule,
NbInputModule,
NbCheckboxModule,
NbCardModule,
WindowRoutingModule,
],
entryComponents: [ FormComponent ],
Expand Down

0 comments on commit 9dcd40e

Please sign in to comment.