feat(demo): add landing page with docs (#1951)

This commit is contained in:
Dmitry Nehaychik 2018-12-26 15:17:57 +03:00 committed by Sergey Andrievskiy
parent 67c9587b87
commit 43cc3a1556
190 changed files with 15425 additions and 21 deletions

View file

@ -0,0 +1,39 @@
<div class="logo">
<a href="http://akveo.com" target="_blank"><img src="assets/img/akveo-logo.png" alt="Akveo logo"></a>
</div>
<div>
<ul>
<li><strong class="title">More from Akveo</strong></li>
<li><a href="http://akveo.com?utm_source=nebular_documentation&utm_medium=footer" target="_blank">Homepage</a></li>
<li><a href="https://akveo.github.io/eva-icons?utm_source=nebular_documentation&utm_medium=footer">Eva Icons</a></li>
<li><a href="https://akveo.github.io/react-native-ui-kitten?utm_source=nebular_documentation&utm_medium=footer">React Native UI Kitten</a></li>
<li><a href="http://akveo.com/ngx-admin?utm_source=nebular_documentation&utm_medium=footer"
target="_blank">ngx-admin</a></li>
</ul>
</div>
<div>
<ul>
<li><strong class="title">Follow Us</strong></li>
<li class="social">
<a href="https://github.com/akveo/ngx-admin" target="_blank">
<i class="small-social-github"></i>
</a>
<a href="https://twitter.com/akveo_inc" target="_blank">
<i class="small-social-twitter"></i>
</a>
<a href="https://www.facebook.com/akveo" target="_blank">
<i class="small-social-facebook"></i>
</a>
</li>
<li class="copy">
&copy; 2015-2018 <a href="http://akveo.com?utm_source=nebular_documentation&utm_medium=footer" target="_blank">Akveo LLC</a><br>
Documentation licensed under CC BY 4.0.
</li>
</ul>
</div>
<div class="contact">
<ul>
<li><strong class="title">Contact Us</strong></li>
<li><a href="#">contact@akveo.com</a></li>
</ul>
</div>

View file

@ -0,0 +1,108 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
$text-fg: nb-theme(footer-fg);
$social-fg: nb-theme(color-fg-icon);
$title-fg: nb-theme(color-fg-heading);
display: flex;
flex: 1;
flex-wrap: wrap;
padding-top: 1.25rem;
justify-content: space-around;
> div {
display: flex;
margin-right: 0;
justify-content: center;
width: 100%;
&:last-child {
margin-right: 0;
}
a {
color: $text-fg;
}
ul {
list-style: none;
padding-left: 0;
}
li {
display: flex;
margin-bottom: 1rem;
justify-content: center;
align-items: center;
text-align: center;
}
&.logo {
display: none;
}
.title {
color: $title-fg;
font-size: 1.125rem;
font-weight: bold;
line-height: 1.375rem;
}
.copy {
color: $text-fg;
display: list-item;
font-size: 0.75rem;
}
.social {
display: flex;
flex-direction: row;
a {
font-size: 3rem;
text-decoration: none;
color: $social-fg;
margin-right: 1rem;
}
}
}
> div.logo {
display: none;
}
@include media-breakpoint-up(md) {
> div {
justify-content: flex-start;
margin-right: 2rem;
width: auto;
li {
justify-content: flex-start;
align-items: flex-start;
text-align: left;
}
}
}
@include media-breakpoint-up(lg) {
> div.logo {
display: flex;
flex-direction: column;
margin-top: -2.5rem;
text-align: center;
justify-content: center;
img {
max-width: 9rem;
}
}
}
}

View file

@ -0,0 +1,10 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
selector: 'ngx-docs-footer',
styleUrls: ['./footer.component.scss'],
templateUrl: './footer.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NgxDocsFooterComponent {
}

View file

