Skip to content

Commit

Permalink
feat(theme): add new Window component (#713)
Browse files Browse the repository at this point in the history
Closes #669
  • Loading branch information
yggg authored and nnixaa committed Sep 17, 2018
1 parent fc3b2d4 commit 60a65cb
Show file tree
Hide file tree
Showing 25 changed files with 1,052 additions and 0 deletions.
36 changes: 36 additions & 0 deletions docs/assets/images/components/collapsable.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions docs/structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,16 @@ export const structure = [
'NbTooltipComponent',
],
},
{
type: 'tabs',
name: 'Window',
icon: 'collapsable.svg',
source: [
'NbWindowService',
'NbWindowRef',
'NbWindowConfig',
],
},
{
type: 'group',
name: 'Extra',
Expand Down
2 changes: 2 additions & 0 deletions src/framework/theme/components/cdk/adapter/adapter.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { OverlayContainer, ScrollDispatcher } from '@angular/cdk/overlay';
import { NbOverlayContainerAdapter } from './overlay-container-adapter';
import { NbScrollDispatcherAdapter } from './scroll-dispatcher-adapter';
import { NbViewportRulerAdapter } from './viewport-ruler-adapter';
import { NbBlockScrollStrategyAdapter } from './block-scroll-strategy-adapter';


@NgModule({
providers: [
NbViewportRulerAdapter,
NbOverlayContainerAdapter,
NbBlockScrollStrategyAdapter,
{ provide: OverlayContainer, useExisting: NbOverlayContainerAdapter },
{ provide: ScrollDispatcher, useClass: NbScrollDispatcherAdapter },
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Injectable, Inject } from '@angular/core';
import { BlockScrollStrategy } from '@angular/cdk/overlay';
import { NB_DOCUMENT } from '../../../theme.options';
import { NbViewportRulerAdapter } from './viewport-ruler-adapter';

@Injectable()
export class NbBlockScrollStrategyAdapter extends BlockScrollStrategy {
constructor(ruler: NbViewportRulerAdapter, @Inject(NB_DOCUMENT) document) {
super(ruler, document);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@mixin nb-window-theme() {
nb-window-collapse-icon,
nb-window-expand-icon,
nb-window-close-icon,
nb-window-minimize-icon {
svg path {
fill: nb-theme(btn-outline-fg);
}
}
}
4 changes: 4 additions & 0 deletions src/framework/theme/components/window/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './window.module';
export * from './window.service';
export * from './window-ref';
export { NbWindowConfig, NbWindowState, NB_WINDOW_CONFIG, NbWindowStateChange } from './window.options';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
:host {
display: block;

svg {
vertical-align: bottom;
}
}
82 changes: 82 additions & 0 deletions src/framework/theme/components/window/window-icon.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Component, HostBinding } from '@angular/core';

@Component({
selector: 'nb-window-collapse-icon',
template: `
<svg aria-hidden="true" xmlns="http:https://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g fill="#2A2A2A" fill-rule="evenodd">
<path d="M7 17H2v-1h6v6H7v-5z"/>
<path d="M9 15H4v-1h6v6H9v-5zM15 9h5v1h-6V4h1v5z"/>
<path d="M17 7h5v1h-6V2h1v5z"/>
</g>
</svg>
`,
styleUrls: ['./window-icon.component.scss'],
})
export class NbWindowCollapseIconComponent {
@HostBinding('attr.aria-label') label = 'collapse';
}

@Component({
selector: 'nb-window-expand-icon',
template: `
<svg aria-hidden="true" xmlns="http:https://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g fill="#2A2A2A" fill-rule="evenodd">
<path d="M4 20h5v1H3v-6h1v5z"/>
<path d="M6 18h5v1H5v-6h1v5zM18 6h-5V5h6v6h-1V6z"/>
<path d="M20 4h-5V3h6v6h-1V4z"/>
</g>
</svg>
`,
styleUrls: ['./window-icon.component.scss'],
})
export class NbWindowExpandIconComponent {
@HostBinding('attr.aria-label') label = 'expand';
}

@Component({
selector: 'nb-window-close-icon',
template: `
<svg
aria-hidden="true"
xmlns="http:https://www.w3.org/2000/svg"
xmlns:xlink="http:https://www.w3.org/1999/xlink"
viewBox="0 0 24 24">
<defs>
<path id="a" d="M4.1 11.4h15.8v1.2H4.1z" transform="rotate(-45.001 12 12)"/>
</defs>
<clipPath id="b">
<use overflow="visible" xlink:href="#a"/>
</clipPath>
<path fill="#2a2a2a" d="M1 1h22v22H1z" clip-path="url(#b)"/>
<g>
<defs>
<path id="c" d="M11.4 4.1h1.2v15.8h-1.2z" transform="rotate(-45.001 12 12)"/>
</defs>
<clipPath id="d">
<use overflow="visible" xlink:href="#c"/>
</clipPath>
<path fill="#2a2a2a" d="M1 1h22v22H1z" clip-path="url(#d)"/>
</g>
</svg>
`,
styleUrls: ['./window-icon.component.scss'],
})
export class NbWindowCloseIconComponent {
@HostBinding('attr.aria-label') label = 'close';
}

@Component({
selector: 'nb-window-minimize-icon',
template: `
<svg aria-hidden="true" xmlns="http:https://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g fill="#2A2A2A" fill-rule="evenodd">
<path d="M4 22v-1h15v1z"/>
</g>
</svg>
`,
styleUrls: ['./window-icon.component.scss'],
})
export class NbWindowMinimizeIconComponent {
@HostBinding('attr.aria-label') label = 'minimize';
}
90 changes: 90 additions & 0 deletions src/framework/theme/components/window/window-ref.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { ComponentRef } from '@angular/core';
import { Observable, ReplaySubject, Subject } from 'rxjs';
import { NbWindowComponent } from './window.component';
import { NbWindowConfig, NbWindowState, NbWindowStateChange } from './window.options';

/**
* The `NbWindowRef` helps to manipulate window after it was created.
* The window can be dismissed by using `close` method of the windowRef.
* You can access rendered component as `componentRef` property of the windowRef.
*/
export class NbWindowRef {
componentRef: ComponentRef<NbWindowComponent>;

protected prevStateValue: NbWindowState;
protected stateValue: NbWindowState;
/**
* Current window state.
*/
get state() {
return this.stateValue;
}
set state(newState: NbWindowState) {
if (newState && this.stateValue !== newState) {
this.prevStateValue = this.state;
this.stateValue = newState;
this.stateChange$.next({ oldState: this.prevStateValue, newState });
}
}

protected stateChange$ = new ReplaySubject<NbWindowStateChange>(1);
/**
* Emits when window state change.
*/
get stateChange(): Observable<NbWindowStateChange> {
return this.stateChange$.asObservable();
}

protected _closed = false;
protected closed$ = new Subject();
/**
* Emits when window was closed.
*/
get onClose() {
return this.closed$.asObservable();
}

constructor(public config: NbWindowConfig) {
this.state = config.initialState;
}

/**
* Minimize window.
*/
minimize() {
this.state = NbWindowState.MINIMIZED;
}

/**
* Maximize window.
*/
maximize() {
this.state = NbWindowState.MAXIMIZED;
}

/**
* Set window on top.
*/
fullScreen() {
this.state = NbWindowState.FULL_SCREEN;
}

toPreviousState() {
this.state = this.prevStateValue;
}

/**
* Closes window.
* */
close() {
if (this._closed) {
return;
}

this._closed = true;
this.componentRef.destroy();
this.stateChange$.complete();
this.closed$.next();
this.closed$.complete();
}
}
56 changes: 56 additions & 0 deletions src/framework/theme/components/window/window.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
:host {
flex: 1 0 auto;
min-width: 20rem;

nb-card {
margin: 0;
}
nb-card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 0;
overflow: hidden;
}
.title {
flex: 1 0 auto;
margin-right: 3rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.buttons {
width: 9.5rem;
display: flex;
justify-content: space-evenly;

.button {
background: none;
border: none;
flex: 0 0 3rem;
padding: 0 0.8rem;
}
}
}

:host(.full-screen) {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

:host(.maximized) nb-card {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}

:host(.minimized) nb-card {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
height: auto;

nb-card-header {
border-bottom: none;
}
}
Loading

0 comments on commit 60a65cb

Please sign in to comment.