├── .gitignore
├── LICENSE
├── README.md
├── demo
├── controllers
│ └── demo.js
├── index.html
├── resources
│ └── styles
│ │ └── demo.css
└── views
│ ├── item-1-1.html
│ ├── item-1-2.html
│ ├── item-2.html
│ ├── item-3-1.html
│ ├── item-3-2-1.html
│ ├── item-3-2-2-1.html
│ ├── item-4-1.html
│ ├── item-4-2.html
│ ├── item-4.html
│ └── readme.html
├── package.json
└── source
├── Makefile
├── angular-material-multilevel-menu.css
├── angular-material-multilevel-menu.html
└── angular-material-multilevel-menu.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | yarn.lock
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Juan Manuel Mouriz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-material-multilevel-menu
2 |
3 | Material Multi-Level Menu for AngularJS
4 |
5 | ## Demo
6 |
7 | View [online demo](https://jmouriz.github.io/angular-material-multilevel-menu/demo/demo.html)
8 |
9 | ## Main features
10 |
11 | - Breadcrumb
12 | - Interface with angular-route if available
13 |
14 | ## Install
15 |
16 | Download the package:
17 |
18 | ```
19 | yarn add angular-material-multilevel-menu
20 | ```
21 |
22 | ## Dependencies
23 |
24 | TODO
25 |
26 | ## Usage
27 |
28 | In your document head, include:
29 |
30 | ```html
31 |
32 | ```
33 |
34 | Use the md-multi-level-menu where you wish:
35 |
36 | ```html
37 |
40 |
41 | ```
42 |
43 | Then, just before close body tag, include:
44 |
45 | ```html
46 |
47 | ```
48 |
49 | Include the module in your application:
50 |
51 | ```javascript
52 | var application = angular.module('Application', ['ngMdMultiLevelMenu']);
53 | ```
54 |
55 | Configure the items:
56 |
57 | ```javascript
58 | application.config(['menuProvider', function(menuProvider) {
59 | menuProvider.items([{
60 | label: 'Item 1',
61 | icon: 'amazon',
62 | items: [{
63 | label: 'Item 1.1',
64 | link: 'item-1-1',
65 | icon: 'apple'
66 | }, {
67 | label: 'Item 1.2',
68 | link: 'item-1-2',
69 | icon: 'facebook'
70 | }]
71 | }, {
72 | label: 'Item 2',
73 | link: 'item-2',
74 | icon: 'windows'
75 | }, {
76 | label: 'Item 3',
77 | icon: 'google-plus',
78 | items: [{
79 | label: 'Item 3.1',
80 | link: 'item-3-1',
81 | icon: 'twitter'
82 | }, {
83 | label: 'Item 3.2',
84 | icon: 'github-box',
85 | items: [{
86 | label: 'Item 3.2.1',
87 | link: 'item-3-2-1',
88 | icon: 'whatsapp'
89 | }, {
90 | label: 'Item 3.2.2',
91 | icon: 'office',
92 | items: [{
93 | label: 'Item 3.2.2.1',
94 | link: 'item-3-2-2-1',
95 | icon: 'hangouts'
96 | }]
97 | }]
98 | }]
99 | }, {
100 | label: 'Item 4',
101 | link: 'item-4',
102 | icon: 'linkedin'
103 | hidden: false
104 | }]);
105 | }]);
106 | ```
107 |
108 | Finally, in your controller, configure the select callback of $menu service to handle the links:
109 |
110 | ```javascript
111 | application.controller('Controller', ['$menu', function($menu) {
112 | $menu.callback(function(item) {
113 | console.log('You are going to', item.link);
114 | });
115 | }]);
116 | ```
117 |
118 | ## Development install
119 |
120 | ```
121 | git clone https://github.com/jmouriz/angular-material-multilevel-menu.git
122 | cd angular-material-multilevel-menu
123 | yarn install
124 | cd source
125 | make
126 | ```
127 |
128 | TODO
129 |
--------------------------------------------------------------------------------
/demo/controllers/demo.js:
--------------------------------------------------------------------------------
1 | var $DEBUG = {};
2 |
3 | var demo = angular.module('Demo', ['ngMaterial', 'ngMdMultiLevelMenu', 'ngMdBadge', 'ngRoute', 'hc.marked']);
4 |
5 | demo.config(['menuProvider', function(menuProvider) {
6 | menuProvider.items('primary', [{
7 | label: 'Documentation',
8 | icon: 'import_contacts',
9 | link: 'demo/views/readme',
10 | color: 'blue'
11 | }, {
12 | id: 'item-1',
13 | label: 'Item 1: 3',
14 | icon: 'amazon',
15 | items: [{
16 | label: 'Item 1.1',
17 | link: 'demo/views/item-1-1',
18 | icon: 'apple'
19 | }, {
20 | label: 'Item 1.2',
21 | link: 'demo/views/item-1-2',
22 | icon: 'facebook'
23 | }]
24 | }, {
25 | id: 'item-2',
26 | label: 'Item 2',
27 | link: 'demo/views/item-2',
28 | icon: 'windows',
29 | badge: 3
30 | }, {
31 | label: 'Item 3',
32 | icon: 'google-plus',
33 | items: [{
34 | label: 'Item 3.1',
35 | link: 'demo/views/item-3-1',
36 | icon: 'twitter'
37 | }, {
38 | label: 'Item 3.2',
39 | icon: 'github-box',
40 | items: [{
41 | label: 'Item 3.2.1',
42 | link: 'demo/views/item-3-2-1',
43 | icon: 'whatsapp'
44 | }, {
45 | label: 'Item 3.2.2',
46 | icon: 'office',
47 | items: [{
48 | label: 'Item 3.2.2.1',
49 | link: 'demo/views/item-3-2-2-1',
50 | icon: 'hangouts'
51 | }]
52 | }]
53 | }]
54 | }, {
55 | id: 'item-4',
56 | label: 'Item 4',
57 | link: 'demo/views/item-4',
58 | icon: 'linkedin'
59 | }]);
60 |
61 | menuProvider.items('secondary', [{
62 | label: 'Documentation X',
63 | icon: 'import_contacts',
64 | link: 'demo/views/readme',
65 | color: 'blue'
66 | }, {
67 | id: 'item-1',
68 | label: 'Item 1: 3',
69 | icon: 'amazon',
70 | items: [{
71 | label: 'Item 1.1',
72 | link: 'demo/views/item-1-1',
73 | icon: 'apple'
74 | }, {
75 | label: 'Item 1.2',
76 | link: 'demo/views/item-1-2',
77 | icon: 'facebook'
78 | }]
79 | }, {
80 | id: 'item-2',
81 | label: 'Item 2',
82 | link: 'demo/views/item-2',
83 | icon: 'windows',
84 | badge: 3
85 | }, {
86 | label: 'Item 3',
87 | icon: 'google-plus',
88 | items: [{
89 | label: 'Item 3.1',
90 | link: 'demo/views/item-3-1',
91 | icon: 'twitter'
92 | }, {
93 | label: 'Item 3.2',
94 | icon: 'github-box',
95 | items: [{
96 | label: 'Item 3.2.1',
97 | link: 'demo/views/item-3-2-1',
98 | icon: 'whatsapp'
99 | }, {
100 | label: 'Item 3.2.2',
101 | icon: 'office',
102 | items: [{
103 | label: 'Item 3.2.2.1',
104 | link: 'demo/views/item-3-2-2-1',
105 | icon: 'hangouts'
106 | }]
107 | }]
108 | }]
109 | }, {
110 | id: 'item-4',
111 | label: 'Item 4',
112 | link: 'demo/views/item-4',
113 | icon: 'linkedin'
114 | }]);
115 | }]);
116 |
117 | demo.config(['markedProvider', function(markedProvider) {
118 | markedProvider.setOptions({
119 | gfm: true,
120 | tables: true,
121 | highlight: function(code, language) {
122 | if (!language) {
123 | language = 'bash';
124 | } else if (language == 'html') {
125 | language = 'markup';
126 | }
127 | return Prism.highlight(code, Prism.languages[language]);
128 | }
129 | });
130 | }]);
131 |
132 | demo.controller('Demo', ['$scope', '$menu', '$mdSidenav', '$mdBottomSheet', function($scope, $menu, $mdSidenav, $mdBottomSheet) {
133 | $scope.breadcrumb = $menu.breadcrumb();
134 | $scope.style = $menu.style();
135 | //$scope.count = $menu.get('item-2').badge;
136 |
137 | $scope.toggle = function() {
138 | $mdSidenav('left').toggle();
139 | $scope.icon = $scope.icon == 'menu' ? 'close' : 'menu';
140 | };
141 |
142 | $scope.test = function() {
143 | var item = $menu.get('primary', 'item-4');
144 | $DEBUG.menu = $menu;
145 | if (item.items) {
146 | item.items = undefined;
147 | } else {
148 | item.items = [{
149 | label: 'Item 4.1',
150 | link: 'demo/views/item-4-1',
151 | icon: 'favorite'
152 | }, {
153 | label: 'Item 4.2',
154 | link: 'demo/views/item-4-2',
155 | icon: 'grade'
156 | }]
157 | }
158 | };
159 |
160 | $scope.menu = function() {
161 | $mdBottomSheet.show({
162 | templateUrl: 'bottom-sheet-template',
163 | controller: function($scope) {}
164 | });
165 | };
166 |
167 | $menu.callback(function(item) {
168 | $scope.toggle();
169 | if (item.link) {
170 | console.log('You are going to', item.link);
171 | $mdBottomSheet.hide();
172 | }
173 | });
174 |
175 | $mdSidenav('left', true).then(function(instance) {
176 | $scope.icon = 'menu';
177 | instance.onClose(function () {
178 | $scope.icon = 'menu';
179 | });
180 | });
181 |
182 | $scope.$watch('count', function(value) {
183 | //$menu.get('item-2').badge = $scope.count;
184 | //$menu.get('item-1').label = 'Item 1: ' + $scope.count;
185 | });
186 |
187 | $scope.$watch('breadcrumb', function(value) {
188 | $menu.breadcrumb(value);
189 | });
190 |
191 | $scope.$watch('style', function(value) {
192 | $menu.style(value);
193 | });
194 | }]);
195 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AngularJS Material Multi Level Menu Demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | AngularJS Multilevel Menu Demo
23 |
24 |
25 |
26 |
27 |
32 |
33 |
34 |
35 |
36 |
37 | Replace
38 | Accordion
39 |
40 |
41 | Show breadcrumb
42 |
43 |
44 |
45 | Dynamic test
46 |
47 | Bottom bar
48 |
49 |
50 |
51 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/demo/resources/styles/demo.css:
--------------------------------------------------------------------------------
1 | md-sidenav {
2 | position: static;
3 | }
4 |
5 | md-bottom-sheet {
6 | overflow: hidden;
7 | padding-top: 0;
8 | padding-left: 0;
9 | padding-right: 0;
10 | }
11 |
12 | .content {
13 | padding: 16px;
14 | }
15 |
16 | pre {
17 | word-wrap: break-word;
18 | white-space: pre-wrap;
19 | }
20 |
--------------------------------------------------------------------------------
/demo/views/item-1-1.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-1-1"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/item-1-2.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-1-2"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/item-2.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-2"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/item-3-1.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-3-1"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/item-3-2-1.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-3-2-1"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/item-3-2-2-1.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-3-2-2-1"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/item-4-1.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-4-1"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/item-4-2.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-4-2"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/item-4.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to section "item-4"
3 |
4 |
--------------------------------------------------------------------------------
/demo/views/readme.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-material-multilevel-menu",
3 | "version": "1.5.2",
4 | "description": "Material Multi-Level Menu for AngularJS",
5 | "main": "angular-material-multilevel-menu.js",
6 | "repository": "https://github.com/jmouriz/angular-material-multilevel-menu",
7 | "author": "Juan Manuel ",
8 | "license": "MIT",
9 | "dependencies": {
10 | "angular": "^1.6.5",
11 | "angular-animate": "^1.6.5",
12 | "angular-aria": "^1.6.5",
13 | "angular-material": "^1.1.4",
14 | "angular-material-icons": "^0.7.1",
15 | "jquery": "^3.2.1"
16 | },
17 | "devDependencies": {
18 | "angular-marked": "^1.2.2",
19 | "angular-route": "^1.6.6",
20 | "minify": "^3.0.1",
21 | "prismjs": "^1.6.0"
22 | },
23 | "optionalDependencies": {
24 | "angular-material-badge": "^1.2.2",
25 | "svg-morpheus": "^0.3.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/source/Makefile:
--------------------------------------------------------------------------------
1 | PACKAGE := $(shell grep name ../package.json | head -1 | cut -d: -f2 | tr -d '" ,')
2 | BUILD := ../build
3 | SOURCE := $(PACKAGE)
4 | TARGET := $(BUILD)/$(PACKAGE).min
5 |
6 | all: $(TARGET).js $(TARGET).css $(TARGET).html
7 |
8 | $(TARGET).css: $(SOURCE).css
9 | @../node_modules/.bin/minify $< > $@
10 |
11 | $(TARGET).html: $(SOURCE).html
12 | @../node_modules/.bin/minify $< > $@
13 |
14 | $(TARGET).js: $(SOURCE).js
15 | @../node_modules/.bin/minify $< > $@
16 |
--------------------------------------------------------------------------------
/source/angular-material-multilevel-menu.css:
--------------------------------------------------------------------------------
1 | .menu-container {
2 | height: 100%;
3 | display: flex;
4 | flex-direction: column;
5 | }
6 |
7 | .menu {
8 | position: relative;
9 | width: 100%;
10 | min-height: 100%;
11 | left: 0;
12 | clip-path: inset(0 0 0 0);
13 | }
14 |
15 | .menu.ng-animate {
16 | transition: all cubic-bezier(.25, .46, .45, .95) .35s;
17 | }
18 |
19 | .menu.left {
20 | left: -100%;
21 | clip-path: inset(0 0 0 100%);
22 | }
23 |
24 | .menu.right {
25 | left: 100%;
26 | clip-path: inset(0 100% 0 0);
27 | }
28 |
29 | .submenu {
30 | margin-left: 16px;
31 | }
32 |
33 | .submenu.slide {
34 | position: relative;
35 | overflow: hidden;
36 | }
37 |
38 | .submenu.slide.ng-enter {
39 | animation: 1.35s down;
40 | }
41 |
42 | .submenu.slide.ng-leave {
43 | animation: .35s up;
44 | }
45 |
46 | @keyframes down {
47 | from {
48 | max-height: 0;
49 | }
50 | to {
51 | max-height: 100vh;
52 | }
53 | }
54 |
55 | @keyframes up {
56 | from {
57 | max-height: 100vh;
58 | }
59 | to {
60 | max-height: 0;
61 | }
62 | }
63 |
64 | a.breadcrumb,
65 | a.breadcrumb:visited {
66 | color: inherit;
67 | text-decoration: none;
68 | }
69 |
70 | md-list.body {
71 | padding-top: 0;
72 | padding-bottom: 0;
73 | }
74 |
--------------------------------------------------------------------------------
/source/angular-material-multilevel-menu.html:
--------------------------------------------------------------------------------
1 |