@ -0,0 +1,49 @@
<div class="logo">
<a href="http://akveo.com" target="_blank"><img src="assets/img/akveo-logo.png" alt="Akveo logo"></a>
</div>
<div>
<ul>
<li><span class="title">More from Akveo</span></li>
<li><a href="http://akveo.com?utm_source=ngx_admin_landing&utm_medium=footer" target="_blank">Homepage</a></li>
<li><a href="https://akveo.github.io/nebular?utm_source=ngx_admin_landing&utm_medium=footer">Nebular</a></li>
<li><a href="https://akveo.github.io/eva-icons?utm_source=ngx_admin_landing&utm_medium=footer">Eva Icons</a></li>
<li><a href="https://akveo.github.io/react-native-ui-kitten?utm_source=ngx_admin_landing&utm_medium=footer">React Native UI Kitten</a></li>
</ul>
</div>
<div class="social-container">
<ul>
<li><span class="title">Follow Us</span></li>
<li class="social">
<a href="https://github.com/akveo/ngx-admin"
aria-label="github"
target="_blank">
<i [innerHTML]="'github-outline' | eva: { width: 30, height: 30, fill: '#f7f8fa' }"></i>
</a>
<a href="https://twitter.com/akveo_inc"
aria-label="twitter"
target="_blank">
<i [innerHTML]="'twitter' | eva: { width: 30, height: 30, fill: '#f7f8fa' }"></i>
</a>
<a href="https://www.facebook.com/akveo"
aria-label="facebook"
target="_blank">
<i [innerHTML]="'facebook' | eva: { width: 35, height: 35, fill: '#f7f8fa' }"></i>
</a>
<a href="https://www.linkedin.com/company/akveo"
aria-label="linkedIn"
target="_blank">
<i [innerHTML]="'linkedin' | eva: { width: 35, height: 35, fill: '#f7f8fa' }"></i>
</a>
</li>
<li class="copy">
&copy; 2015-2018 <a href="http://akveo.com?utm_source=eva_documentation&utm_medium=footer" target="_blank">Akveo LLC</a><br>
Documentation licensed under CC BY 4.0.
</li>
</ul>
</div>
<div class="contact">
<ul>
<li class="title">Contact Us</li>
<li><a href="mailto:contact@akveo.com">contact@akveo.com</a></li>
</ul>
</div>

View file

@ -0,0 +1,188 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
$text-fg: nb-theme(footer-fg);
$social-fg: nb-theme(color-fg-icon);
$title-fg: nb-theme(footer-title-fg);
display: flex;
flex: 1;
flex-wrap: wrap;
padding-top: 2.75rem;
justify-content: flex-start;
margin: 0.375rem 10.25rem 0;
> div {
display: flex;
margin-right: 0;
margin-bottom: 2rem;
margin-top: 0.375rem;
justify-content: center;
width: 100%;
&:last-child {
margin-right: 0;
margin-bottom: 0;
}
a {
font-size: nb-theme(font-size);
color: $text-fg;
}
ul {
list-style: none;
padding-left: 0;
}
li {
font-family: nb-theme(font-secondary), sans-serif;
font-weight: normal;
display: flex;
margin-bottom: 1.5rem;
justify-content: center;
align-items: center;
text-align: center;
&:first-child {
margin-bottom: 1.75rem;
}
}
.title {
color: $title-fg;
font-size: nb-theme(font-size-lg);
}
.copy {
$copy-color: #535b6c;
color: $copy-color;
display: list-item;
font-size: 0.66rem;
line-height: 1.75;
a {
font-size: 0.65rem;
color: $copy-color;
}
}
.social {
display: flex;
flex-direction: row;
a {
display: flex;
align-items: center;
justify-content: center;
width: 2.5rem;
height: 2.5rem;
background-color: $social-fg;
border-radius: 0.375rem;
text-decoration: none;
margin-right: 1.5rem;
line-height: 0.5;
&:last-child {
margin-right: 0;
}
}
}
}
> div.logo {
margin-bottom: 3.125rem;
a {
width: 10rem;
height: 10rem;
}
img {
width: 100%;
height: 100%;
}
}
@include media-breakpoint-up(md) {
justify-content: space-around;
margin-right: 0;
margin-left: 0;
> div.logo {
display: none;
}
> div {
justify-content: flex-start;
margin-right: 0;
margin-bottom: 0;
width: auto;
li {
justify-content: flex-start;
align-items: flex-start;
text-align: left;
}
}
}
@include media-breakpoint-up(lg) {
margin-right: 2rem;
margin-left: 2rem;
> div.logo {
display: flex;
flex-direction: column;
margin-top: 0;
margin-bottom: 0;
text-align: center;
}
}
@include media-breakpoint-up(xxl) {
justify-content: flex-start;
margin: 0.375rem 10.25rem 0;
> div.logo {
margin-right: 7.875rem;
}
> div {
margin-right: 8.375rem;
}
.company-info {
margin-right: 12.25rem;
}
.social-container {
margin-right: 6.75rem;
}
}
@include media-breakpoint-down(md) {
padding-left: 1rem;
padding-right: 1rem;
> div {
margin-right: 0;
&.logo {
margin-right: 0;
}
}
.social-container {
margin-right: 0;
}
}
}

