Skip to content

Commit e1aca4f

Browse files
committed
Merge pull request yannbf#21 from yannbf/feature/sidemenu
Adds custom sidemenu styles
2 parents 7f0573f + 289ea30 commit e1aca4f

File tree

18 files changed

+2338
-55
lines changed

18 files changed

+2338
-55
lines changed

src/app/app.component.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import { SideMenuPage } from '../pages/side-menu/side-menu';
12
import { IonicOfficialComponentsPage } from '../pages/ionic-official-components/ionic-official-components';
23
import { LoginListPage } from '../pages/login/login';
34
import { ThemingPage } from '../pages/theming/theming';
45
import { AppState } from './app.global';
5-
import { SlidesPage } from '../pages/slide/slide';
6+
// import { SlidesPage } from '../pages/slide/slide';
67
import { PopupModalsPage } from '../pages/popup-modal/popup-modal';
78
import { ListsPage } from '../pages/list/list';
89
import { PopupMenuListPage } from '../pages/popup-menu/popup-menu';
@@ -25,30 +26,44 @@ export class MyApp {
2526
rootPage: any = HomePage;
2627
activePage = new Subject();
2728

28-
pages: Array<{ title: string, component: any, active: boolean }>;
29+
pages: Array<{ title: string, component: any, active: boolean, icon: string }>;
30+
rightMenuItems: Array<{ icon: string, active: boolean }>;
2931
state: any;
3032

3133
constructor(public platform: Platform, public global: AppState) {
3234
this.initializeApp();
35+
this.rightMenuItems = [
36+
{ icon: 'home', active: true },
37+
{ icon: 'alarm', active: false },
38+
{ icon: 'analytics', active: false },
39+
{ icon: 'archive', active: false },
40+
{ icon: 'basket', active: false },
41+
{ icon: 'body', active: false },
42+
{ icon: 'bookmarks', active: false },
43+
{ icon: 'camera', active: false },
44+
{ icon: 'beer', active: false },
45+
{ icon: 'power', active: false },
46+
]
3347

3448
this.pages = [
35-
{ title: 'Home', component: HomePage, active: true },
36-
{ title: 'Ionic Official Components', component: IonicOfficialComponentsPage, active: false },
37-
{ title: 'Login', component: LoginListPage, active: false },
38-
{ title: 'Lists', component: ListsPage, active: false },
39-
{ title: 'Popup Modal', component: PopupModalsPage, active: false },
40-
{ title: 'Miscellaneous', component: MiscellaneousListPage, active: false },
41-
{ title: 'Popup Menu', component: PopupMenuListPage, active: false },
42-
{ title: 'Profile', component: ProfileListPage, active: false },
49+
{ title: 'Home', component: HomePage, active: true, icon: 'home' },
50+
{ title: 'Ionic Official Components', component: IonicOfficialComponentsPage, active: false, icon: 'alarm' },
51+
{ title: 'Login', component: LoginListPage, active: false, icon: 'archive' },
52+
{ title: 'Lists', component: ListsPage, active: false, icon: 'body' },
53+
{ title: 'Popup Modal', component: PopupModalsPage, active: false, icon: 'basket' },
54+
{ title: 'Miscellaneous', component: MiscellaneousListPage, active: false, icon: 'bookmarks' },
55+
{ title: 'Popup Menu', component: PopupMenuListPage, active: false, icon: 'beer' },
56+
{ title: 'Profile', component: ProfileListPage, active: false, icon: 'camera' },
57+
{ title: 'Side Menu', component: SideMenuPage, active: false, icon: 'bookmark' },
4358
// Removed for now as there were breaking changes in slides
4459
// { title: 'Slides', component: SlidesPage },
45-
{ title: 'Theming', component: ThemingPage, active: false },
60+
{ title: 'Theming', component: ThemingPage, active: false, icon: 'power' },
4661
];
4762

4863
this.activePage.subscribe((selectedPage: any) => {
49-
this.pages.map(page => {
50-
page.active = page.title === selectedPage.title;
51-
});
64+
this.pages.map(page => {
65+
page.active = page.title === selectedPage.title;
66+
});
5267
});
5368
}
5469

@@ -68,4 +83,9 @@ export class MyApp {
6883
this.nav.setRoot(page.component);
6984
this.activePage.next(page);
7085
}
86+
87+
rightMenuClick(item) {
88+
this.rightMenuItems.map(menuItem => menuItem.active = false);
89+
item.active = true;
90+
}
7191
}

