Skip to content

Commit

Permalink
feat(共享模块): 添加菜单组件
Browse files Browse the repository at this point in the history
  • Loading branch information
jiayisheji committed Nov 7, 2017
1 parent 10db52b commit 40660ad
Show file tree
Hide file tree
Showing 14 changed files with 755 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/app/shared/menu/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './menu.module';
1 change: 1 addition & 0 deletions src/app/shared/menu/menu-item/menu-item.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<ng-content></ng-content>
57 changes: 57 additions & 0 deletions src/app/shared/menu/menu-item/menu-item.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
.menu-item {
line-height: 40px;
height: 40px;
list-style-type: disc;
list-style-position: inside;
border-right: 0;
margin-left: 0;
left: 0;
&:after {
content: "";
position: absolute;
right: 0;
top: 0;
bottom: 0;
border-right: 3px solid #1890ff;
transform: scaleY(0.0001);
opacity: 0;
transition: opacity 0.15s cubic-bezier(0.215, 0.61, 0.355, 1), transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
}
>a {
display: block;
color: rgba(0, 0, 0, 0.65);
&:before {
position: absolute;
background-color: transparent;
width: 100%;
height: 100%;
top: 0;
left: 0;
bottom: 0;
right: 0;
content: '';
}
&:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-image: radial-gradient(circle, #ffffff 10%, transparent 10.01%);
background-repeat: no-repeat;
background-size: 1000% 1000%;
background-position: 50%;
opacity: 0;
pointer-events: none;
transition: background .5s, opacity 1s;
}
&:active:after {
-webkit-background-size: 0% 0%;
background-size: 0% 0%;
opacity: .2;
transition: 0s;
}
}
}
25 changes: 25 additions & 0 deletions src/app/shared/menu/menu-item/menu-item.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { MenuItemComponent } from './menu-item.component';

describe('MenuItemComponent', () => {
let component: MenuItemComponent;
let fixture: ComponentFixture<MenuItemComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MenuItemComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(MenuItemComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
95 changes: 95 additions & 0 deletions src/app/shared/menu/menu-item/menu-item.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
Component,
AfterViewInit,
ViewEncapsulation,
Input,
HostBinding,
Renderer2,
Optional,
ElementRef,
ChangeDetectorRef
} from '@angular/core';
import { MenuComponent } from '../menu.component';
import { SubMenuComponent } from '../sub-menu/sub-menu.component';
import { Inject, HostListener } from '@angular/core';

@Component({
// tslint:disable-next-line:component-selector
selector: '[app-menu-item]',
templateUrl: './menu-item.component.html',
styleUrls: ['./menu-item.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class MenuItemComponent {
_selected: boolean;
_padding = 0;
@Input() disabled = false;
@Input()
set selected(value: boolean) {
this._selected = value;
if (value) {
this._renderer.addClass(this.hostElement.nativeElement, 'menu-item-selected');
} else {
this._renderer.removeClass(this.hostElement.nativeElement, 'menu-item-selected');
}
}

get selected() {
return this._selected;
}

/**
* 绑定类
*/
@HostBinding('class.menu-item')
get _setMenuItemClass() {
return true;
}

/**
* 绑定偏移距离
*/
@HostBinding('style.padding-left.px')
get setPaddingLeft() {
if (this.subMenu) {
/** if in sub menu component */
if (this.menu.mode === 'inline') {
/** if host menu's mode is inline add PADDING_BASE * level padding */
return (this.subMenu.level + 1) * this.PADDING_BASE;
} else {
/** return origin padding */
return this._padding;
}
} else if (this.menu.hasSubMenu && (this.menu.mode === 'inline')) {
/** not in sub menu component but root menu's mode is inline and contains submenu return default padding*/
return this.PADDING_BASE;
} else {
return this._padding;
}
}

/** clear all item selected status except this */
@HostListener('click', ['$event'])
_onClickItem() {
if (this.menu.clickActive && (!this.disabled)) {
this.menu.clearAllSelected();
this.selected = true;
}
}

constructor(
private menu: MenuComponent,
private _renderer: Renderer2,
public cd: ChangeDetectorRef,
private hostElement: ElementRef,
@Optional() private subMenu: SubMenuComponent,
@Inject('MENU_CONFIG_PADDING') private PADDING_BASE
) {
console.log('app-menu-item', this.PADDING_BASE);
this.menu.menuItems.push(this);
if (this.hostElement.nativeElement.style['padding-left']) {
this._padding = parseInt(this.hostElement.nativeElement.style['padding-left'], 10);
}
}

}
1 change: 1 addition & 0 deletions src/app/shared/menu/menu.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<ng-content></ng-content>
58 changes: 58 additions & 0 deletions src/app/shared/menu/menu.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.m-menu {
margin: 16px 0px;
width: 100%;
font-family: "Helvetica Neue For Number", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.5;
color: rgba(0, 0, 0, 0.65);
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
outline: none;
margin-bottom: 0;
padding-left: 0;
list-style: none;
z-index: 1050;
-webkit-box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
background: #fff;
-webkit-transition: background .3s, width .2s;
-o-transition: background .3s, width .2s;
transition: background .3s, width .2s;
zoom: 1;
&:before,
&:after {
content: " ";
display: table;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
.menu-item,
.menu-submenu,
.menu-submenu-title {
cursor: pointer;
}
}

.menu-item,
.menu-submenu-title {
margin-top: 4px;
margin-bottom: 4px;
position: relative;
display: block;
white-space: nowrap;
transition: color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), border-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), background 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), padding 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
.menu-icon {
min-width: 14px;
margin-right: 8px;
transition: font-size 0.15s cubic-bezier(0.215, 0.61, 0.355, 1), margin 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}

.menu-submenu .menu-sub {
cursor: initial;
transition: background 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
25 changes: 25 additions & 0 deletions src/app/shared/menu/menu.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { MenuComponent } from './menu.component';

describe('MenuComponent', () => {
let component: MenuComponent;
let fixture: ComponentFixture<MenuComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MenuComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(MenuComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

0 comments on commit 40660ad

Please sign in to comment.