View file

@ -0,0 +1,15 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { Component } from '@angular/core';
@Component({
selector: 'ngx-landing-footer',
styleUrls: ['./footer.component.scss'],
templateUrl: './footer.component.html',
})
export class NgxLandingFooterComponent {
}

View file

@ -0,0 +1,73 @@
import { Directive, ElementRef, Inject, Input, OnDestroy, OnInit, Renderer2 } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { NB_WINDOW } from '@nebular/theme';
import { takeWhile, publish, refCount } from 'rxjs/operators';
import { NgxTocElement, NgxTocStateService } from '../../services/toc-state.service';
import { delay } from 'rxjs/internal/operators';
@Directive({
// tslint:disable-next-line
selector: '[ngxFragment]',
})
export class NgxFragmentTargetDirective implements OnInit, OnDestroy, NgxTocElement {
@Input() ngxFragment: string;
@Input() ngxFragmentClass: string;
@Input() ngxFragmentSync: boolean = true;
private inView = false;
private alive = true;
private readonly marginFromTop = 120;
get fragment(): string {
return this.ngxFragment;
}
get element(): any {
return this.el.nativeElement;
}
get y(): number {
return this.element.getBoundingClientRect().y;
}
constructor(
private activatedRoute: ActivatedRoute,
@Inject(NB_WINDOW) private window,
private tocState: NgxTocStateService,
private el: ElementRef,
private renderer: Renderer2,
) {}
ngOnInit() {
this.ngxFragmentSync && this.tocState.add(this);
this.activatedRoute.fragment
.pipe(publish(null), refCount(), takeWhile(() => this.alive), delay(10))
.subscribe((fragment: string) => {
if (fragment && this.fragment === fragment && !this.inView) {
this.selectFragment();
} else {
this.deselectFragment();
}
});
}
selectFragment() {
this.ngxFragmentClass && this.renderer.addClass(this.el.nativeElement, this.ngxFragmentClass);
this.setInView(true);
this.window.scrollTo(0, this.el.nativeElement.offsetTop - this.marginFromTop);
}
deselectFragment() {
this.renderer.removeClass(this.el.nativeElement, this.ngxFragmentClass);
}
setInView(val: boolean) {
this.inView = val;
}
ngOnDestroy() {
this.alive = false;
this.ngxFragmentSync && this.tocState.remove(this);
}
}

View file

@ -0,0 +1,25 @@
<div class="section left">
<button *ngIf="sidebarTag" class="sidebar-toggle" (click)="toggleSidebar()">
<i class="nb-menu"></i>
</button>
<div class="logo">
<a routerLink="/">ngx-admin</a>
<span class="version">v{{ currentVersion }}</span>
</div>
</div>
<div class="section middle">
<nb-menu [items]="headerMenu"></nb-menu>
</div>
<div class="section right">
<ng-container *ngIf="!isDocs">
Need some help? Let us know! <a (click)="trackEmailClick()" href="mailto:contact@akveo.com">contact@akveo.com</a>
</ng-container>
<iframe *ngIf="isDocs"
class="stars"
src="https://ghbtns.com/github-btn.html?user=akveo&repo=ngx-admin&type=star&count=true"
frameborder="0"
scrolling="0">
</iframe>
</div>

View file

