feat: docs app

This commit is contained in:
Sergey Andrievskiy 2019-07-16 08:38:11 +03:00
parent 62e6828680
commit 165e64eaca
203 changed files with 15928 additions and 6 deletions

View file

@ -0,0 +1,25 @@
<section class="header" >
<strong class="title">{{ content.name }}</strong>
<div class="actions">
<div class="action-selector">
<select class="action-item" [(ngModel)]="currentTheme" (change)="switchTheme($event.target.value)">
<option *ngFor="let theme of themes" [value]="theme.value">{{theme.label}}</option>
</select>
<i class="icon feather-aperture"></i>
</div>
<a class="btn action-item action-button" target="_blank" [href]="url">
<i class="icon feather-external-link"></i>
</a>
<button type="button"
*ngIf="hasViewSwitch"
class="btn action-item action-button"
(click)="switchToInlineVew()">
<i class="icon feather-code"></i>
</button>
</div>
</section>
<div class="iframe-container">
<iframe #iframe *ngIf="content.id" [style.height.px]="iframeHeight" [class.loading]="loading"></iframe>
</div>
<span class="icon-loading feather-more-vertical" *ngIf="loading"></span>

View file

@ -0,0 +1,170 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
// TODO: move some variables in Nebular themes
// colors
$action-bg: white;
$action-fg: nb-theme(color-fg-heading-light);
$block-bg-default: #ebeff5;
$block-bg-cosmic: #2f296b;
$block-fg-cosmic: #7d838b;
$block-bg-corporate: #f1f5f8;
display: flex;
flex-direction: column;
padding: 0.5rem 1rem 2.5rem 1.5rem;
border-radius: 0.5rem;
position: relative;
.header {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin-bottom: 1.875rem;
}
.title,
.actions {
margin-top: 0.5rem;
}
.title {
margin-right: 1rem;
font-weight: bold;
text-transform: capitalize;
}
.actions {
display: flex;
width: 100%;
.icon {
font-size: 0.95rem;
}
}
.action-item {
background-color: $action-bg;
border-radius: 0.375rem;
height: 100%;
line-height: 1;
border: none;
color: $action-fg;
padding: 0.5rem 1rem;
margin-left: 0.625rem;
cursor: pointer;
&:first-child {
margin-left: 0;
}
&:hover, &:focus {
text-decoration: none;
}
}
.action-selector {
position: relative;
.action-item {
padding: 0;
color: transparent;
}
.icon {
color: $action-fg;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Target IE9 - IE11 */
select::-ms-expand {
display: none;
}
select {
font-size: 0.875rem;
appearance: none;
}
}
&.theme-default {
background-color: $block-bg-default;
}
&.theme-cosmic {
background-color: $block-bg-cosmic;
.title {
color: white;
}
.action-item {
color: $block-fg-cosmic;
}
}
&.theme-corporate {
background-color: $block-bg-corporate;
}
.iframe-container {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
iframe {
width: 100%;
border: none;
transform: translateZ(0);
&.loading {
visibility: hidden;
}
}
.icon-loading {
animation: rotation 2s infinite linear;
color: $action-fg;
font-size: 1.5rem;
font-weight: normal;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
@-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
}
}
@media screen and (min-width: 23em) {
.action-selector {
.action-item {
padding: 0.5rem 1rem;
color: $action-fg;
}
select.action-item {
padding: 0 2.5rem;
}
.icon {
left: 1.25rem;
transform: translate(0, -50%);
}
}
.actions {
width: auto;
}
}
}

View file

@ -0,0 +1,105 @@
import {
Component,
ElementRef,
Input,
OnInit,
OnDestroy,
ViewChild,
ChangeDetectionStrategy,
ChangeDetectorRef,
HostBinding,
Output,
EventEmitter,
AfterViewInit,
} from '@angular/core';
import { Location } from '@angular/common';
import { takeWhile } from 'rxjs/operators';
import { NgxExampleView } from '../../enum.example-view';
import { NgxIframeCommunicatorService } from '../../../@theme/services/iframe-communicator.service';
@Component({
selector: 'ngx-live-example-block',
styleUrls: ['./live-example-block.component.scss'],
templateUrl: './live-example-block.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NgxLiveExampleBlockComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('iframe', { static: false }) iframe: ElementRef;
@Input() content: any;
@Input() hasViewSwitch: boolean = false;
@Output() changeView = new EventEmitter<NgxExampleView>();
/* tslint:disable:no-unused-variable */
@HostBinding('class.theme-default')
private get isDefault() {
return this.currentTheme === 'default';
}
@HostBinding('class.theme-cosmic')
private get isCosmic() {
return this.currentTheme === 'cosmic';
}
@HostBinding('class.theme-corporate')
private get isCorporate() {
return this.currentTheme === 'corporate';
}
/* tslint:enable:no-unused-variable */
iframeHeight = 0;
alive: boolean = true;
themes: {label: string; value: string}[] = [
{ label: 'Default', value: 'default' },
{ label: 'Cosmic', value: 'cosmic' },
{ label: 'Corporate', value: 'corporate' },
];
currentTheme: string = 'default';
loading = true;
get url(): string {
return this.location.prepareExternalUrl(`example/${this.content.id}`);
}
get iframeWindow(): Window {
return this.iframe.nativeElement.contentWindow;
}
constructor(private changeDetection: ChangeDetectorRef,
private location: Location,
private communicator: NgxIframeCommunicatorService) {
}
ngOnInit() {
this.communicator.receive(this.content.id)
.pipe(takeWhile(() => this.alive))
.subscribe(it => {
this.iframeHeight = it.height;
this.loading = false;
this.changeDetection.detectChanges();
});
}
ngAfterViewInit() {
// we cannot set src using angular binding
// as it will trigger change detection and reload iframe
// which in its turn will send a new height
// and we would need to set the height and trigger change detection again
// resulting in infinite loop
this.iframe.nativeElement.src = this.url;
}
ngOnDestroy() {
this.alive = false;
}
switchTheme(theme: string) {
this.communicator.send({ id: this.content.id, theme }, this.iframeWindow);
}
switchToInlineVew() {
this.changeView.emit(NgxExampleView.INLINE);
}
}