Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(window): add window buttons configuration #2762

Merged
merged 16 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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