@ -0,0 +1,286 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
$left-section-width: nb-theme(sidebar-width);
$right-section-width: nb-theme(settings-col-width);
$logo-fg: nb-theme(header-fg);
$version-fg: nb-theme(color-fg-heading-light);
$menu-item-fg: nb-theme(color-fg-heading-light);
$menu-item-fg-active: nb-theme(header-menu-fg-active);
$contacts-fg: nb-theme(color-fg-heading-light);
$contacts-active-fg: nb-theme(header-menu-fg-active);
display: flex;
flex: 1 0 auto;
flex-direction: row;
align-items: center;
.section {
display: flex;
padding: 0.875rem 0.5rem;
&.left {
width: $left-section-width;
}
&.middle {
flex: 1;
}
}
.logo {
display: flex;
flex: 1 0 auto;
flex-direction: row;
a {
font-family: nb-theme(font-main), sans-serif;
font-size: 1.275rem;
color: $logo-fg;
text-decoration: none !important;
font-weight: bold;
}
.version {
font-size: 0.75rem;
font-weight: bold;
color: $version-fg;
}
}
/deep/ nb-menu {
flex: 1;
.menu-items {
display: flex;
justify-content: flex-start;
.menu-item {
border: none;
width: 5.375rem;
a {
padding: 0.675rem 1.375rem;
color: $menu-item-fg;
display: block;
&:hover, &.active, &:focus {
font-weight: normal;
color: $menu-item-fg-active;
outline: none !important;
}
}
}
li:first-child {
display: none;
}
}
}
.section.right {
color: $contacts-fg;
a {
font-family: nb-theme(font-main), sans-serif;
color: $contacts-active-fg;
margin-left: 0.375rem;
}
}
@include media-breakpoint-up(is) {
.section {
padding: 0.875rem 0;
}
}
@include media-breakpoint-up(sm) {
.logo {
align-items: baseline;
flex: 1 0 auto;
a {
color: #000000;
margin-right: 0.5rem;
}
.version {
display: inline;
}
}
}
@include media-breakpoint-up(md) {
.logo {
flex: 1 0 auto;
flex-direction: column;
align-items: flex-start;
.version {
margin-left: 0;
}
}
/deep/ nb-menu .menu-items li:nth-child(2) {
display: list-item;
}
}
@include media-breakpoint-up(lg) {
/deep/ nb-menu .menu-items {
justify-content: flex-start;
li:not(:first-child) {
display: list-item;
}
}
}
@include media-breakpoint-up(xl) {
.sidebar-toggle {
display: none;
}
}
@include media-breakpoint-down(sm) {
/deep/ nb-menu {
.menu-items {
justify-content: flex-end;
}
}
.section {
&.right {
display: none;
}
}
}
@include media-breakpoint-down(is) {
padding: 0 0 0 1rem;
.section {
&.left {
width: auto;
}
}
.logo {
flex: 1 0 auto;
flex-direction: column;
align-items: flex-start;
a {
color: #000000;
}
.version {
margin-left: 0;
}
}
}
&.docs-page {
.section {
&.left {
align-items: center;
padding-left: 0;
width: auto;
}
&.middle {
justify-content: flex-end;
}
&.right {
display: none;
margin-left: 0;
width: auto;
}
}
.sidebar-toggle {
border: none;
background-color: transparent;
font-size: 2.5rem;
line-height: 1rem;
flex: 1 0 auto;
padding: 0 0.5rem;
.nb-menu {
vertical-align: middle;
}
}
/deep/ nb-menu {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
@include media-breakpoint-up(is) {
/deep/ nb-menu .menu-items li:first-child {
display: list-item;
}
}
@include media-breakpoint-up(sm) {
.section.middle {
justify-content: space-between;
}
.section.right {
display: block;
}
.stars {
width: 7.5rem;
height: 1.25rem;
margin-left: auto;
}
}
@include media-breakpoint-up(lg) {
.section.middle {
justify-content: space-around;
}
/deep/ nb-menu {
min-width: 28rem;
.menu-items li {
display: list-item;
}
}
}
@include media-breakpoint-up(xl) {
.section.left {
padding-left: 1.125rem;
width: nb-theme(sidebar-width);
}
.sidebar-toggle {
display: none;
}
/deep/ nb-menu {
flex: 1;
}
}
@include media-breakpoint-up(macpro) {
.section.right {
margin-left: 1.875rem;
width: $right-section-width;
}
}
}
}

View file

