@exmg/exm-navigation 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/exm-navigation-base.d.ts +34 -10
- package/src/exm-navigation-base.js +131 -87
- package/src/exm-navigation-drawer-nav-item-base.js +12 -8
- package/src/exm-navigation-icon-button-base.js +2 -0
- package/src/exm-navigation-sub-menu-base.d.ts +10 -0
- package/src/exm-navigation-sub-menu-base.js +71 -12
- package/src/exm-navigation-topbar-base.js +3 -4
- package/src/mixins/media-queries.d.ts +1 -0
- package/src/mixins/media-queries.js +14 -1
- package/src/styles/exm-navigation-css.js +8 -2
- package/src/styles/exm-navigation-drawer-nav-item-css.js +66 -23
- package/src/styles/exm-navigation-icon-button-css.js +5 -1
- package/src/styles/exm-navigation-sub-menu-css.js +5 -30
- package/src/styles/exm-navigation-topbar-css.js +1 -1
- package/src/exm-navigation-drawer-nav.d.ts +0 -9
- package/src/exm-navigation-drawer-nav.js +0 -47
- package/src/exm-navigation-rail-nav-base.d.ts +0 -4
- package/src/exm-navigation-rail-nav-base.js +0 -9
- package/src/exm-navigation-rail-nav.d.ts +0 -9
- package/src/exm-navigation-rail-nav.js +0 -12
- package/src/exm-navigation-signals.d.ts +0 -11
- package/src/exm-navigation-signals.js +0 -11
- package/src/exm-navigation-toolbar-base.d.ts +0 -8
- package/src/exm-navigation-toolbar-base.js +0 -33
- package/src/exm-navigation-toolbar.d.ts +0 -9
- package/src/exm-navigation-toolbar.js +0 -12
- package/src/styles/exm-navigate-drawer-nav-item-css.d.ts +0 -1
- package/src/styles/exm-navigate-drawer-nav-item-css.js +0 -40
- package/src/styles/exm-navigation-rail-nav-css.d.ts +0 -2
- package/src/styles/exm-navigation-rail-nav-css.js +0 -4
- package/src/styles/exm-navigation-styles-css.d.ts +0 -2
- package/src/styles/exm-navigation-styles-css.js +0 -4
- package/src/styles/exm-navigation-toolbar-css.d.ts +0 -2
- package/src/styles/exm-navigation-toolbar-css.js +0 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exmg/exm-navigation",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.js",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@exmg/lit-base": "^3.0.0",
|
|
22
|
+
"@lit-labs/motion": "^1.0.7",
|
|
22
23
|
"@material/mwc-drawer": "^0.27.0",
|
|
23
24
|
"@material/mwc-top-app-bar-fixed": "^0.27.0",
|
|
24
25
|
"@material/web": "^2.2.0",
|
|
@@ -51,5 +52,5 @@
|
|
|
51
52
|
"publishConfig": {
|
|
52
53
|
"access": "public"
|
|
53
54
|
},
|
|
54
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "5747be50ecb7c46ed349c74a6e8d66895d835455"
|
|
55
56
|
}
|
|
@@ -2,6 +2,8 @@ import { PropertyValues } from 'lit';
|
|
|
2
2
|
import { ExmgElement } from '@exmg/lit-base/index.js';
|
|
3
3
|
import { MenuItem } from './types.js';
|
|
4
4
|
import { ExmNavigationDrawer } from './exm-navigation-drawer.js';
|
|
5
|
+
import '@material/web/icon/icon.js';
|
|
6
|
+
import '@material/web/iconbutton/icon-button.js';
|
|
5
7
|
import './exm-navigation-icon-button.js';
|
|
6
8
|
import './exm-navigation-topbar.js';
|
|
7
9
|
import './exm-navigation-rail.js';
|
|
@@ -10,6 +12,7 @@ import './exm-navigation-drawer-menu.js';
|
|
|
10
12
|
import './exm-navigation-drawer.js';
|
|
11
13
|
declare const ExmNavigationBase_base: (new (...args: any[]) => {
|
|
12
14
|
media: "mobile" | "tablet" | "desktop";
|
|
15
|
+
touch: boolean;
|
|
13
16
|
}) & typeof ExmgElement;
|
|
14
17
|
export declare class ExmNavigationBase extends ExmNavigationBase_base {
|
|
15
18
|
items: MenuItem[];
|
|
@@ -18,32 +21,46 @@ export declare class ExmNavigationBase extends ExmNavigationBase_base {
|
|
|
18
21
|
disableNavigate: boolean;
|
|
19
22
|
drawer?: ExmNavigationDrawer;
|
|
20
23
|
navContent?: HTMLDivElement;
|
|
21
|
-
|
|
24
|
+
/**
|
|
25
|
+
* The menu item triggered by hovering and entering submenu's
|
|
26
|
+
* Once an item with endpoint is clicked, this value should be written to activeItem
|
|
27
|
+
*/
|
|
22
28
|
selectedItem: string[];
|
|
29
|
+
/**
|
|
30
|
+
* The currently active menu item
|
|
31
|
+
*/
|
|
23
32
|
activeItem: string[];
|
|
33
|
+
/**
|
|
34
|
+
* Wether or not the rail should be visible yes or no
|
|
35
|
+
*/
|
|
24
36
|
railOpen: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Wether or not the drawer should be visible yes or no
|
|
39
|
+
*/
|
|
25
40
|
drawerOpen: boolean;
|
|
26
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Object with menuitem and a bool for having that path sub items yes or no
|
|
43
|
+
*/
|
|
27
44
|
navigationHasSubmenu: Record<string, boolean>;
|
|
28
45
|
static styles: import("lit").CSSResult[];
|
|
29
|
-
menu: MenuItem[];
|
|
30
|
-
expandedItems: {
|
|
31
|
-
[k: string]: boolean;
|
|
32
|
-
};
|
|
33
|
-
unSubscribeSelected: () => void;
|
|
34
46
|
protected updated(changedProperties: PropertyValues): void;
|
|
35
47
|
protected firstUpdated(changedProperties: PropertyValues): void;
|
|
36
48
|
connectedCallback(): void;
|
|
37
49
|
/**
|
|
38
50
|
* Set the correct values when the media changes.
|
|
39
51
|
*/
|
|
40
|
-
handleMediaTypeChange
|
|
52
|
+
private handleMediaTypeChange;
|
|
41
53
|
private getPathEndpoint;
|
|
42
|
-
loadPage
|
|
54
|
+
private loadPage;
|
|
55
|
+
/**
|
|
56
|
+
* Handles the drawer state. If it should be open yes or no.
|
|
57
|
+
* @param param0
|
|
58
|
+
*/
|
|
59
|
+
handleDrawerOpen({ mobileForce, tabletForce }?: Record<string, boolean>): void;
|
|
43
60
|
/**
|
|
44
61
|
* Handle Rail item click or Drawer sub menu click.
|
|
45
62
|
* If the selected menu item has children, we add the first item to the list (as per Google implementation).
|
|
46
|
-
* In this case we also do not close the drawer in non
|
|
63
|
+
* In this case we also do not close the drawer in non desktop mode, so the user is able to select a next level in the menu
|
|
47
64
|
*/
|
|
48
65
|
private handleRailItemClick;
|
|
49
66
|
/**
|
|
@@ -102,6 +119,13 @@ export declare class ExmNavigationBase extends ExmNavigationBase_base {
|
|
|
102
119
|
* Render the topbar. This is displayed on mobile and contains the menu button and a slot for the title
|
|
103
120
|
*/
|
|
104
121
|
private renderTopbar;
|
|
122
|
+
/**
|
|
123
|
+
* If there is an active item, and that item has children, the width of the drawer should be set for desktop.
|
|
124
|
+
* This will push the content to the right.
|
|
125
|
+
*
|
|
126
|
+
* @returns the width of the drawer area
|
|
127
|
+
*/
|
|
128
|
+
private getDrawerWidth;
|
|
105
129
|
render(): import("lit-html").TemplateResult<1>;
|
|
106
130
|
}
|
|
107
131
|
export {};
|
|
@@ -6,6 +6,8 @@ import { styleMap } from 'lit/directives/style-map.js';
|
|
|
6
6
|
import { MediaQueries } from './mixins/media-queries.js';
|
|
7
7
|
import { classMap } from 'lit/directives/class-map.js';
|
|
8
8
|
import { style } from './styles/exm-navigation-css.js';
|
|
9
|
+
import '@material/web/icon/icon.js';
|
|
10
|
+
import '@material/web/iconbutton/icon-button.js';
|
|
9
11
|
import './exm-navigation-icon-button.js';
|
|
10
12
|
import './exm-navigation-topbar.js';
|
|
11
13
|
import './exm-navigation-rail.js';
|
|
@@ -20,16 +22,27 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
20
22
|
this.path = ['chat'];
|
|
21
23
|
this.drawerWidth = 319;
|
|
22
24
|
this.disableNavigate = false;
|
|
23
|
-
|
|
25
|
+
/**
|
|
26
|
+
* The menu item triggered by hovering and entering submenu's
|
|
27
|
+
* Once an item with endpoint is clicked, this value should be written to activeItem
|
|
28
|
+
*/
|
|
24
29
|
this.selectedItem = [];
|
|
30
|
+
/**
|
|
31
|
+
* The currently active menu item
|
|
32
|
+
*/
|
|
25
33
|
this.activeItem = [];
|
|
34
|
+
/**
|
|
35
|
+
* Wether or not the rail should be visible yes or no
|
|
36
|
+
*/
|
|
26
37
|
this.railOpen = true;
|
|
38
|
+
/**
|
|
39
|
+
* Wether or not the drawer should be visible yes or no
|
|
40
|
+
*/
|
|
27
41
|
this.drawerOpen = false;
|
|
28
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Object with menuitem and a bool for having that path sub items yes or no
|
|
44
|
+
*/
|
|
29
45
|
this.navigationHasSubmenu = {};
|
|
30
|
-
this.menu = [];
|
|
31
|
-
this.expandedItems = {};
|
|
32
|
-
this.unSubscribeSelected = () => { };
|
|
33
46
|
}
|
|
34
47
|
updated(changedProperties) {
|
|
35
48
|
if (changedProperties.has('media')) {
|
|
@@ -39,7 +52,7 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
39
52
|
for (const item of this.items) {
|
|
40
53
|
this.navigationHasSubmenu[item.id] = (item.items || []).length > 0;
|
|
41
54
|
}
|
|
42
|
-
if (this.navigationHasSubmenu[this.path[0]] && this.
|
|
55
|
+
if (this.navigationHasSubmenu[this.path[0]] && this.media === 'desktop') {
|
|
43
56
|
this.drawerOpen = true;
|
|
44
57
|
}
|
|
45
58
|
}
|
|
@@ -58,8 +71,7 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
58
71
|
* Set the correct values when the media changes.
|
|
59
72
|
*/
|
|
60
73
|
handleMediaTypeChange() {
|
|
61
|
-
this.
|
|
62
|
-
this.drawerOpen = this.media === 'desktop' && this.navigationHasSubmenu[this.selectedItem[0]];
|
|
74
|
+
this.drawerOpen = this.media === 'desktop' && this.navigationHasSubmenu[this.activeItem[0]];
|
|
63
75
|
this.railOpen = this.media !== 'mobile';
|
|
64
76
|
}
|
|
65
77
|
getPathEndpoint() {
|
|
@@ -68,7 +80,7 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
68
80
|
const checkItems = (path, last) => {
|
|
69
81
|
const item = items.find((item) => item.id === path);
|
|
70
82
|
if (last) {
|
|
71
|
-
return
|
|
83
|
+
return item === null || item === void 0 ? void 0 : item.path;
|
|
72
84
|
}
|
|
73
85
|
items = (item === null || item === void 0 ? void 0 : item.items) || [];
|
|
74
86
|
return;
|
|
@@ -76,91 +88,94 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
76
88
|
for (let i = 0; i < this.selectedItem.length; i++) {
|
|
77
89
|
result = checkItems(this.selectedItem[i], i === this.selectedItem.length - 1);
|
|
78
90
|
}
|
|
79
|
-
return result
|
|
91
|
+
return result;
|
|
80
92
|
}
|
|
81
93
|
loadPage(path) {
|
|
82
94
|
this.path = path;
|
|
83
|
-
this.
|
|
95
|
+
this.activeItem = path;
|
|
96
|
+
const endPoint = this.getPathEndpoint();
|
|
97
|
+
// If the route does not have a path, skip navigating
|
|
98
|
+
if (!endPoint) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
84
101
|
this.fire('navigation-change', path);
|
|
85
102
|
if (!this.disableNavigate) {
|
|
86
103
|
window.history.pushState({}, '', this.getPathEndpoint());
|
|
87
104
|
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
88
105
|
}
|
|
89
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Handles the drawer state. If it should be open yes or no.
|
|
109
|
+
* @param param0
|
|
110
|
+
*/
|
|
111
|
+
handleDrawerOpen({ mobileForce, tabletForce } = {}) {
|
|
112
|
+
if (this.media === 'mobile' || this.touch) {
|
|
113
|
+
// Only triggerable by button
|
|
114
|
+
if (mobileForce || !this.navigationHasSubmenu[this.activeItem[0]]) {
|
|
115
|
+
this.drawerOpen = false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (this.media === 'tablet') {
|
|
119
|
+
if (tabletForce) {
|
|
120
|
+
this.drawerOpen = false;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
this.drawerOpen = this.navigationHasSubmenu[this.selectedItem[0]];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (this.media === 'desktop') {
|
|
127
|
+
if (this.navigationHasSubmenu[this.activeItem[0]]) {
|
|
128
|
+
this.drawerOpen = true;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
this.drawerOpen = this.navigationHasSubmenu[this.selectedItem[0]];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
90
135
|
/**
|
|
91
136
|
* Handle Rail item click or Drawer sub menu click.
|
|
92
137
|
* If the selected menu item has children, we add the first item to the list (as per Google implementation).
|
|
93
|
-
* In this case we also do not close the drawer in non
|
|
138
|
+
* In this case we also do not close the drawer in non desktop mode, so the user is able to select a next level in the menu
|
|
94
139
|
*/
|
|
95
140
|
handleRailItemClick({ detail }) {
|
|
96
141
|
var _a;
|
|
97
|
-
if (this.
|
|
142
|
+
if (this.activeItem[0] !== detail || this.media === 'mobile') {
|
|
98
143
|
const items = ((_a = this.items.find((item) => item.id === detail)) === null || _a === void 0 ? void 0 : _a.items) || [];
|
|
99
|
-
if (items.length) {
|
|
144
|
+
if (items.length && !this.touch) {
|
|
100
145
|
this.selectedItem = [detail, items[0].id];
|
|
101
146
|
}
|
|
102
147
|
else {
|
|
103
148
|
this.selectedItem = [detail];
|
|
104
149
|
}
|
|
105
|
-
// copy the selected item to the active item
|
|
106
|
-
this.activeItem = this.selectedItem;
|
|
107
|
-
/**
|
|
108
|
-
* If persistent menu close the drawer when a item is clicked and does not has children items
|
|
109
|
-
*/
|
|
110
|
-
if (this.persistent) {
|
|
111
|
-
this.drawerOpen = items.length > 0 || this.navigationHasSubmenu[detail];
|
|
112
|
-
}
|
|
113
|
-
else if (items.length === 0) {
|
|
114
|
-
this.drawerOpen = false;
|
|
115
|
-
}
|
|
116
150
|
this.loadPage(this.selectedItem);
|
|
151
|
+
this.handleDrawerOpen();
|
|
117
152
|
}
|
|
118
153
|
}
|
|
119
154
|
/**
|
|
120
155
|
* Handle the mouse enter of the rail item.
|
|
121
156
|
*/
|
|
122
157
|
handleRailItemMouseEnter({ detail }) {
|
|
123
|
-
if (this.
|
|
124
|
-
|
|
125
|
-
if (detail !== this.selectedItem[0]) {
|
|
126
|
-
this.activeItem = [detail];
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else if (this.navigationHasSubmenu[this.selectedItem[0]] && this.persistent) {
|
|
131
|
-
this.activeItem = this.selectedItem;
|
|
132
|
-
this.drawerOpen = true;
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
this.activeItem = this.selectedItem;
|
|
136
|
-
this.drawerOpen = false;
|
|
158
|
+
if (this.touch) {
|
|
159
|
+
return;
|
|
137
160
|
}
|
|
138
|
-
this.
|
|
161
|
+
this.selectedItem = [detail];
|
|
162
|
+
this.handleDrawerOpen();
|
|
139
163
|
}
|
|
140
164
|
/**
|
|
141
165
|
* Handle the mouse leave of the rail item.
|
|
142
166
|
* If the item has no submenu and the current selected item has no submenu, it is safe to close the drawer
|
|
143
167
|
*/
|
|
144
|
-
handleRailItemMouseLeave({
|
|
145
|
-
if (!this.navigationHasSubmenu[detail] && !this.navigationHasSubmenu[this.selectedItem[0]]) {
|
|
146
|
-
this.drawerOpen = false;
|
|
147
|
-
}
|
|
148
|
-
if (!this.persistent && !this.navigationHasSubmenu[detail]) {
|
|
149
|
-
this.drawerOpen = false;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
168
|
+
handleRailItemMouseLeave() { }
|
|
152
169
|
/**
|
|
153
170
|
* Handle drawer mouse leave. Should close the drawer
|
|
154
171
|
*/
|
|
155
172
|
handleDrawerMouseLeave() {
|
|
156
|
-
if (!this.navigationHasSubmenu[this.selectedItem[0]] || !this.persistent) {
|
|
157
|
-
this.drawerOpen = false;
|
|
158
|
-
}
|
|
159
173
|
/**
|
|
160
174
|
* On mouse leave the drawer we want to set the active item to the selected item.
|
|
161
175
|
* If not, it will show the active item on every hover and will make navigating in the selected item impossible
|
|
162
176
|
*/
|
|
163
|
-
this.
|
|
177
|
+
this.selectedItem = this.activeItem;
|
|
178
|
+
this.handleDrawerOpen({ tabletForce: true });
|
|
164
179
|
}
|
|
165
180
|
/**
|
|
166
181
|
* Handle the click on a sub menu item
|
|
@@ -169,11 +184,13 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
169
184
|
*/
|
|
170
185
|
handleSubMenuClick({ detail }) {
|
|
171
186
|
this.selectedItem = detail;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
187
|
+
const endPoint = this.getPathEndpoint();
|
|
188
|
+
let mobileForce = false;
|
|
189
|
+
if (endPoint) {
|
|
190
|
+
this.loadPage(this.selectedItem);
|
|
191
|
+
mobileForce = true;
|
|
175
192
|
}
|
|
176
|
-
this.
|
|
193
|
+
this.handleDrawerOpen({ mobileForce, tabletForce: this.touch && !!endPoint });
|
|
177
194
|
}
|
|
178
195
|
/**
|
|
179
196
|
* Handle the topbar menu click.
|
|
@@ -187,7 +204,7 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
187
204
|
* This should reset the active item, so the root-level menu gets triggered
|
|
188
205
|
*/
|
|
189
206
|
handleDrawerBackClick() {
|
|
190
|
-
this.
|
|
207
|
+
this.selectedItem = [];
|
|
191
208
|
}
|
|
192
209
|
/**
|
|
193
210
|
* Check if the passed paths last item has children yes or no
|
|
@@ -209,10 +226,9 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
209
226
|
return !this.railOpen
|
|
210
227
|
? html `
|
|
211
228
|
<section class="drawer-menu-button">
|
|
212
|
-
<
|
|
213
|
-
icon
|
|
214
|
-
|
|
215
|
-
></exm-navigation-icon-button>
|
|
229
|
+
<md-icon-button @click=${this.handleTopbarMenuClick}>
|
|
230
|
+
<md-icon>${this.drawerOpen ? 'menu_open' : 'menu'}</md-icon>
|
|
231
|
+
</md-icon-button>
|
|
216
232
|
</section>
|
|
217
233
|
`
|
|
218
234
|
: nothing;
|
|
@@ -222,37 +238,60 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
222
238
|
* If more levels deep, show the back button
|
|
223
239
|
*/
|
|
224
240
|
renderStartMenu() {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
241
|
+
if (this.railOpen) {
|
|
242
|
+
return nothing;
|
|
243
|
+
}
|
|
244
|
+
return this.selectedItem.length === 0 ||
|
|
245
|
+
(this.selectedItem.length === 1 && !this.currentSelectedHasChildren(this.selectedItem))
|
|
228
246
|
? html `<exm-navigation-drawer-menu
|
|
229
247
|
.items=${this.items}
|
|
230
248
|
.path=${this.activeItem}
|
|
231
249
|
@drawer-menu-item-click=${this.handleRailItemClick}
|
|
232
250
|
></exm-navigation-drawer-menu>`
|
|
233
|
-
:
|
|
234
|
-
|
|
235
|
-
<
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
`
|
|
243
|
-
: nothing;
|
|
251
|
+
: html `
|
|
252
|
+
<section class="drawer-back-button">
|
|
253
|
+
<exm-navigation-icon-button
|
|
254
|
+
icon="arrow_back"
|
|
255
|
+
label="Main menu"
|
|
256
|
+
@navigation-icon-button-click=${this.handleDrawerBackClick}
|
|
257
|
+
></exm-navigation-icon-button>
|
|
258
|
+
</section>
|
|
259
|
+
`;
|
|
244
260
|
}
|
|
245
261
|
/**
|
|
246
262
|
* return the sub menus. More then 1 level deep
|
|
247
263
|
*/
|
|
248
264
|
renderDrawerSubMenu() {
|
|
265
|
+
/**
|
|
266
|
+
* When the selected item is empty we do not display the submenu on mobile
|
|
267
|
+
*/
|
|
268
|
+
if (this.selectedItem.length === 0 && this.media === 'mobile') {
|
|
269
|
+
return nothing;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Do we have all items of the selectedItem available in the active Item
|
|
273
|
+
*/
|
|
274
|
+
const selectedInActive = this.selectedItem.reduce((_, item, index) => {
|
|
275
|
+
if (item === this.activeItem[index]) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
return false;
|
|
279
|
+
}, false);
|
|
280
|
+
/**
|
|
281
|
+
* Determine the data to use for the submenu. This is needed to show the correct selected items in the submenu of the drawer
|
|
282
|
+
* If all selected Items ar in the active item, show the active item
|
|
283
|
+
* If the selected item haas no children, but the drawer is open, show the active item
|
|
284
|
+
* In all the other cases we use the selected item
|
|
285
|
+
*/
|
|
286
|
+
const selected = selectedInActive || (!this.navigationHasSubmenu[this.selectedItem[0]] && this.drawerOpen)
|
|
287
|
+
? this.activeItem
|
|
288
|
+
: this.selectedItem;
|
|
249
289
|
return html `
|
|
250
290
|
<exm-navigation-sub-menu
|
|
251
291
|
.items=${this.items}
|
|
252
|
-
.path=${
|
|
292
|
+
.path=${selected}
|
|
253
293
|
?has-back-button=${!this.railOpen &&
|
|
254
|
-
(
|
|
255
|
-
(this.activeItem.length > 0 && this.currentSelectedHasChildren(this.activeItem)))}
|
|
294
|
+
(selected.length > 1 || (selected.length > 0 && this.currentSelectedHasChildren(selected)))}
|
|
256
295
|
@sub-menu-item-click=${this.handleSubMenuClick}
|
|
257
296
|
></exm-navigation-sub-menu>
|
|
258
297
|
`;
|
|
@@ -263,7 +302,7 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
263
302
|
renderRail() {
|
|
264
303
|
return html `<exm-navigation-rail
|
|
265
304
|
.items=${this.items}
|
|
266
|
-
.selected=${this.
|
|
305
|
+
.selected=${this.activeItem}
|
|
267
306
|
@rail-item-click=${this.handleRailItemClick}
|
|
268
307
|
@rail-item-mouseenter=${this.handleRailItemMouseEnter}
|
|
269
308
|
@rail-item-mouseleave=${this.handleRailItemMouseLeave}
|
|
@@ -281,10 +320,21 @@ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
|
|
|
281
320
|
<slot name="topbar-actions" slot="topbar-actions"></slot>
|
|
282
321
|
</exm-navigation-topbar>`;
|
|
283
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* If there is an active item, and that item has children, the width of the drawer should be set for desktop.
|
|
325
|
+
* This will push the content to the right.
|
|
326
|
+
*
|
|
327
|
+
* @returns the width of the drawer area
|
|
328
|
+
*/
|
|
329
|
+
getDrawerWidth() {
|
|
330
|
+
if (this.media === 'desktop' && this.activeItem.length > 0 && this.navigationHasSubmenu[this.activeItem[0]]) {
|
|
331
|
+
return this.drawerWidth;
|
|
332
|
+
}
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
284
335
|
render() {
|
|
285
|
-
var _a;
|
|
286
336
|
const containerStyle = {
|
|
287
|
-
'--exm-drawer-width': `${
|
|
337
|
+
'--exm-drawer-width': `${this.getDrawerWidth()}px`,
|
|
288
338
|
};
|
|
289
339
|
const containerClass = { 'show-topbar': !this.railOpen };
|
|
290
340
|
return html `
|
|
@@ -323,9 +373,6 @@ __decorate([
|
|
|
323
373
|
__decorate([
|
|
324
374
|
query('#navigation-container')
|
|
325
375
|
], ExmNavigationBase.prototype, "navContent", void 0);
|
|
326
|
-
__decorate([
|
|
327
|
-
state()
|
|
328
|
-
], ExmNavigationBase.prototype, "persistent", void 0);
|
|
329
376
|
__decorate([
|
|
330
377
|
state()
|
|
331
378
|
], ExmNavigationBase.prototype, "selectedItem", void 0);
|
|
@@ -338,9 +385,6 @@ __decorate([
|
|
|
338
385
|
__decorate([
|
|
339
386
|
state()
|
|
340
387
|
], ExmNavigationBase.prototype, "drawerOpen", void 0);
|
|
341
|
-
__decorate([
|
|
342
|
-
state()
|
|
343
|
-
], ExmNavigationBase.prototype, "drawerHover", void 0);
|
|
344
388
|
__decorate([
|
|
345
389
|
state()
|
|
346
390
|
], ExmNavigationBase.prototype, "navigationHasSubmenu", void 0);
|
|
@@ -6,6 +6,7 @@ import '@material/web/focus/md-focus-ring.js';
|
|
|
6
6
|
import './exm-navigation-icon.js';
|
|
7
7
|
import '@material/web/list/list.js';
|
|
8
8
|
import '@material/web/list/list-item.js';
|
|
9
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
9
10
|
export class ExmNavigationDrawerNavItemBase extends LitElement {
|
|
10
11
|
constructor() {
|
|
11
12
|
super(...arguments);
|
|
@@ -15,15 +16,18 @@ export class ExmNavigationDrawerNavItemBase extends LitElement {
|
|
|
15
16
|
this.submenuIcon = 'arrow_forward';
|
|
16
17
|
}
|
|
17
18
|
render() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const classList = { selected: this.selected, 'has-sub-menu': this.hasSubmenu, 'has-icon': !!this.icon };
|
|
20
|
+
return html `
|
|
21
|
+
<button class="${classMap(classList)}">
|
|
22
|
+
${this.icon ? html `<exm-navigation-icon class="item-icon" icon=${this.icon}></exm-navigation-icon>` : nothing}
|
|
23
|
+
<span class="label"><slot></slot></span>
|
|
24
|
+
${this.hasSubmenu
|
|
25
|
+
? html `<exm-navigation-icon class="has-submenu" icon=${this.submenuIcon}></exm-navigation-icon>`
|
|
21
26
|
: nothing}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
</md-list-item>`;
|
|
27
|
+
<md-ripple part="ripple"></md-ripple>
|
|
28
|
+
<md-focus-ring part="focus-ring" inward></md-focus-ring>
|
|
29
|
+
</button>
|
|
30
|
+
`;
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
33
|
ExmNavigationDrawerNavItemBase.styles = [style];
|
|
@@ -20,6 +20,8 @@ export class ExmNavigationIconButtonBase extends ExmgElement {
|
|
|
20
20
|
<button class="icon-button ${classMap(buttonClass)}" @click=${this.handleMenuButtonClick}>
|
|
21
21
|
<exm-navigation-icon icon=${this.icon}></exm-navigation-icon>
|
|
22
22
|
${this.label ? html ` <span class="label">${this.label}</span>` : nothing}
|
|
23
|
+
<md-ripple part="ripple"></md-ripple>
|
|
24
|
+
<md-focus-ring part="focus-ring" inward></md-focus-ring>
|
|
23
25
|
</button>
|
|
24
26
|
`;
|
|
25
27
|
}
|
|
@@ -10,9 +10,19 @@ export declare class ExmNavigationSubMenuBase extends ExmgElement {
|
|
|
10
10
|
path: (string | null)[];
|
|
11
11
|
hasBackButton: boolean;
|
|
12
12
|
currentItem?: MenuItem['items'];
|
|
13
|
+
static itemIndex: number;
|
|
14
|
+
navigationElement?: HTMLElement;
|
|
13
15
|
static styles: import("lit").CSSResult[];
|
|
14
16
|
protected updated(changedProperties: PropertyValues): void;
|
|
17
|
+
connectedCallback(): void;
|
|
18
|
+
disconnectedCallback(): void;
|
|
15
19
|
private handleSubMenuItemClick;
|
|
20
|
+
/**
|
|
21
|
+
* If a collapsable menuitem is not selected we can just pass the path.
|
|
22
|
+
* If it is selected, we remove the item from the path to collapse the menu again
|
|
23
|
+
*/
|
|
24
|
+
private handleCollapsableSubMenuItemClick;
|
|
25
|
+
private getItemStyle;
|
|
16
26
|
private renderSubMenu;
|
|
17
27
|
render(): import("lit-html").TemplateResult<1>;
|
|
18
28
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { html } from 'lit';
|
|
3
3
|
import { ExmgElement } from '@exmg/lit-base/index.js';
|
|
4
|
-
import { property, state } from 'lit/decorators.js';
|
|
4
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
5
5
|
import { repeat } from 'lit/directives/repeat.js';
|
|
6
6
|
import { style } from './styles/exm-navigation-sub-menu-css.js';
|
|
7
|
+
import { animate, fadeOut, fadeIn } from '@lit-labs/motion';
|
|
7
8
|
import './exm-navigation-rail-nav-item.js';
|
|
8
9
|
import './exm-navigation-drawer-nav-item.js';
|
|
9
10
|
import '@material/web/list/list.js';
|
|
10
11
|
import '@exmg/exm-collapsed/exm-collapsed.js';
|
|
11
12
|
import { classMap } from 'lit/directives/class-map.js';
|
|
13
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
12
14
|
export class ExmNavigationSubMenuBase extends ExmgElement {
|
|
13
15
|
constructor() {
|
|
14
16
|
super(...arguments);
|
|
@@ -19,20 +21,55 @@ export class ExmNavigationSubMenuBase extends ExmgElement {
|
|
|
19
21
|
updated(changedProperties) {
|
|
20
22
|
var _a;
|
|
21
23
|
if (changedProperties.has('path') || changedProperties.has('items')) {
|
|
22
|
-
console.log('updated', this.path);
|
|
23
24
|
this.currentItem = ((_a = this.items.find((item) => item.id === this.path[0])) === null || _a === void 0 ? void 0 : _a.items) || [];
|
|
24
25
|
}
|
|
25
26
|
}
|
|
27
|
+
connectedCallback() {
|
|
28
|
+
super.connectedCallback();
|
|
29
|
+
}
|
|
30
|
+
disconnectedCallback() {
|
|
31
|
+
if (this.navigationElement) {
|
|
32
|
+
this.navigationElement.classList.remove('show');
|
|
33
|
+
}
|
|
34
|
+
super.disconnectedCallback();
|
|
35
|
+
}
|
|
26
36
|
handleSubMenuItemClick(path) {
|
|
27
37
|
this.fire('sub-menu-item-click', path);
|
|
28
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* If a collapsable menuitem is not selected we can just pass the path.
|
|
41
|
+
* If it is selected, we remove the item from the path to collapse the menu again
|
|
42
|
+
*/
|
|
43
|
+
handleCollapsableSubMenuItemClick(path, id, selected) {
|
|
44
|
+
if (!selected) {
|
|
45
|
+
this.handleSubMenuItemClick(path);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const index = path.findIndex((item) => item === id);
|
|
49
|
+
this.fire('sub-menu-item-click', path.splice(0, index));
|
|
50
|
+
}
|
|
51
|
+
getItemStyle() {
|
|
52
|
+
return {
|
|
53
|
+
'grid-area': `${ExmNavigationSubMenuBase.itemIndex}/1/${ExmNavigationSubMenuBase.itemIndex + 1}/2`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
29
56
|
renderSubMenu(item, path) {
|
|
57
|
+
const selected = this.path.includes(item.id);
|
|
30
58
|
return html `
|
|
31
59
|
<exm-navigation-drawer-nav-item
|
|
60
|
+
${animate({
|
|
61
|
+
keyframeOptions: {
|
|
62
|
+
duration: 300,
|
|
63
|
+
},
|
|
64
|
+
out: fadeOut,
|
|
65
|
+
in: fadeIn,
|
|
66
|
+
properties: ['opacity'],
|
|
67
|
+
})}
|
|
68
|
+
style=${styleMap(this.getItemStyle())}
|
|
32
69
|
type="button"
|
|
33
|
-
?selected=${
|
|
34
|
-
class="has-submenu"
|
|
35
|
-
@click=${this.
|
|
70
|
+
?selected=${selected}
|
|
71
|
+
class="has-submenu ${this.path.includes(item.id) ? 'selected' : ''}"
|
|
72
|
+
@click=${this.handleCollapsableSubMenuItemClick.bind(this, [...path], item.id, selected)}
|
|
36
73
|
?has-submenu=${true}
|
|
37
74
|
submenu-icon=${this.path.includes(item.id) ? 'expand_less' : 'expand_more'}
|
|
38
75
|
>${item.label}
|
|
@@ -41,9 +78,12 @@ export class ExmNavigationSubMenuBase extends ExmgElement {
|
|
|
41
78
|
<div class="sub-menu">
|
|
42
79
|
<md-list>
|
|
43
80
|
<!-- Need to check for multiple items -->
|
|
44
|
-
${(item.items || []).map((subItem) =>
|
|
45
|
-
|
|
81
|
+
${(item.items || []).map((subItem) => {
|
|
82
|
+
ExmNavigationSubMenuBase.itemIndex += 1;
|
|
83
|
+
return (subItem.items || []).length === 0
|
|
84
|
+
? html `
|
|
46
85
|
<exm-navigation-drawer-nav-item
|
|
86
|
+
style=${styleMap(this.getItemStyle())}
|
|
47
87
|
class="collapsed-item"
|
|
48
88
|
?selected=${this.path.includes(subItem.id)}
|
|
49
89
|
@click=${this.handleSubMenuItemClick.bind(this, [...path, subItem.id])}
|
|
@@ -51,7 +91,8 @@ export class ExmNavigationSubMenuBase extends ExmgElement {
|
|
|
51
91
|
${subItem.label}
|
|
52
92
|
</exm-navigation-drawer-nav-item>
|
|
53
93
|
`
|
|
54
|
-
|
|
94
|
+
: this.renderSubMenu(item, [this.path[0] || '', item.id]);
|
|
95
|
+
})}
|
|
55
96
|
</md-list>
|
|
56
97
|
</div>
|
|
57
98
|
</exm-collapsed>
|
|
@@ -59,12 +100,25 @@ export class ExmNavigationSubMenuBase extends ExmgElement {
|
|
|
59
100
|
}
|
|
60
101
|
render() {
|
|
61
102
|
const navClass = { nav: true, 'has-back-button': this.hasBackButton };
|
|
103
|
+
ExmNavigationSubMenuBase.itemIndex = 0;
|
|
62
104
|
return html `<div class="top"><slot name="top"></slot></div>
|
|
63
|
-
<nav class=${classMap(navClass)}>
|
|
105
|
+
<nav id="exm-navigation-sub-menu" class=${classMap(navClass)}>
|
|
64
106
|
<md-list>
|
|
65
|
-
${repeat(this.currentItem || [], ({ id }) => id, (item) =>
|
|
66
|
-
|
|
107
|
+
${repeat(this.currentItem || [], ({ id }) => id, (item) => {
|
|
108
|
+
ExmNavigationSubMenuBase.itemIndex += 1;
|
|
109
|
+
return (item.items || []).length === 0
|
|
110
|
+
? html `
|
|
67
111
|
<exm-navigation-drawer-nav-item
|
|
112
|
+
${animate({
|
|
113
|
+
keyframeOptions: {
|
|
114
|
+
duration: 300,
|
|
115
|
+
},
|
|
116
|
+
stabilizeOut: true,
|
|
117
|
+
out: fadeOut,
|
|
118
|
+
in: fadeIn,
|
|
119
|
+
properties: ['opacity'],
|
|
120
|
+
})}
|
|
121
|
+
style="${styleMap(this.getItemStyle())}"
|
|
68
122
|
type="button"
|
|
69
123
|
?selected=${this.path.includes(item.id)}
|
|
70
124
|
@click=${this.handleSubMenuItemClick.bind(this, [this.path[0] || '', item.id])}
|
|
@@ -72,12 +126,14 @@ export class ExmNavigationSubMenuBase extends ExmgElement {
|
|
|
72
126
|
${item.label}
|
|
73
127
|
</exm-navigation-drawer-nav-item>
|
|
74
128
|
`
|
|
75
|
-
|
|
129
|
+
: this.renderSubMenu(item, [this.path[0] || '', item.id]);
|
|
130
|
+
})}
|
|
76
131
|
</md-list>
|
|
77
132
|
</nav>
|
|
78
133
|
<div class="bottom"><slot name="bottom"></slot></div>`;
|
|
79
134
|
}
|
|
80
135
|
}
|
|
136
|
+
ExmNavigationSubMenuBase.itemIndex = 0;
|
|
81
137
|
ExmNavigationSubMenuBase.styles = [style];
|
|
82
138
|
__decorate([
|
|
83
139
|
property({ type: Array })
|
|
@@ -91,4 +147,7 @@ __decorate([
|
|
|
91
147
|
__decorate([
|
|
92
148
|
state()
|
|
93
149
|
], ExmNavigationSubMenuBase.prototype, "currentItem", void 0);
|
|
150
|
+
__decorate([
|
|
151
|
+
query('nav')
|
|
152
|
+
], ExmNavigationSubMenuBase.prototype, "navigationElement", void 0);
|
|
94
153
|
//# sourceMappingURL=exm-navigation-sub-menu-base.js.map
|
|
@@ -15,10 +15,9 @@ export class ExmNavigationTopbarBase extends ExmgElement {
|
|
|
15
15
|
}
|
|
16
16
|
render() {
|
|
17
17
|
return html `
|
|
18
|
-
<
|
|
19
|
-
icon
|
|
20
|
-
|
|
21
|
-
></exm-navigation-icon-button>
|
|
18
|
+
<md-icon-button @click=${this.handleMenuButtonClick}
|
|
19
|
+
><md-icon>${this.drawerOpen ? 'menu_open' : 'menu'}</md-icon></md-icon-button
|
|
20
|
+
>
|
|
22
21
|
<slot name="topbar-title" class="topbar-title"></slot>
|
|
23
22
|
<slot name="topbar-actions"></slot>
|
|
24
23
|
`;
|
|
@@ -5,9 +5,11 @@ export const MediaQueries = (superClass) => {
|
|
|
5
5
|
constructor() {
|
|
6
6
|
super(...arguments);
|
|
7
7
|
this.media = 'desktop';
|
|
8
|
+
this.touch = false;
|
|
8
9
|
this.mobileMedia = window.matchMedia('(max-width: 960px)');
|
|
9
10
|
this.tabletMedia = window.matchMedia('(min-width: 961px) and (max-width: 1200px)');
|
|
10
11
|
this.desktopMedia = window.matchMedia('(min-width: 1201px)');
|
|
12
|
+
this.hoverMedia = window.matchMedia('(hover: hover)');
|
|
11
13
|
}
|
|
12
14
|
updateMedia(media) {
|
|
13
15
|
return (mediaMatch) => {
|
|
@@ -17,6 +19,12 @@ export const MediaQueries = (superClass) => {
|
|
|
17
19
|
}
|
|
18
20
|
};
|
|
19
21
|
}
|
|
22
|
+
updateTouch() {
|
|
23
|
+
return (mediaMatch) => {
|
|
24
|
+
this.touch = !mediaMatch.matches;
|
|
25
|
+
this.requestUpdate();
|
|
26
|
+
};
|
|
27
|
+
}
|
|
20
28
|
connectedCallback() {
|
|
21
29
|
super.connectedCallback();
|
|
22
30
|
// @ts-ignore
|
|
@@ -25,10 +33,12 @@ export const MediaQueries = (superClass) => {
|
|
|
25
33
|
this.updateMedia('tablet')(this.tabletMedia);
|
|
26
34
|
// @ts-ignore
|
|
27
35
|
this.updateMedia('desktop')(this.desktopMedia);
|
|
28
|
-
//
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
this.updateTouch()(this.hoverMedia);
|
|
29
38
|
this.mobileMedia.addEventListener('change', this.updateMedia('mobile').bind(this));
|
|
30
39
|
this.tabletMedia.addEventListener('change', this.updateMedia('tablet').bind(this));
|
|
31
40
|
this.desktopMedia.addEventListener('change', this.updateMedia('desktop').bind(this));
|
|
41
|
+
this.hoverMedia.addEventListener('change', this.updateTouch().bind(this));
|
|
32
42
|
}
|
|
33
43
|
updated(changedProperties) {
|
|
34
44
|
var _a;
|
|
@@ -39,6 +49,9 @@ export const MediaQueries = (superClass) => {
|
|
|
39
49
|
__decorate([
|
|
40
50
|
property({ type: String })
|
|
41
51
|
], MediaQueryClass.prototype, "media", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
property({ type: Boolean })
|
|
54
|
+
], MediaQueryClass.prototype, "touch", void 0);
|
|
42
55
|
return MediaQueryClass;
|
|
43
56
|
};
|
|
44
57
|
//# sourceMappingURL=media-queries.js.map
|
|
@@ -56,11 +56,17 @@ export const style = css `
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
.drawer-menu-button {
|
|
59
|
-
padding: 8px
|
|
59
|
+
padding: 0 8px;
|
|
60
|
+
height: var(--_exm-navigation-top-bar-height, 64px);
|
|
61
|
+
box-sizing: border-box;
|
|
62
|
+
display: grid;
|
|
63
|
+
grid-template-columns: 48px 1fr;
|
|
64
|
+
align-items: center;
|
|
65
|
+
justify-items: center;
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
.drawer-back-button {
|
|
63
|
-
padding: 8px
|
|
69
|
+
padding: 0 8px;
|
|
64
70
|
}
|
|
65
71
|
`;
|
|
66
72
|
//# sourceMappingURL=exm-navigation-css.js.map
|
|
@@ -6,35 +6,78 @@ export const style = css `
|
|
|
6
6
|
var(--md-sys-color-secondary)
|
|
7
7
|
);
|
|
8
8
|
--_exm-navigation-item-color-selected: var(--exm-navigation-item-color-selected, var(--md-sys-color-on-secondary));
|
|
9
|
+
--_exm-navigation-item-color-sub-selected: var(
|
|
10
|
+
--exm-navigation-item-color-sub-selected,
|
|
11
|
+
var(--md-sys-color-on-surface)
|
|
12
|
+
);
|
|
13
|
+
--_exm-navigation-item-background-color-sub-selected: var(
|
|
14
|
+
--exm-navigation-item-background-color-sub-selected,
|
|
15
|
+
var(--md-sys-color-surface-container-highest)
|
|
16
|
+
);
|
|
17
|
+
--md-list-item-container-shape: 2rem;
|
|
18
|
+
--md-list-item-one-line-container-height: 48px;
|
|
9
19
|
}
|
|
10
20
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
border-radius: 1rem;
|
|
15
|
-
--md-list-item-container-shape: 1rem;
|
|
16
|
-
}
|
|
21
|
+
button {
|
|
22
|
+
--background-color: transparent;
|
|
23
|
+
--text-color: var(--md-list-item-label-text-color);
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
--md-list-item-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
border-radius: var(--md-list-item-container-shape);
|
|
26
|
+
height: var(--md-list-item-one-line-container-height);
|
|
27
|
+
font-size: 16px;
|
|
28
|
+
padding: 0 16px;
|
|
29
|
+
display: grid;
|
|
30
|
+
align-items: center;
|
|
31
|
+
width: 100%;
|
|
32
|
+
grid-template-columns: auto 1fr auto;
|
|
33
|
+
background-color: var(--background-color);
|
|
34
|
+
position: relative;
|
|
35
|
+
border: none;
|
|
36
|
+
color: var(--text-color);
|
|
37
|
+
outline: none;
|
|
26
38
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
.label {
|
|
40
|
+
grid-area: 1/2/2/3;
|
|
41
|
+
text-align: start;
|
|
42
|
+
}
|
|
31
43
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
&.selected {
|
|
45
|
+
--background-color: var(--_exm-navigation-item-background-color-selected);
|
|
46
|
+
--text-color: var(--_exm-navigation-item-color-selected);
|
|
47
|
+
|
|
48
|
+
&.has-sub-menu {
|
|
49
|
+
--background-color: var(--_exm-navigation-item-background-color-sub-selected);
|
|
50
|
+
--text-color: var(--_exm-navigation-item-color-sub-selected);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.has-icon {
|
|
55
|
+
padding-left: 4px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&.has-sub-menu {
|
|
59
|
+
padding-right: 4px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
& + button {
|
|
63
|
+
margin-top: 4px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
md-focus-ring {
|
|
67
|
+
color: white;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
exm-navigation-icon {
|
|
71
|
+
width: 48px;
|
|
72
|
+
|
|
73
|
+
&.item-icon {
|
|
74
|
+
grid-area: 1/1/2/2;
|
|
75
|
+
}
|
|
35
76
|
|
|
36
|
-
|
|
37
|
-
|
|
77
|
+
&.has-submenu {
|
|
78
|
+
grid-area: 1/3/2/4;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
38
81
|
}
|
|
39
82
|
`;
|
|
40
83
|
//# sourceMappingURL=exm-navigation-drawer-nav-item-css.js.map
|
|
@@ -8,12 +8,16 @@ export const style = css `
|
|
|
8
8
|
color: #fff;
|
|
9
9
|
height: 48px;
|
|
10
10
|
align-items: center;
|
|
11
|
-
justify-content:
|
|
11
|
+
justify-content: start;
|
|
12
12
|
padding: 0;
|
|
13
|
+
position: relative;
|
|
14
|
+
border-radius: 2rem;
|
|
15
|
+
outline: none;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
.icon-button.has-label {
|
|
16
19
|
grid-template-columns: 48px auto;
|
|
20
|
+
width: 100%;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
.icon-button .label {
|
|
@@ -1,42 +1,17 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
2
|
export const style = css `
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
--exm-navigation-item-background-color-selected,
|
|
6
|
-
var(--md-sys-color-secondary)
|
|
7
|
-
);
|
|
8
|
-
--_exm-navigation-item-color-selected: var(--exm-navigation-item-color-selected, var(--md-sys-color-on-secondary));
|
|
3
|
+
.nav {
|
|
4
|
+
padding: 8px;
|
|
9
5
|
}
|
|
10
6
|
|
|
11
7
|
md-list {
|
|
12
8
|
padding-top: 0;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
md-list-item {
|
|
16
|
-
margin-right: 8px;
|
|
17
|
-
margin-left: 8px;
|
|
18
|
-
border-radius: 1rem;
|
|
19
|
-
--md-list-item-container-shape: 1rem;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
md-list-item[selected] {
|
|
23
|
-
--md-list-item-label-text-color: var(--_exm-navigation-item-color-selected);
|
|
24
|
-
background-color: var(--_exm-navigation-item-background-color-selected);
|
|
25
|
-
--md-list-item-leading-icon-color: var(--_exm-navigation-item-color-selected)
|
|
26
|
-
--md-list-item-trailing-icon-color: var(--_exm-navigation-item-color-selected);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
md-list-item.collapsed-item[selected] {
|
|
30
|
-
--md-list-item-label-text-color: var(--_exm-navigation-item-color-selected);
|
|
31
|
-
background-color: var(--_exm-navigation-item-background-color-selected);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
md-list-item[selected] md-icon {
|
|
35
|
-
color: var(--md-sys-color-primary);
|
|
9
|
+
display: grid;
|
|
10
|
+
grid-template-rows: repeat(auto-fit, auto);
|
|
36
11
|
}
|
|
37
12
|
|
|
38
13
|
.has-back-button {
|
|
39
|
-
padding-left:
|
|
14
|
+
padding-left: 48px;
|
|
40
15
|
}
|
|
41
16
|
|
|
42
17
|
.sub-menu {
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import '@material/web/list/list.js';
|
|
2
|
-
import '@material/web/list/list-item.js';
|
|
3
|
-
import { ExmgElement } from '@exmg/lit-base';
|
|
4
|
-
declare const ExmNavigationDrawerNav_base: typeof ExmgElement;
|
|
5
|
-
export declare class ExmNavigationDrawerNav extends ExmNavigationDrawerNav_base {
|
|
6
|
-
static styles: import("lit").CSSResult[];
|
|
7
|
-
render(): import("lit-html").TemplateResult<1>;
|
|
8
|
-
}
|
|
9
|
-
export {};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { __decorate } from "tslib";
|
|
2
|
-
import { html, css } from 'lit';
|
|
3
|
-
import { customElement } from 'lit/decorators.js';
|
|
4
|
-
import { navigationRailHidden, navigationRailActive } from './exm-navigation-signals.js';
|
|
5
|
-
import { SignalWatcher } from '@lit-labs/preact-signals';
|
|
6
|
-
import '@material/web/list/list.js';
|
|
7
|
-
import '@material/web/list/list-item.js';
|
|
8
|
-
import { ExmgElement } from '@exmg/lit-base';
|
|
9
|
-
let ExmNavigationDrawerNav = class ExmNavigationDrawerNav extends SignalWatcher(ExmgElement) {
|
|
10
|
-
render() {
|
|
11
|
-
return navigationRailHidden.value
|
|
12
|
-
? html `<div class="nav">
|
|
13
|
-
<div class="header">
|
|
14
|
-
<md-icon-button @click=${() => this.fire('drawer-close', null, true)}
|
|
15
|
-
><md-icon>menu_open</md-icon></md-icon-button
|
|
16
|
-
>
|
|
17
|
-
</div>
|
|
18
|
-
<div class="navigation">
|
|
19
|
-
${navigationRailActive.value === null
|
|
20
|
-
? html `<div class="nav top-level"><slot name="topLevel"></slot></div>`
|
|
21
|
-
: html `<div class="nav"><slot name="navTop"></slot><slot></slot></div>`}
|
|
22
|
-
</div>
|
|
23
|
-
</div>`
|
|
24
|
-
: html `<slot></slot>`;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
ExmNavigationDrawerNav.styles = [
|
|
28
|
-
css `
|
|
29
|
-
:host {
|
|
30
|
-
display: block;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.nav {
|
|
34
|
-
margin: 8px 0 auto;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.header md-icon-button {
|
|
38
|
-
margin: 4px 12px 8px 16px;
|
|
39
|
-
}
|
|
40
|
-
`,
|
|
41
|
-
];
|
|
42
|
-
ExmNavigationDrawerNav = __decorate([
|
|
43
|
-
customElement('exm-navigation-drawer-nav')
|
|
44
|
-
// eslint-disable-next-line
|
|
45
|
-
], ExmNavigationDrawerNav);
|
|
46
|
-
export { ExmNavigationDrawerNav };
|
|
47
|
-
//# sourceMappingURL=exm-navigation-drawer-nav.js.map
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ExmNavigationRailNavBase } from './exm-navigation-rail-nav-base.js';
|
|
2
|
-
export declare class ExmNavigationRailNav extends ExmNavigationRailNavBase {
|
|
3
|
-
static styles: import("lit").CSSResult[];
|
|
4
|
-
}
|
|
5
|
-
declare global {
|
|
6
|
-
interface HTMLElementTagNameMap {
|
|
7
|
-
'exm-navigation-rail-nav': ExmNavigationRailNav;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { __decorate } from "tslib";
|
|
2
|
-
import { customElement } from 'lit/decorators.js';
|
|
3
|
-
import { style } from './styles/exm-navigation-rail-nav-css.js';
|
|
4
|
-
import { ExmNavigationRailNavBase } from './exm-navigation-rail-nav-base.js';
|
|
5
|
-
let ExmNavigationRailNav = class ExmNavigationRailNav extends ExmNavigationRailNavBase {
|
|
6
|
-
};
|
|
7
|
-
ExmNavigationRailNav.styles = [style];
|
|
8
|
-
ExmNavigationRailNav = __decorate([
|
|
9
|
-
customElement('exm-navigation-rail-nav')
|
|
10
|
-
], ExmNavigationRailNav);
|
|
11
|
-
export { ExmNavigationRailNav };
|
|
12
|
-
//# sourceMappingURL=exm-navigation-rail-nav.js.map
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare const navigationItemHover: import("@preact/signals-core").Signal<boolean>;
|
|
2
|
-
export declare const navigationDrawerHover: import("@preact/signals-core").Signal<boolean>;
|
|
3
|
-
export declare const navigationDrawerOpen: import("@preact/signals-core").Signal<boolean>;
|
|
4
|
-
export declare const navigationActiveHasSubmenu: import("@preact/signals-core").Signal<{
|
|
5
|
-
[k: string]: boolean;
|
|
6
|
-
}>;
|
|
7
|
-
export declare const navigationRailSelected: import("@preact/signals-core").Signal<string | null>;
|
|
8
|
-
export declare const navigationSubSelected: import("@preact/signals-core").Signal<string | null>;
|
|
9
|
-
export declare const navigationRailActive: import("@preact/signals-core").Signal<string | null>;
|
|
10
|
-
export declare const navigationRailHidden: import("@preact/signals-core").Signal<boolean>;
|
|
11
|
-
export declare const navigationDrawerPersistent: import("@preact/signals-core").Signal<boolean>;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { signal } from '@lit-labs/preact-signals';
|
|
2
|
-
export const navigationItemHover = signal(false);
|
|
3
|
-
export const navigationDrawerHover = signal(false);
|
|
4
|
-
export const navigationDrawerOpen = signal(false);
|
|
5
|
-
export const navigationActiveHasSubmenu = signal({});
|
|
6
|
-
export const navigationRailSelected = signal(null);
|
|
7
|
-
export const navigationSubSelected = signal(null);
|
|
8
|
-
export const navigationRailActive = signal(null);
|
|
9
|
-
export const navigationRailHidden = signal(false);
|
|
10
|
-
export const navigationDrawerPersistent = signal(false);
|
|
11
|
-
//# sourceMappingURL=exm-navigation-signals.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { ExmgElement } from '@exmg/lit-base';
|
|
2
|
-
import '@material/web/iconbutton/icon-button.js';
|
|
3
|
-
import '@material/web/icon/icon.js';
|
|
4
|
-
import '@material/mwc-top-app-bar-fixed';
|
|
5
|
-
export declare class ExmNavigationToolbarBase extends ExmgElement {
|
|
6
|
-
protected firstUpdated(): void;
|
|
7
|
-
render(): import("lit-html").TemplateResult<1>;
|
|
8
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { ExmgElement } from '@exmg/lit-base';
|
|
2
|
-
import { html } from 'lit';
|
|
3
|
-
import '@material/web/iconbutton/icon-button.js';
|
|
4
|
-
import '@material/web/icon/icon.js';
|
|
5
|
-
import '@material/mwc-top-app-bar-fixed';
|
|
6
|
-
export class ExmNavigationToolbarBase extends ExmgElement {
|
|
7
|
-
firstUpdated() {
|
|
8
|
-
const appToolbar = this.shadowRoot.querySelector('mwc-top-app-bar-fixed');
|
|
9
|
-
if (appToolbar) {
|
|
10
|
-
const observer = new MutationObserver((_, obs) => {
|
|
11
|
-
const shadowRoot = appToolbar.shadowRoot;
|
|
12
|
-
const header = shadowRoot ? shadowRoot.querySelector('header') : null;
|
|
13
|
-
if (header) {
|
|
14
|
-
header.style.left = '0px';
|
|
15
|
-
header.style.right = '0px';
|
|
16
|
-
obs.disconnect(); // Stop observing once we have made the changes
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
observer.observe(appToolbar.shadowRoot, {
|
|
20
|
-
childList: true,
|
|
21
|
-
subtree: true,
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
render() {
|
|
26
|
-
return html `<mwc-top-app-bar-fixed>
|
|
27
|
-
<slot name="navigationIcon" slot="navigationIcon"></slot>
|
|
28
|
-
<slot name="title" slot="title"></slot>
|
|
29
|
-
<slot name="actionItems" slot="actionItems"></slot>
|
|
30
|
-
</mwc-top-app-bar-fixed>`;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=exm-navigation-toolbar-base.js.map
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ExmNavigationToolbarBase } from './exm-navigation-toolbar-base.js';
|
|
2
|
-
export declare class ExmNavigationToolbar extends ExmNavigationToolbarBase {
|
|
3
|
-
static styles: import("lit").CSSResult[];
|
|
4
|
-
}
|
|
5
|
-
declare global {
|
|
6
|
-
interface HTMLElementTagNameMap {
|
|
7
|
-
'exm-navigation-toolbar': ExmNavigationToolbar;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { __decorate } from "tslib";
|
|
2
|
-
import { customElement } from 'lit/decorators.js';
|
|
3
|
-
import { style } from './styles/exm-navigation-toolbar-css.js';
|
|
4
|
-
import { ExmNavigationToolbarBase } from './exm-navigation-toolbar-base.js';
|
|
5
|
-
let ExmNavigationToolbar = class ExmNavigationToolbar extends ExmNavigationToolbarBase {
|
|
6
|
-
};
|
|
7
|
-
ExmNavigationToolbar.styles = [style];
|
|
8
|
-
ExmNavigationToolbar = __decorate([
|
|
9
|
-
customElement('exm-navigation-toolbar')
|
|
10
|
-
], ExmNavigationToolbar);
|
|
11
|
-
export { ExmNavigationToolbar };
|
|
12
|
-
//# sourceMappingURL=exm-navigation-toolbar.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const style: import("lit").CSSResult;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { css } from 'lit';
|
|
2
|
-
export const style = css `
|
|
3
|
-
:host {
|
|
4
|
-
--_exm-navigation-item-background-color-selected: var(
|
|
5
|
-
--exm-navigation-item-background-color-selected,
|
|
6
|
-
var(--md-sys-color-secondary)
|
|
7
|
-
);
|
|
8
|
-
--_exm-navigation-item-color-selected: var(--exm-navigation-item-color-selected, var(--md-sys-color-on-secondary));
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
md-list-item {
|
|
12
|
-
margin-right: 8px;
|
|
13
|
-
margin-left: 8px;
|
|
14
|
-
border-radius: 1rem;
|
|
15
|
-
--md-list-item-container-shape: 1rem;
|
|
16
|
-
display: grid;
|
|
17
|
-
grid-template-columns: auto 1fr auto;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
md-list-item[selected] {
|
|
21
|
-
--md-list-item-label-text-color: var(--_exm-navigation-item-color-selected);
|
|
22
|
-
background-color: var(--_exm-navigation-item-background-color-selected);
|
|
23
|
-
--md-list-item-leading-icon-color: var(--_exm-navigation-item-color-selected)
|
|
24
|
-
--md-list-item-trailing-icon-color: var(--_exm-navigation-item-color-selected);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
md-list-item.collapsed-item[selected] {
|
|
28
|
-
--md-list-item-label-text-color: var(--_exm-navigation-item-color-selected);
|
|
29
|
-
background-color: var(--_exm-navigation-item-background-color-selected);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
md-list-item[selected] md-icon {
|
|
33
|
-
color: var(--md-sys-color-primary);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.sub-menu {
|
|
37
|
-
margin-left: 1rem;
|
|
38
|
-
}
|
|
39
|
-
`;
|
|
40
|
-
//# sourceMappingURL=exm-navigate-drawer-nav-item-css.js.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { css } from 'lit';
|
|
2
|
-
export const style = css `:host{display:flex;flex-direction:column;--_exm-navigation-rail-nav-width: var(--exm-navigation-rail-nav-width, 88px);width:var(--_exm-navigation-rail-nav-width);margin-top:20px}`;
|
|
3
|
-
export default style;
|
|
4
|
-
//# sourceMappingURL=exm-navigation-rail-nav-css.js.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { css } from 'lit';
|
|
2
|
-
export const style = css `:host{--_exm-navigation-item-background-color-selected: var( --exm-navigation-item-background-color-selected, var(--md-sys-color-secondary) );--_exm-navigation-item-color-selected: var(--exm-navigation-item-color-selected, var(--md-sys-color-on-secondary))}exm-navigation-drawer{--md-list-container-color: none;--md-list-item-label-text-color: var(--md-sys-color-on-surface-variant);--md-list-item-supporting-text-color: var(--md-sys-color-on-surface-variant);--md-list-item-trailing-supporting-text-color: var(--md-sys-color-on-surface-variant);--md-list-item-container-shape: 24px}exm-navigation-drawer md-list-item{margin-right:8px;margin-left:8px;border-radius:24px;--md-list-item-container-shape: 24px}exm-navigation-drawer md-list-item[selected]{--md-list-item-label-text-color: var(--_exm-navigation-item-color-selected);background-color:var(--_exm-navigation-item-background-color-selected);--md-list-item-leading-icon-color: var(--_exm-navigation-item-color-selected) --md-list-item-trailing-icon-color: var(--_exm-navigation-item-color-selected)}exm-navigation-drawer md-list-item.collapsed-item[selected]{--md-list-item-label-text-color: var(--_exm-navigation-item-color-selected);background-color:var(--_exm-navigation-item-background-color-selected)}exm-navigation-drawer md-list-item[selected] md-icon{color:var(--md-sys-color-primary)}.sub-menu{margin-left:.8rem}.left-margin{margin-left:2.5rem}`;
|
|
3
|
-
export default style;
|
|
4
|
-
//# sourceMappingURL=exm-navigation-styles-css.js.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { css } from 'lit';
|
|
2
|
-
export const style = css `:host{display:block}mwc-top-app-bar-fixed{--mdc-theme-primary: var(--exm-navigation-toolbar-primary, var(--md-sys-color-background));--mdc-theme-on-primary: var(--exm-navigation-toolbar-on-primary, var(--md-sys-color-on-background))}md-icon{fill:var(--exm-navigation-toolbar-on-primary, var(--md-sys-color-on-background))}@media screen and (min-width: 961px){slot[name=navigationIcon]{display:none}}`;
|
|
3
|
-
export default style;
|
|
4
|
-
//# sourceMappingURL=exm-navigation-toolbar-css.js.map
|