src/app/app.html

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<div class="{{global.state['theme']}}">
2-
<ion-menu [content]="content" id="menu-components" class="animated-menu">
2+
<!--Default Menu-->
3+
<ion-menu [content]="content" id="menu-components">
34
<ion-header>
45
<ion-toolbar>
56
<ion-title>Menu</ion-title>
@@ -13,6 +14,64 @@
1314
</ion-list>
1415
</ion-content>
1516
</ion-menu>
17+
<!--Side Menu with avatar-->
18+
<ion-menu [content]="content" id="menu-avatar">
19+
<ion-content>
20+
<div #header>
21+
<ion-row style="align-items:center;">
22+
<ion-col width-25>
23+
<img src="assets/icon/icon-email.svg" />
24+
<span class="icon-badge">4</span>
25+
</ion-col>
26+
<ion-col width-50>
27+
<img class="user-avatar round" [src]="chosenPicture || placeholder" onerror="this.src='assets/img/avatar/girl-avatar.png'"
28+
/>
29+
</ion-col>
30+
<ion-col width-25>
31+
<img src="assets/icon/icon-calendar.svg" />
32+
</ion-col>
33+
</ion-row>
34+
<ion-row style="justify-content: center;">
35+
<h3>Paula Bolliger</h3>
36+
</ion-row>
37+
</div>
38+
<ion-list no-lines>
39+
<button menuClose ion-item detail-none *ngFor="let p of pages" (click)="openPage(p)">
40+
<!--<ion-icon [name]="p.icon" item-left></ion-icon>-->
41+
{{p.title}}
42+
</button>
43+
</ion-list>
44+
</ion-content>
45+
</ion-menu>
46+
<!--Right side menu-->
47+
<ion-menu side="right" type="push" [content]="content" id="menu-right">
48+
<ion-content>
49+
<ion-list no-lines>
50+
<button menuClose icon-only ion-item detail-none (click)="rightMenuClick(item)" *ngFor="let item of rightMenuItems; let i = index">
51+
<div *ngIf="item.active" class="active-menu-item"></div>
52+
<ion-icon [name]="item.icon"></ion-icon>
53+
</button>
54+
</ion-list>
55+
</ion-content>
56+
</ion-menu>
57+
<!--Material Design Menu-->
58+
<ion-menu [content]="content" id="menu-material">
59+
<ion-content>
60+
<ion-header class="menu-header">
61+
<!--material-design-background-->
62+
<img class="user-avatar round" [src]="chosenPicture || placeholder" onerror="this.src='assets/img/avatar/girl-avatar.png'"
63+
/>
64+
<p class="name">Paula Bolliger</p>
65+
<p class="e-mail">pbolliger@email.com</p>
66+
</ion-header>
67+
<ion-list no-lines>
68+
<button menuClose="left" ion-item detail-none *ngFor="let p of pages" (click)="openPage(p)">
69+
<ion-icon [name]="p.icon" item-left></ion-icon>
70+
{{p.title}}
71+
</button>
72+
</ion-list>
73+
</ion-content>
74+
</ion-menu>
1675
<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
1776
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
1877
</div>

src/app/app.imports.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { SideMenuPage } from '../pages/side-menu/side-menu';
12
// Global state (used for theming)
23
import { AppState } from './app.global';
34

@@ -156,6 +157,9 @@ export const Pages = [
156157
LoginSliderPage,
157158
LoginBackgroundVideoPage,
158159

160+
// Side Menu
161+
SideMenuPage,
162+
159163
// Miscellaneous
160164
MiscellaneousListPage,
161165
PopupMenuListPage,

src/app/app.scss

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
}
4444

4545
.round {
46-
border-radius: 3%;
46+
border-radius: 50%;
4747
}
4848

4949
.transparent-header {
@@ -69,3 +69,102 @@
6969
}
7070
// ---
7171
}
72+
73+
// right side menu
74+
#menu-right {
75+
button {
76+
padding-left: 16px;
77+
}
78+
ion-content {
79+
background: rgba(255, 36, 36, 0.82);
80+
}
81+
.menu-inner {
82+
width: 10vh;
83+
}
84+
.active-menu-item {
85+
position: absolute;
86+
border-top: 6px solid transparent;
87+
border-bottom: 6px solid transparent;
88+
border-left: 6px solid #ffffff;
89+
}
90+
.label {
91+
display: flex;
92+
align-items: center;
93+
}
94+
.list-md[no-lines] .item-block,
95+
.list-md[no-lines] ion-item-options,
96+
.list-md[no-lines] .item .item-inner,
97+
.list-ios[no-lines] .item-block,
98+
.list-ios[no-lines] ion-item-options,
99+
.list-ios[no-lines] .item .item-inner {
100+
padding: .3rem 0;
101+
background: transparent;
102+
color: white;
103+
}
104+
ion-icon {
105+
line-height: 1;
106+
}
107+
}
108+
109+
.icon-badge {
110+
top: 0px;
111+
right: 0px;
112+
background: #FF5D5D;
113+
color: white;
114+
font-size: 12px;
115+
position: absolute;
116+
padding: 5px 8px;
117+
border-radius: 15px;
118+
}
119+
120+
// Sidemenu with avatar
121+
#menu-avatar {
122+
.user-avatar {
123+
padding: .5em;
124+
}
125+
h3,
126+
.label {
127+
color: white;
128+
font-weight: bold;
129+
}
130+
.item {
131+
background: transparent;
132+
}
133+
ion-content {
134+
background: linear-gradient(48deg, rgba(157, 72, 173, 0.8) 0%, rgba(157, 72, 173, 0.86) 28%, rgba(0, 168, 168, 0.98) 93%, rgba(0, 168, 168, 1) 100%);
135+
}
136+
.menu-inner {
137+
background: rgba(255, 255, 255, .3);
138+
}
139+
}
140+
141+
// Material Design Sidemenu
142+
#menu-material {
143+
.menu-header {
144+
padding: 5px 15px;
145+
background-image: url('../assets/img/misc/material-design-background.jpg');
146+
background-size: cover;
147+
color: white;
148+
.name {
149+
font-weight: 500;
150+
margin-bottom: 3px;
151+
}
152+
.e-mail {
153+
margin-top: 0;
154+
margin-bottom: 5px;
155+
}
156+
}
157+
.user-avatar {
158+
padding: .5em;
159+
height: 12vh;
160+
}
161+
h3,
162+
.label,
163+
{
164+
color: #999;
165+
font-weight: 400;
166+
}
167+
ion-icon {
168+
color: #777;
169+
}
170+
}

0 commit comments

Comments
 (0)