@ -0,0 +1,52 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { Component, HostBinding, Input, OnDestroy } from '@angular/core';
import { takeWhile } from 'rxjs/operators';
import { NbSidebarService } from '@nebular/theme';
/*import { NgxAnalytics } from '../../services/analytics.service';*/
import { NgxVersionService } from '../../services/version.service';
import { HeaderMenuService } from '../../../@core/data/service/header-menu.service';
@Component({
selector: 'ngx-landing-header',
styleUrls: ['./header.component.scss'],
templateUrl: './header.component.html',
})
export class NgxLandingHeaderComponent implements OnDestroy {
private alive = true;
@HostBinding('class.docs-page') @Input() isDocs = false;
@Input() sidebarTag: string = '';
currentVersion: string;
headerMenu = [];
constructor(/*private analytics: NgxAnalytics,*/
private sidebarService: NbSidebarService,
private versionService: NgxVersionService,
private headerMenuService: HeaderMenuService) {
this.currentVersion = this.versionService.getNgxVersion();
this.headerMenuService.getHeaderMenu()
.pipe(takeWhile(() => this.alive ))
.subscribe((headerMenu) => this.headerMenu = headerMenu);
}
trackEmailClick() {
}
toggleSidebar() {
this.sidebarService.toggle(false, this.sidebarTag);
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -0,0 +1,23 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { NgxLandingFooterComponent } from './footer/footer.component';
import { NgxLandingHeaderComponent } from './header/header.component';
import { NgxSectionTitleComponent } from './section-title/section-title.component';
import { NgxPageTabsComponent } from './page-tabs/page-tabs.component';
import { NgxPageTocComponent } from './page-toc/page-toc.component';
import { NgxFragmentTargetDirective } from './fragment-target/fragment-target.directive';
import { NgxDocsFooterComponent } from './docs-footer/footer.component';
export {
NgxLandingHeaderComponent,
NgxLandingFooterComponent,
NgxSectionTitleComponent,
NgxPageTabsComponent,
NgxPageTocComponent,
NgxFragmentTargetDirective,
NgxDocsFooterComponent,
};

View file

@ -0,0 +1,101 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
display: flex;
flex-wrap: wrap;
$tabs-fg: nb-theme(color-fg-heading-light);
$tabs-fg-active: nb-theme(color-fg-heading);
$tabs-bg-active: nb-theme(color-white);
$tabs-shadow: 0 8px 20px 0 rgba(218, 224, 235, 0.6);
$tabs-accent-line: nb-theme(color-fg-highlight);
a {
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
padding: 1rem;
width: 50%;
height: 7.5rem;
font-size: 0.875rem;
text-decoration: none;
color: $tabs-fg;
margin-bottom: 1rem;
.title {
padding-bottom: 0.75rem;
font-weight: 500;
}
.icon {
font-size: 1.5rem;
padding-bottom: 1rem;
}
&.selected {
background: white;
color: $tabs-fg-active;
box-shadow: $tabs-shadow;
.line {
height: 0.1875rem;
width: 60%;
background: $tabs-accent-line;
border-radius: 1.5px;
}
}
}
.icon,
.title {
display: block;
text-align: center;
}
}
:host(.horizontal) {
a {
flex: 0 0 50%;
height: auto;
margin-bottom: 0;
padding: 0 1rem;
.title,
.icon {
display: inline;
padding-bottom: 0;
vertical-align: middle;
}
.icon {
margin-right: 0.5rem;
}
}
.text-container {
padding-bottom: 1.3rem;
}
.line {
order: -1;
margin-bottom: 1.3rem;
}
@media screen and (min-width: 40em) {
flex: 1 1 0;
a {
flex: 1 1 0;
&.selected::after {
content: '';
position: absolute;
top: 100%;
border-left: 1rem solid transparent;
border-right: 1rem solid transparent;
border-top: 1rem solid #fff;
}
}
}
}

View file

@ -0,0 +1,87 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { ChangeDetectionStrategy, Component, Input, OnDestroy, HostBinding } from '@angular/core';
import { takeWhile, map, publishReplay, refCount } from 'rxjs/operators';
import { ActivatedRoute } from '@angular/router';
import { Observable, of as observableOf, combineLatest } from 'rxjs';
@Component({
selector: 'ngx-page-tabs',
styleUrls: ['./page-tabs.component.scss'],
template: `
<a *ngFor="let item of items$ | async" [class.selected]="item.selected" [routerLink]="['../', item.tab]">
<div class="text-container">
<i class="icon {{ item.icon }}"></i>
<span class="title">{{ item.title }}</span>
</div>
<i class="line"></i>
</a>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NgxPageTabsComponent implements OnDestroy {
items$: Observable<any[]> = observableOf([]);
@Input()
set tabs(value) {
this.items$ = combineLatest(
observableOf(value || []).pipe(
map(tabs => this.availableTabs.filter(tab => tabs[tab.tab])),
),
this.activatedRoute.params.pipe(publishReplay(), refCount()),
)
.pipe(
takeWhile(() => this.alive),
map(([tabs, params]) => (tabs.map((item: any) => ({ ...item, selected: item.tab === params.tab })))),
);
}
@HostBinding('class.horizontal')
isHorizontal = false;
@Input()
set horizontal(value) {
this.isHorizontal = value !== 'false' && value !== false;
}
private availableTabs: {
tab: string;
title: string;
icon: string;
selected?: boolean;
}[] = [
{
tab: 'overview',
title: 'Overview',
icon: 'feather-eye',
selected: true,
},
{
tab: 'api',
title: 'API',
icon: 'feather-settings',
},
{
tab: 'theme',
title: 'Theme',
icon: 'feather-droplet',
},
{
tab: 'examples',
title: 'Examples',
icon: 'feather-image',
},
];
private alive = true;
constructor(private activatedRoute: ActivatedRoute) {
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -0,0 +1,50 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
$title-fg: nb-theme(color-fg-heading-light);
$item-fg: rgba(102, 110, 128, 0.87);
$item-fg-active: #202020;
$accent-line-bg: nb-theme(color-fg-highlight);
padding-left: 1rem;
display: block;
h4 {
font-size: 1.25rem;
font-weight: normal;
margin-bottom: 2.5rem;
color: $title-fg;
}
ul {
list-style: none;
padding-left: 3.25rem;
font-size: 0.9375rem;
li {
margin-bottom: 0.9375rem;
}
a {
color: $item-fg;
}
li.selected a {
font-weight: 500;
color: $item-fg-active;
position: relative;
&::after {
content: '';
position: absolute;
left: -3.25rem;
top: 50%;
transform: translateY(-50%);
height: 0.1875rem;
width: 2rem;
background: $accent-line-bg;
border-radius: 1.5px;
}
}
}
}

View file

@ -0,0 +1,67 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Input,
OnDestroy,
} from '@angular/core';
import { takeWhile, map } from 'rxjs/operators';
import { ActivatedRoute } from '@angular/router';
import { of as observableOf, combineLatest } from 'rxjs';
@Component({
selector: 'ngx-page-toc',
styleUrls: ['./page-toc.component.scss'],
template: `
<ng-container *ngIf="items?.length > 0">
<h4>Overview</h4>
<ul>
<li *ngFor="let item of items" [class.selected]="item.selected">
<a [routerLink]="item.link" [fragment]="item.fragment">{{ item.title }}</a>
</li>
</ul>
</ng-container>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NgxPageTocComponent implements OnDestroy {
items: any[];
@Input()
set toc(value) {
combineLatest(
observableOf(value || []),
this.activatedRoute.fragment,
)
.pipe(
takeWhile(() => this.alive),
map(([toc, fragment]) => {
toc = toc.map((item: any) => ({ ...item, selected: fragment === item.fragment }));
if (toc.length && !toc.find(item => item.selected)) {
toc[0].selected = true;
}
return toc;
}),
)
.subscribe((toc) => {
this.items = toc;
this.cd.detectChanges();
});
}
private alive = true;
constructor(private activatedRoute: ActivatedRoute, private cd: ChangeDetectorRef) {
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -0,0 +1,3 @@
<h2>
<ng-content></ng-content>
</h2>

View file

@ -0,0 +1,24 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
h2 {
font-family: 'Helvetica Neue Bold', sans-serif;
font-size: 2rem;
color: #000000;
text-align: center;
}
@include media-breakpoint-down(is) {
h2 {
font-size: 1.5rem;
}
}
}

View file

@ -0,0 +1,10 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-landing-section-title',
templateUrl: './section-title.component.html',
styleUrls: ['./section-title.component.scss'],
})
export class NgxSectionTitleComponent {
}