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) #713

Merged
merged 33 commits into from
Sep 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6b7a3f2
feature(window): add window
yggg Sep 11, 2018
2da5316
feature(window): add focus trap
yggg Sep 11, 2018
d807e13
feature(window): buttons accessibility
yggg Sep 11, 2018
e1e969a
feature(window): unminimize to previous state
yggg Sep 11, 2018
3ecf7aa
docs(window): add docs
yggg Sep 12, 2018
3970b95
refactor(window): make buttons smaller
yggg Sep 12, 2018
bb0c87b
refactor(window): prevent window shrinking
yggg Sep 12, 2018
6ec9cf5
docs(window): make windows smaller
yggg Sep 12, 2018
5fbc6d9
feat(window): update template context
yggg Sep 12, 2018
251e506
docs(window): add template context details
yggg Sep 12, 2018
eb2d050
fix(window): import module with focus trap
yggg Sep 13, 2018
32f45a0
test(window): add tests
yggg Sep 13, 2018
c9ea3ea
refactor(window): make fields protected
yggg Sep 13, 2018
0e26024
Merge branch 'master' into feature/window
yggg Sep 13, 2018
16efd95
refactor(window): use host binding
yggg Sep 14, 2018
5c4f40d
refactor(window): provide user defined default windows object
yggg Sep 14, 2018
ef65bf7
refactor(window): rename types to options
yggg Sep 14, 2018
177673c
refactor(window): export only public options
yggg Sep 14, 2018
21cdba6
refactor(window): change injection token description
yggg Sep 14, 2018
de619a8
docs(window): add icon
yggg Sep 14, 2018
244d2b6
feat(window): change window button icons color based on theme
yggg Sep 14, 2018
e47d667
Merge branch 'feature/window' of https://github.com/yggg/nebular into…
yggg Sep 14, 2018
a8b285d
refactor(window): rename variables
yggg Sep 14, 2018
e5d3025
refactor(window): move viewport ruler to adapter module
yggg Sep 14, 2018
a12acd7
Merge branch 'master' into feature/window
yggg Sep 14, 2018
c3af959
fix(window): fix TS4023
yggg Sep 14, 2018
0d99767
feat(window): add option for window class
yggg Sep 17, 2018
33f08ca
docs(window): update examples
yggg Sep 17, 2018
9f6f1c0
fix(window): remove reference to deleted option
yggg Sep 17, 2018
f10bde5
test(window): add window class option test
yggg Sep 17, 2018
dc50171
feat(window): remove window size enum
yggg Sep 17, 2018
cefaa92
fix(window): remove window size from imports
yggg Sep 17, 2018
ffab928
test(window): mock viewport ruler adapter
yggg Sep 17, 2018
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
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://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://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://www.w3.org/2000/svg"
xmlns:xlink="http://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://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