mirror of
https://github.com/Redocly/redoc.git
synced 2025-03-03 09:25:47 +03:00
Update side menu to work with new menu structure
This commit is contained in:
parent
de00c7868a
commit
ac0681c8a9
7
lib/components/SideMenu/side-menu-items.html
Normal file
7
lib/components/SideMenu/side-menu-items.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<li *ngFor="let item of items; let idx = index" class="menu-item"
|
||||
ngClass="menu-item-level-{{item.level}}{{item.active ? ' active' : ''}}">
|
||||
<label class="menu-item-header" [ngClass]="{disabled: !item.ready}" (click)="activateItem(item)"> {{item.name}}</label>
|
||||
<ul *ngIf="item.items" class="menu-subitems">
|
||||
<side-menu-items [items]="item.items" (activate)="activateItem($event)"> </side-menu-items>
|
||||
</ul>
|
||||
</li>
|
83
lib/components/SideMenu/side-menu-items.scss
Normal file
83
lib/components/SideMenu/side-menu-items.scss
Normal file
|
@ -0,0 +1,83 @@
|
|||
@import '../../shared/styles/variables';
|
||||
|
||||
.menu-item-header {
|
||||
cursor: pointer;
|
||||
color: rgba($text-color, .6);
|
||||
-webkit-transition: all .15s ease-in-out;
|
||||
-moz-transition: all .15s ease-in-out;
|
||||
-ms-transition: all .15s ease-in-out;
|
||||
-o-transition: all .15s ease-in-out;
|
||||
transition: all .15s ease-in-out;
|
||||
display: block;
|
||||
padding: $side-menu-item-vpadding*2.5 $side-menu-item-hpadding;
|
||||
|
||||
&[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.disabled, &.disabled:hover {
|
||||
cursor: default;
|
||||
color: lighten($text-color, 60%);
|
||||
}
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
-webkit-transition: all .15s ease-in-out;
|
||||
-moz-transition: all .15s ease-in-out;
|
||||
-ms-transition: all .15s ease-in-out;
|
||||
-o-transition: all .15s ease-in-out;
|
||||
transition: all .15s ease-in-out;
|
||||
list-style: none inside none;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.menu-item:hover,
|
||||
.menu-item.active {
|
||||
background: darken($side-menu-active-bg-color, 6%);
|
||||
}
|
||||
|
||||
.menu-subitems {
|
||||
margin: 0;
|
||||
font-size: 0.929em;
|
||||
line-height: 1.2em;
|
||||
font-weight: $light;
|
||||
color: rgba($text-color, .9);
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
|
||||
.active > & {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-item-level-0 {
|
||||
> .menu-item-header {
|
||||
font-family: $headers-font, $headers-font-family;
|
||||
font-weight: $light;
|
||||
font-size: $h5;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
> .menu-item-header:hover,
|
||||
&.active > .menu-item-header {
|
||||
color: $primary-color;
|
||||
background: $side-menu-active-bg-color;
|
||||
}
|
||||
&.active {
|
||||
background: $side-menu-active-bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-item-level-1 {
|
||||
> .menu-item-header {
|
||||
padding-left: 2*$side-menu-item-hpadding;
|
||||
}
|
||||
|
||||
> .menu-item-header:hover,
|
||||
&.active > .menu-item-header {
|
||||
background: darken($side-menu-active-bg-color, 6%);
|
||||
}
|
||||
}
|
|
@ -7,17 +7,7 @@
|
|||
</div>
|
||||
<div #desktop id="resources-nav">
|
||||
<h5 class="menu-header"> API reference </h5>
|
||||
<div *ngFor="let cat of categories; let idx = index" class="menu-cat">
|
||||
|
||||
<label class="menu-cat-header" (click)="activateAndScroll(idx, -1)" [hidden]="cat.headless"
|
||||
[ngClass]="{active: cat.active, disabled: !cat.ready }"> {{cat.name}}</label>
|
||||
<ul *ngIf="cat.methods.length" class="menu-subitems" [@itemAnimation]="cat.active ? 'expanded' : 'collapsed'">
|
||||
<li *ngFor="let method of cat.methods; trackBy:summary; let methIdx = index"
|
||||
[ngClass]="{active: method.active, disabled: !method.ready}"
|
||||
(click)="activateAndScroll(idx, methIdx)">
|
||||
{{method.summary}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<ul class="menu-root">
|
||||
<side-menu-items [items]="menuItems" (activate)="activateAndScroll($event)"></side-menu-items>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -6,6 +6,11 @@ $mobile-menu-compact-breakpoint: 550px;
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
ul.menu-root {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.menu-header {
|
||||
text-transform: uppercase;
|
||||
color: $headers-color;
|
||||
|
@ -13,81 +18,6 @@ $mobile-menu-compact-breakpoint: 550px;
|
|||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.menu-cat-header {
|
||||
font-size: $h5;
|
||||
font-family: $headers-font, $headers-font-family;
|
||||
font-weight: $light;
|
||||
cursor: pointer;
|
||||
color: rgba($text-color, .6);
|
||||
text-transform: uppercase;
|
||||
background-color: $side-bar-bg-color;
|
||||
-webkit-transition: all .15s ease-in-out;
|
||||
-moz-transition: all .15s ease-in-out;
|
||||
-ms-transition: all .15s ease-in-out;
|
||||
-o-transition: all .15s ease-in-out;
|
||||
transition: all .15s ease-in-out;
|
||||
display: block;
|
||||
padding: $side-menu-item-vpadding*2.5 $side-menu-item-hpadding;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
color: $primary-color;
|
||||
background-color: $side-menu-active-bg-color;
|
||||
}
|
||||
|
||||
&[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.disabled, &.disabled:hover {
|
||||
cursor: default;
|
||||
color: lighten($text-color, 60%);
|
||||
}
|
||||
}
|
||||
|
||||
.menu-subitems {
|
||||
margin: 0;
|
||||
font-size: 0.929em;
|
||||
line-height: 1.2em;
|
||||
font-weight: $light;
|
||||
color: rgba($text-color, .9);
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
&.active {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
& li {
|
||||
-webkit-transition: all .15s ease-in-out;
|
||||
-moz-transition: all .15s ease-in-out;
|
||||
-ms-transition: all .15s ease-in-out;
|
||||
-o-transition: all .15s ease-in-out;
|
||||
transition: all .15s ease-in-out;
|
||||
list-style: none inside none;
|
||||
cursor: pointer;
|
||||
background-color: $side-menu-active-bg-color;
|
||||
padding: $side-menu-item-vpadding*2 $side-menu-item-hpadding*2;
|
||||
padding-left: $side-menu-item-hpadding*2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
& li:hover,
|
||||
& li.active {
|
||||
background: darken($side-menu-active-bg-color, 6%);
|
||||
}
|
||||
|
||||
&.disabled, &.disabled:hover {
|
||||
cursor: default;
|
||||
color: lighten($text-color, 60%);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.menu-subitems li.active {
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
display: none;
|
||||
height: 3em;
|
||||
|
|
|
@ -1,36 +1,50 @@
|
|||
'use strict';
|
||||
|
||||
import { Component, ElementRef, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output, ElementRef, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';
|
||||
|
||||
//import { global } from '@angular/core/src/facade/lang';
|
||||
import { trigger, state, animate, transition, style } from '@angular/core';
|
||||
import { BaseComponent, SpecManager } from '../base';
|
||||
import { ScrollService, MenuService, OptionsService } from '../../services/index';
|
||||
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
|
||||
import { MenuCategory } from '../../services/schema-helper.service';
|
||||
import { MenuItem } from '../../services/schema-helper.service';
|
||||
|
||||
const global = window;
|
||||
|
||||
@Component({
|
||||
selector: 'side-menu-items',
|
||||
templateUrl: './side-menu-items.html',
|
||||
styleUrls: ['./side-menu-items.css']
|
||||
})
|
||||
export class SideMenuItems {
|
||||
@Input() items: MenuItem[];
|
||||
@Output() activate = new EventEmitter<MenuItem>();
|
||||
|
||||
activateItem(item) {
|
||||
this.activate.next(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'side-menu',
|
||||
templateUrl: './side-menu.html',
|
||||
styleUrls: ['./side-menu.css'],
|
||||
animations: [
|
||||
trigger('itemAnimation', [
|
||||
state('collapsed, void',
|
||||
style({ height: '0px' })),
|
||||
state('expanded',
|
||||
style({ height: '*' })),
|
||||
transition('collapsed <=> expanded', [
|
||||
animate('200ms ease')
|
||||
])
|
||||
])
|
||||
// trigger('itemAnimation', [
|
||||
// state('collapsed, void',
|
||||
// style({ height: '0px' })),
|
||||
// state('expanded',
|
||||
// style({ height: '*' })),
|
||||
// transition('collapsed <=> expanded', [
|
||||
// animate('200ms ease')
|
||||
// ])
|
||||
// ])
|
||||
],
|
||||
})
|
||||
export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
|
||||
activeCatCaption: string;
|
||||
activeItemCaption: string;
|
||||
categories: Array<MenuCategory>;
|
||||
menuItems: Array<MenuItem>;
|
||||
|
||||
private options: any;
|
||||
private $element: any;
|
||||
|
@ -54,11 +68,10 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
|
|||
this.menuService.changed.subscribe((evt) => this.changed(evt));
|
||||
}
|
||||
|
||||
changed(newItem) {
|
||||
if (newItem) {
|
||||
let {cat, item} = newItem;
|
||||
this.activeCatCaption = cat.name || '';
|
||||
this.activeItemCaption = item && item.summary || '';
|
||||
changed(item) {
|
||||
if (item) {
|
||||
this.activeCatCaption = item.name || '';
|
||||
this.activeItemCaption = item.parent && item.parent.name || '';
|
||||
}
|
||||
|
||||
//safari doesn't update bindings if not run changeDetector manually :(
|
||||
|
@ -74,22 +87,19 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
|
|||
if ($item) $item.scrollIntoView();
|
||||
}
|
||||
|
||||
activateAndScroll(catIdx, methodIdx) {
|
||||
activateAndScroll(item) {
|
||||
if (this.mobileMode()) {
|
||||
this.toggleMobileNav();
|
||||
}
|
||||
let menu = this.categories;
|
||||
|
||||
if (!menu[catIdx].ready) return;
|
||||
if (menu[catIdx].methods && menu[catIdx].methods.length && (methodIdx >= 0) &&
|
||||
!menu[catIdx].methods[methodIdx].ready) return;
|
||||
//if (!this.flatItems[idx].ready) return; // TODO: move inside next statement
|
||||
|
||||
this.menuService.activate(catIdx, methodIdx);
|
||||
this.menuService.activate(item.flatIdx);
|
||||
this.menuService.scrollToActive();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.categories = this.menuService.categories;
|
||||
this.menuItems = this.menuService.items;
|
||||
|
||||
this.$mobileNav = DOM.querySelector(this.$element, '.mobile-nav');
|
||||
this.$resourcesNav = DOM.querySelector(this.$element, '#resources-nav');
|
||||
|
|
|
@ -9,7 +9,7 @@ import { RequestSamples } from './RequestSamples/request-samples';
|
|||
import { ResponsesList } from './ResponsesList/responses-list';
|
||||
import { ResponsesSamples } from './ResponsesSamples/responses-samples';
|
||||
import { SchemaSample } from './SchemaSample/schema-sample';
|
||||
import { SideMenu } from './SideMenu/side-menu';
|
||||
import { SideMenu, SideMenuItems } from './SideMenu/side-menu';
|
||||
import { MethodsList } from './MethodsList/methods-list';
|
||||
import { Method } from './Method/method';
|
||||
import { Warnings } from './Warnings/warnings';
|
||||
|
@ -21,9 +21,9 @@ import { Redoc } from './Redoc/redoc';
|
|||
export const REDOC_DIRECTIVES = [
|
||||
ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
||||
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc, SecurityDefinitions,
|
||||
LoadingBar
|
||||
LoadingBar, SideMenuItems
|
||||
];
|
||||
|
||||
export { ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
||||
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc, SecurityDefinitions,
|
||||
LoadingBar }
|
||||
LoadingBar, SideMenuItems }
|
||||
|
|
Loading…
Reference in New Issue
Block a user