@exmg/exm-navigation 1.0.3 → 1.1.1-alpha.9

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.
Files changed (101) hide show
  1. package/README.md +73 -0
  2. package/dist/exm-navigation-base.d.ts +131 -0
  3. package/dist/exm-navigation-base.js +391 -0
  4. package/dist/exm-navigation-drawer-base.d.ts +11 -0
  5. package/dist/exm-navigation-drawer-base.js +52 -0
  6. package/dist/exm-navigation-drawer-menu-base.d.ts +12 -0
  7. package/dist/exm-navigation-drawer-menu-base.js +45 -0
  8. package/dist/exm-navigation-drawer-menu.d.ts +9 -0
  9. package/dist/exm-navigation-drawer-menu.js +12 -0
  10. package/dist/exm-navigation-drawer-nav-item-base.d.ts +14 -0
  11. package/dist/exm-navigation-drawer-nav-item-base.js +49 -0
  12. package/dist/exm-navigation-drawer-nav-item.d.ts +8 -0
  13. package/dist/exm-navigation-drawer-nav-item.js +10 -0
  14. package/{src → dist}/exm-navigation-drawer.d.ts +0 -1
  15. package/{src → dist}/exm-navigation-drawer.js +0 -2
  16. package/dist/exm-navigation-icon-base.d.ts +7 -0
  17. package/dist/exm-navigation-icon-base.js +20 -0
  18. package/dist/exm-navigation-icon-button-base.d.ts +9 -0
  19. package/dist/exm-navigation-icon-button-base.js +36 -0
  20. package/dist/exm-navigation-icon-button.d.ts +8 -0
  21. package/dist/exm-navigation-icon-button.js +10 -0
  22. package/dist/exm-navigation-icon.d.ts +8 -0
  23. package/dist/exm-navigation-icon.js +10 -0
  24. package/dist/exm-navigation-rail-base.d.ts +12 -0
  25. package/dist/exm-navigation-rail-base.js +55 -0
  26. package/{src → dist}/exm-navigation-rail-nav-item-base.d.ts +2 -4
  27. package/dist/exm-navigation-rail-nav-item-base.js +37 -0
  28. package/{src → dist}/exm-navigation-rail-nav-item.d.ts +0 -1
  29. package/{src → dist}/exm-navigation-rail-nav-item.js +0 -2
  30. package/{src → dist}/exm-navigation-rail.d.ts +0 -1
  31. package/{src → dist}/exm-navigation-rail.js +0 -2
  32. package/dist/exm-navigation-sub-menu-base.d.ts +28 -0
  33. package/dist/exm-navigation-sub-menu-base.js +153 -0
  34. package/dist/exm-navigation-sub-menu.d.ts +8 -0
  35. package/dist/exm-navigation-sub-menu.js +10 -0
  36. package/dist/exm-navigation-topbar-base.d.ts +10 -0
  37. package/dist/exm-navigation-topbar-base.js +33 -0
  38. package/dist/exm-navigation-topbar.d.ts +8 -0
  39. package/dist/exm-navigation-topbar.js +10 -0
  40. package/dist/exm-navigation.d.ts +8 -0
  41. package/dist/exm-navigation.js +10 -0
  42. package/dist/index.d.ts +12 -0
  43. package/dist/index.js +13 -0
  44. package/dist/mixins/media-queries.d.ts +8 -0
  45. package/dist/mixins/media-queries.js +57 -0
  46. package/{src/styles/exm-navigation-rail-nav-css.d.ts → dist/styles/exm-navigation-css.d.ts} +0 -1
  47. package/dist/styles/exm-navigation-css.js +72 -0
  48. package/{src → dist}/styles/exm-navigation-drawer-css.d.ts +0 -1
  49. package/dist/styles/exm-navigation-drawer-css.js +35 -0
  50. package/dist/styles/exm-navigation-drawer-nav-item-css.d.ts +1 -0
  51. package/dist/styles/exm-navigation-drawer-nav-item-css.js +84 -0
  52. package/dist/styles/exm-navigation-icon-button-css.d.ts +1 -0
  53. package/dist/styles/exm-navigation-icon-button-css.js +29 -0
  54. package/dist/styles/exm-navigation-icon-css.d.ts +1 -0
  55. package/dist/styles/exm-navigation-icon-css.js +22 -0
  56. package/{src → dist}/styles/exm-navigation-rail-css.d.ts +0 -1
  57. package/dist/styles/exm-navigation-rail-css.js +50 -0
  58. package/{src → dist}/styles/exm-navigation-rail-nav-item-css.d.ts +0 -1
  59. package/dist/styles/exm-navigation-rail-nav-item-css.js +94 -0
  60. package/dist/styles/exm-navigation-sub-menu-css.d.ts +1 -0
  61. package/dist/styles/exm-navigation-sub-menu-css.js +21 -0
  62. package/dist/styles/exm-navigation-topbar-css.d.ts +1 -0
  63. package/dist/styles/exm-navigation-topbar-css.js +30 -0
  64. package/dist/types.d.ts +8 -0
  65. package/dist/types.js +2 -0
  66. package/package.json +19 -20
  67. package/index.d.ts +0 -16
  68. package/index.js +0 -17
  69. package/src/exm-navigation-base.d.ts +0 -30
  70. package/src/exm-navigation-base.js +0 -85
  71. package/src/exm-navigation-drawer-base.d.ts +0 -29
  72. package/src/exm-navigation-drawer-base.js +0 -173
  73. package/src/exm-navigation-drawer-nav.d.ts +0 -9
  74. package/src/exm-navigation-drawer-nav.js +0 -47
  75. package/src/exm-navigation-rail-base.d.ts +0 -4
  76. package/src/exm-navigation-rail-base.js +0 -10
  77. package/src/exm-navigation-rail-nav-base.d.ts +0 -4
  78. package/src/exm-navigation-rail-nav-base.js +0 -9
  79. package/src/exm-navigation-rail-nav-item-base.js +0 -69
  80. package/src/exm-navigation-rail-nav.d.ts +0 -9
  81. package/src/exm-navigation-rail-nav.js +0 -12
  82. package/src/exm-navigation-signals.d.ts +0 -11
  83. package/src/exm-navigation-signals.js +0 -11
  84. package/src/exm-navigation-toolbar-base.d.ts +0 -8
  85. package/src/exm-navigation-toolbar-base.js +0 -33
  86. package/src/exm-navigation-toolbar.d.ts +0 -9
  87. package/src/exm-navigation-toolbar.js +0 -12
  88. package/src/styles/exm-navigation-drawer-css.js +0 -4
  89. package/src/styles/exm-navigation-drawer.scss +0 -29
  90. package/src/styles/exm-navigation-rail-css.js +0 -4
  91. package/src/styles/exm-navigation-rail-nav-css.js +0 -4
  92. package/src/styles/exm-navigation-rail-nav-item-css.js +0 -4
  93. package/src/styles/exm-navigation-rail-nav-item.scss +0 -107
  94. package/src/styles/exm-navigation-rail-nav.scss +0 -7
  95. package/src/styles/exm-navigation-rail.scss +0 -35
  96. package/src/styles/exm-navigation-styles-css.d.ts +0 -2
  97. package/src/styles/exm-navigation-styles-css.js +0 -4
  98. package/src/styles/exm-navigation-styles.scss +0 -46
  99. package/src/styles/exm-navigation-toolbar-css.d.ts +0 -2
  100. package/src/styles/exm-navigation-toolbar-css.js +0 -4
  101. package/src/styles/exm-navigation-toolbar.scss +0 -18
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # `<exm-navigation>` [![Published on npm](https://img.shields.io/npm/v/@exmg/exm-navigation.svg)](https://www.npmjs.com/package/@exmg/exm-navigation)
2
+
3
+ # @exmg/exm-navigation
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @exmg/exm-navigation
9
+ ```
10
+
11
+ ## Anatomy
12
+
13
+ This library contains following component:
14
+
15
+ 1. Navigation (main component and fully composed navigation component)
16
+
17
+ Conceptual usage:
18
+
19
+ ```html
20
+ <exm-navigation .items=${menuItems} .path=${['spaces']}>
21
+ <!-- Slot for adding a title to the topbar. Topbar is only visible on mobile -->
22
+ <section slot="topbar-title">My Title</section>
23
+ <!-- Slot for adding actions to the right of the topbar. Topbar is only visible on mobile -->
24
+ <section slot="topbar-actions">Actions</section>
25
+ <!-- Slot for adding a logo in the top part of the rail. This is not visible on mobile -->
26
+ <section slot="rail-top">Rail top</section>
27
+ <!-- Slot for adding extra actions or other content to the bottom of the rail. This is not visible on mobile -->
28
+ <section slot="rail-bottom">Rail bottom</section>
29
+ <!-- The actual page content to display -->
30
+ <section class="content">${this.renderPage()}</section>
31
+ </exm-navigation>
32
+ ```
33
+
34
+ Some of the components used in the navigation c an be used separately. Please check the code for implementation
35
+
36
+ ## API
37
+
38
+ ### Slots
39
+
40
+ | Name | Description |
41
+ | ---------------- | ------------------------------------------------------------------------------------------------------- |
42
+ | `topbar-title` | Slot for adding a title to the topbar. Topbar is only visible on mobile |
43
+ | `topbar-actions` | Slot for adding actions to the right of the topbar. Topbar is only visible on mobile |
44
+ | `rail-top` | Slot for adding a logo in the top part of the rail. This is not visible on mobile |
45
+ | `rail-bottom` | Slot for adding extra actions or other content to the bottom of the rail. This is not visible on mobile |
46
+ | `default` | The actual page content to display |
47
+
48
+ ### Properties/Attributes
49
+
50
+ | Name | Type | Default | Description |
51
+ | -------------------- | ------------ | ------- | ------------------------------------------------------------------------------------------ |
52
+ | `items` | `MenuItem[]` | _[]_ | The list of menuitems to display in the navigation component |
53
+ | `path` | `string[]` | _[]_ | The current/initial path for the navigation |
54
+ | `disable-navigation` | `boolean` | _false_ | Disable navigation managed by the component. In that case you can use the event to trigger |
55
+
56
+ #### MenuItem
57
+
58
+ ```typescript
59
+ interface MenuItem {
60
+ id: string;
61
+ label: string;
62
+ path?: string;
63
+ url?: string;
64
+ icon?: string;
65
+ items?: MenuItem[];
66
+ }
67
+ ```
68
+
69
+ ### Events
70
+
71
+ | Name | Detail | Description |
72
+ | ------------------- | ---------------- | ----------------------------------- |
73
+ | `navigation-change` | `['one', 'two']` | The path selected in the navigation |
@@ -0,0 +1,131 @@
1
+ import { PropertyValues } from 'lit';
2
+ import { ExmgElement } from '@exmg/lit-base/index.js';
3
+ import { MenuItem } from './types.js';
4
+ import { ExmNavigationDrawer } from './exm-navigation-drawer.js';
5
+ import '@material/web/icon/icon.js';
6
+ import '@material/web/iconbutton/icon-button.js';
7
+ import './exm-navigation-icon-button.js';
8
+ import './exm-navigation-topbar.js';
9
+ import './exm-navigation-rail.js';
10
+ import './exm-navigation-sub-menu.js';
11
+ import './exm-navigation-drawer-menu.js';
12
+ import './exm-navigation-drawer.js';
13
+ declare const ExmNavigationBase_base: (new (...args: any[]) => {
14
+ media: "mobile" | "tablet" | "desktop";
15
+ touch: boolean;
16
+ }) & typeof ExmgElement;
17
+ export declare class ExmNavigationBase extends ExmNavigationBase_base {
18
+ items: MenuItem[];
19
+ path: string[];
20
+ drawerWidth: number;
21
+ disableNavigate: boolean;
22
+ drawer?: ExmNavigationDrawer;
23
+ navContent?: HTMLDivElement;
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
+ */
28
+ selectedItem: string[];
29
+ /**
30
+ * The currently active menu item
31
+ */
32
+ activeItem: string[];
33
+ /**
34
+ * Wether or not the rail should be visible yes or no
35
+ */
36
+ railOpen: boolean;
37
+ /**
38
+ * Wether or not the drawer should be visible yes or no
39
+ */
40
+ drawerOpen: boolean;
41
+ /**
42
+ * Object with menuitem and a bool for having that path sub items yes or no
43
+ */
44
+ navigationHasSubmenu: Record<string, boolean>;
45
+ static styles: import("lit").CSSResult[];
46
+ protected updated(changedProperties: PropertyValues): void;
47
+ protected firstUpdated(changedProperties: PropertyValues): void;
48
+ connectedCallback(): void;
49
+ /**
50
+ * Set the correct values when the media changes.
51
+ */
52
+ private handleMediaTypeChange;
53
+ private getPathEndpoint;
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;
60
+ /**
61
+ * Handle Rail item click or Drawer sub menu click.
62
+ * If the selected menu item has children, we add the first item to the list (as per Google implementation).
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
64
+ */
65
+ private handleRailItemClick;
66
+ /**
67
+ * Handle the mouse enter of the rail item.
68
+ */
69
+ private handleRailItemMouseEnter;
70
+ /**
71
+ * Handle the mouse leave of the rail item.
72
+ * If the item has no submenu and the current selected item has no submenu, it is safe to close the drawer
73
+ */
74
+ private handleRailItemMouseLeave;
75
+ /**
76
+ * Handle drawer mouse leave. Should close the drawer
77
+ */
78
+ private handleDrawerMouseLeave;
79
+ /**
80
+ * Handle the click on a sub menu item
81
+ * @param param Contains detail. This has the new path to go to.
82
+ * If the rail is hidden and the selected item has no children, we close the drawer
83
+ */
84
+ private handleSubMenuClick;
85
+ /**
86
+ * Handle the topbar menu click.
87
+ * Clicking the menu button in the topbar wil toggle the drawer
88
+ */
89
+ private handleTopbarMenuClick;
90
+ /**
91
+ * Handle the drawer back button click.
92
+ * This should reset the active item, so the root-level menu gets triggered
93
+ */
94
+ private handleDrawerBackClick;
95
+ /**
96
+ * Check if the passed paths last item has children yes or no
97
+ * @param path Path array
98
+ * @returns True if the given path has children
99
+ */
100
+ private currentSelectedHasChildren;
101
+ /**
102
+ * When the rail is not open, show the menu button on top of the drawer to close it
103
+ */
104
+ private renderDrawerMenuButton;
105
+ /**
106
+ * When no menu item selected, ot only toplevel without children, show the start menu (same as in the rail)
107
+ * If more levels deep, show the back button
108
+ */
109
+ private renderStartMenu;
110
+ /**
111
+ * return the sub menus. More then 1 level deep
112
+ */
113
+ private renderDrawerSubMenu;
114
+ /**
115
+ * Return the Rail
116
+ */
117
+ private renderRail;
118
+ /**
119
+ * Render the topbar. This is displayed on mobile and contains the menu button and a slot for the title
120
+ */
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;
129
+ render(): import("lit-html").TemplateResult<1>;
130
+ }
131
+ export {};
@@ -0,0 +1,391 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, nothing } from 'lit';
3
+ import { ExmgElement } from '@exmg/lit-base/index.js';
4
+ import { property, query, state } from 'lit/decorators.js';
5
+ import { styleMap } from 'lit/directives/style-map.js';
6
+ import { MediaQueries } from './mixins/media-queries.js';
7
+ import { classMap } from 'lit/directives/class-map.js';
8
+ import { style } from './styles/exm-navigation-css.js';
9
+ import '@material/web/icon/icon.js';
10
+ import '@material/web/iconbutton/icon-button.js';
11
+ import './exm-navigation-icon-button.js';
12
+ import './exm-navigation-topbar.js';
13
+ import './exm-navigation-rail.js';
14
+ import './exm-navigation-sub-menu.js';
15
+ import './exm-navigation-drawer-menu.js';
16
+ import './exm-navigation-drawer.js';
17
+ // eslint-disable-next-line new-cap
18
+ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.items = [];
22
+ this.path = ['chat'];
23
+ this.drawerWidth = 319;
24
+ this.disableNavigate = false;
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
+ */
29
+ this.selectedItem = [];
30
+ /**
31
+ * The currently active menu item
32
+ */
33
+ this.activeItem = [];
34
+ /**
35
+ * Wether or not the rail should be visible yes or no
36
+ */
37
+ this.railOpen = true;
38
+ /**
39
+ * Wether or not the drawer should be visible yes or no
40
+ */
41
+ this.drawerOpen = false;
42
+ /**
43
+ * Object with menuitem and a bool for having that path sub items yes or no
44
+ */
45
+ this.navigationHasSubmenu = {};
46
+ }
47
+ updated(changedProperties) {
48
+ if (changedProperties.has('media')) {
49
+ this.handleMediaTypeChange.bind(this)();
50
+ }
51
+ if (changedProperties.has('items')) {
52
+ for (const item of this.items) {
53
+ this.navigationHasSubmenu[item.id] = (item.items || []).length > 0;
54
+ }
55
+ if (this.navigationHasSubmenu[this.path[0]] && this.media === 'desktop') {
56
+ this.drawerOpen = true;
57
+ }
58
+ }
59
+ }
60
+ firstUpdated(changedProperties) {
61
+ if (changedProperties.has('media')) {
62
+ this.handleMediaTypeChange.bind(this)();
63
+ }
64
+ }
65
+ connectedCallback() {
66
+ super.connectedCallback();
67
+ this.selectedItem = [...this.path];
68
+ this.activeItem = [...this.path];
69
+ }
70
+ /**
71
+ * Set the correct values when the media changes.
72
+ */
73
+ handleMediaTypeChange() {
74
+ this.drawerOpen = this.media === 'desktop' && this.navigationHasSubmenu[this.activeItem[0]];
75
+ this.railOpen = this.media !== 'mobile';
76
+ }
77
+ getPathEndpoint() {
78
+ let items = this.items;
79
+ let result;
80
+ const checkItems = (path, last) => {
81
+ const item = items.find((item) => item.id === path);
82
+ if (last) {
83
+ return item === null || item === void 0 ? void 0 : item.path;
84
+ }
85
+ items = (item === null || item === void 0 ? void 0 : item.items) || [];
86
+ return;
87
+ };
88
+ for (let i = 0; i < this.selectedItem.length; i++) {
89
+ result = checkItems(this.selectedItem[i], i === this.selectedItem.length - 1);
90
+ }
91
+ return result;
92
+ }
93
+ loadPage(path) {
94
+ this.path = path;
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
+ }
101
+ this.fire('navigation-change', path);
102
+ if (!this.disableNavigate) {
103
+ window.history.pushState({}, '', this.getPathEndpoint());
104
+ window.dispatchEvent(new PopStateEvent('popstate'));
105
+ }
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
+ }
135
+ /**
136
+ * Handle Rail item click or Drawer sub menu click.
137
+ * If the selected menu item has children, we add the first item to the list (as per Google implementation).
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
139
+ */
140
+ handleRailItemClick({ detail }) {
141
+ var _a;
142
+ if (this.activeItem[0] !== detail || this.media !== 'desktop') {
143
+ const items = ((_a = this.items.find((item) => item.id === detail)) === null || _a === void 0 ? void 0 : _a.items) || [];
144
+ if (items.length && !this.touch) {
145
+ this.selectedItem = [detail, items[0].id];
146
+ }
147
+ else {
148
+ this.selectedItem = [detail];
149
+ }
150
+ this.loadPage(this.selectedItem);
151
+ this.handleDrawerOpen();
152
+ }
153
+ }
154
+ /**
155
+ * Handle the mouse enter of the rail item.
156
+ */
157
+ handleRailItemMouseEnter({ detail }) {
158
+ if (this.touch) {
159
+ return;
160
+ }
161
+ this.selectedItem = [detail];
162
+ this.handleDrawerOpen();
163
+ }
164
+ /**
165
+ * Handle the mouse leave of the rail item.
166
+ * If the item has no submenu and the current selected item has no submenu, it is safe to close the drawer
167
+ */
168
+ handleRailItemMouseLeave() { }
169
+ /**
170
+ * Handle drawer mouse leave. Should close the drawer
171
+ */
172
+ handleDrawerMouseLeave() {
173
+ /**
174
+ * On mouse leave the drawer we want to set the active item to the selected item.
175
+ * If not, it will show the active item on every hover and will make navigating in the selected item impossible
176
+ */
177
+ this.selectedItem = this.activeItem;
178
+ this.handleDrawerOpen({ tabletForce: true });
179
+ }
180
+ /**
181
+ * Handle the click on a sub menu item
182
+ * @param param Contains detail. This has the new path to go to.
183
+ * If the rail is hidden and the selected item has no children, we close the drawer
184
+ */
185
+ handleSubMenuClick({ detail }) {
186
+ this.selectedItem = detail;
187
+ const endPoint = this.getPathEndpoint();
188
+ let mobileForce = false;
189
+ if (endPoint) {
190
+ this.loadPage(this.selectedItem);
191
+ mobileForce = true;
192
+ }
193
+ this.handleDrawerOpen({ mobileForce, tabletForce: this.touch && !!endPoint });
194
+ }
195
+ /**
196
+ * Handle the topbar menu click.
197
+ * Clicking the menu button in the topbar wil toggle the drawer
198
+ */
199
+ handleTopbarMenuClick() {
200
+ this.drawerOpen = !this.drawerOpen;
201
+ }
202
+ /**
203
+ * Handle the drawer back button click.
204
+ * This should reset the active item, so the root-level menu gets triggered
205
+ */
206
+ handleDrawerBackClick() {
207
+ this.selectedItem = [];
208
+ }
209
+ /**
210
+ * Check if the passed paths last item has children yes or no
211
+ * @param path Path array
212
+ * @returns True if the given path has children
213
+ */
214
+ currentSelectedHasChildren(path) {
215
+ let currentItems = this.items;
216
+ return path.reduce((_, pathSection) => {
217
+ const item = currentItems.find((currentItem) => currentItem.id === pathSection);
218
+ currentItems = (item === null || item === void 0 ? void 0 : item.items) || [];
219
+ return ((item === null || item === void 0 ? void 0 : item.items) || []).length > 0;
220
+ }, false);
221
+ }
222
+ /**
223
+ * When the rail is not open, show the menu button on top of the drawer to close it
224
+ */
225
+ renderDrawerMenuButton() {
226
+ return !this.railOpen
227
+ ? html `
228
+ <section class="drawer-menu-button">
229
+ <md-icon-button @click=${this.handleTopbarMenuClick}>
230
+ <md-icon>${this.drawerOpen ? 'menu_open' : 'menu'}</md-icon>
231
+ </md-icon-button>
232
+ </section>
233
+ `
234
+ : nothing;
235
+ }
236
+ /**
237
+ * When no menu item selected, ot only toplevel without children, show the start menu (same as in the rail)
238
+ * If more levels deep, show the back button
239
+ */
240
+ renderStartMenu() {
241
+ if (this.railOpen) {
242
+ return nothing;
243
+ }
244
+ return this.selectedItem.length === 0 ||
245
+ (this.selectedItem.length === 1 && !this.currentSelectedHasChildren(this.selectedItem))
246
+ ? html `<exm-navigation-drawer-menu
247
+ .items=${this.items}
248
+ .path=${this.activeItem}
249
+ @drawer-menu-item-click=${this.handleRailItemClick}
250
+ ></exm-navigation-drawer-menu>`
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
+ `;
260
+ }
261
+ /**
262
+ * return the sub menus. More then 1 level deep
263
+ */
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;
289
+ return html `
290
+ <exm-navigation-sub-menu
291
+ .items=${this.items}
292
+ .path=${selected}
293
+ ?has-back-button=${!this.railOpen &&
294
+ (selected.length > 1 || (selected.length > 0 && this.currentSelectedHasChildren(selected)))}
295
+ @sub-menu-item-click=${this.handleSubMenuClick}
296
+ ></exm-navigation-sub-menu>
297
+ `;
298
+ }
299
+ /**
300
+ * Return the Rail
301
+ */
302
+ renderRail() {
303
+ return html `<exm-navigation-rail
304
+ .items=${this.items}
305
+ .selected=${this.activeItem}
306
+ @rail-item-click=${this.handleRailItemClick}
307
+ @rail-item-mouseenter=${this.handleRailItemMouseEnter}
308
+ @rail-item-mouseleave=${this.handleRailItemMouseLeave}
309
+ >
310
+ <slot name="rail-top" slot="rail-top"></slot>
311
+ <slot name="rail-bottom" slot="rail-bottom"></slot>
312
+ </exm-navigation-rail>`;
313
+ }
314
+ /**
315
+ * Render the topbar. This is displayed on mobile and contains the menu button and a slot for the title
316
+ */
317
+ renderTopbar() {
318
+ return html `<exm-navigation-topbar ?drawer-open=${this.drawerOpen} @topbar-menu-click=${this.handleTopbarMenuClick}>
319
+ <slot name="topbar-title" slot="topbar-title"></slot>
320
+ <slot name="topbar-actions" slot="topbar-actions"></slot>
321
+ </exm-navigation-topbar>`;
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
+ }
335
+ render() {
336
+ const containerStyle = {
337
+ '--exm-drawer-width': `${this.getDrawerWidth()}px`,
338
+ };
339
+ const containerClass = { 'show-topbar': !this.railOpen };
340
+ return html `
341
+ <section
342
+ class="navigation-container ${classMap(containerClass)}"
343
+ id="navigation-container"
344
+ style=${styleMap(containerStyle)}
345
+ >
346
+ ${this.railOpen ? this.renderRail() : this.renderTopbar()}
347
+ <exm-navigation-drawer ?open=${this.drawerOpen} @drawer-mouseleave=${this.handleDrawerMouseLeave}>
348
+ ${[this.renderDrawerMenuButton(), this.renderStartMenu(), this.renderDrawerSubMenu()]}
349
+ </exm-navigation-drawer>
350
+ <section class="content">
351
+ <slot></slot>
352
+ </section>
353
+ </section>
354
+ `;
355
+ }
356
+ }
357
+ ExmNavigationBase.styles = [style];
358
+ __decorate([
359
+ property({ type: Array })
360
+ ], ExmNavigationBase.prototype, "items", void 0);
361
+ __decorate([
362
+ property({ type: Array })
363
+ ], ExmNavigationBase.prototype, "path", void 0);
364
+ __decorate([
365
+ property({ type: Number, attribute: 'drawer-width' })
366
+ ], ExmNavigationBase.prototype, "drawerWidth", void 0);
367
+ __decorate([
368
+ property({ type: Boolean, attribute: 'disable-navigation' })
369
+ ], ExmNavigationBase.prototype, "disableNavigate", void 0);
370
+ __decorate([
371
+ query('exm-navigation-drawer')
372
+ ], ExmNavigationBase.prototype, "drawer", void 0);
373
+ __decorate([
374
+ query('#navigation-container')
375
+ ], ExmNavigationBase.prototype, "navContent", void 0);
376
+ __decorate([
377
+ state()
378
+ ], ExmNavigationBase.prototype, "selectedItem", void 0);
379
+ __decorate([
380
+ state()
381
+ ], ExmNavigationBase.prototype, "activeItem", void 0);
382
+ __decorate([
383
+ state()
384
+ ], ExmNavigationBase.prototype, "railOpen", void 0);
385
+ __decorate([
386
+ state()
387
+ ], ExmNavigationBase.prototype, "drawerOpen", void 0);
388
+ __decorate([
389
+ state()
390
+ ], ExmNavigationBase.prototype, "navigationHasSubmenu", void 0);
391
+ //# sourceMappingURL=exm-navigation-base.js.map
@@ -0,0 +1,11 @@
1
+ import { ExmgElement } from '@exmg/lit-base';
2
+ export declare class ExmNavigationDrawerBase extends ExmgElement {
3
+ open: boolean;
4
+ persistent: boolean;
5
+ drawer?: HTMLDivElement;
6
+ static styles: import("lit").CSSResult[];
7
+ private handleMouseEnter;
8
+ private handleMouseLeave;
9
+ protected firstUpdated(): Promise<void>;
10
+ render(): import("lit-html").TemplateResult<1>;
11
+ }
@@ -0,0 +1,52 @@
1
+ import { __decorate } from "tslib";
2
+ import { html } from 'lit';
3
+ import { property, query } from 'lit/decorators.js';
4
+ import { ExmgElement } from '@exmg/lit-base';
5
+ import { style } from './styles/exm-navigation-drawer-css.js';
6
+ import { classMap } from 'lit/directives/class-map.js';
7
+ export class ExmNavigationDrawerBase extends ExmgElement {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.open = false;
11
+ this.persistent = false;
12
+ }
13
+ handleMouseEnter() {
14
+ this.fire('drawer-mouseenter');
15
+ }
16
+ handleMouseLeave() {
17
+ this.fire('drawer-mouseleave');
18
+ }
19
+ async firstUpdated() {
20
+ var _a;
21
+ await this.updateComplete;
22
+ if ((_a = this.drawer) === null || _a === void 0 ? void 0 : _a.shadowRoot) {
23
+ const asideElement = this.drawer.shadowRoot.querySelector('aside');
24
+ if (asideElement) {
25
+ // Add event listeners to the aside element
26
+ asideElement.addEventListener('mouseenter', this.handleMouseEnter.bind(this));
27
+ asideElement.addEventListener('mouseleave', this.handleMouseLeave.bind(this));
28
+ }
29
+ }
30
+ }
31
+ render() {
32
+ const classNames = { open: this.open };
33
+ return html `<aside
34
+ class="${classMap(classNames)}"
35
+ @mouseenter=${this.handleMouseEnter}
36
+ @mouseleave=${this.handleMouseLeave}
37
+ >
38
+ <slot></slot>
39
+ </aside> `;
40
+ }
41
+ }
42
+ ExmNavigationDrawerBase.styles = [style];
43
+ __decorate([
44
+ property({ type: Boolean })
45
+ ], ExmNavigationDrawerBase.prototype, "open", void 0);
46
+ __decorate([
47
+ property({ type: Boolean })
48
+ ], ExmNavigationDrawerBase.prototype, "persistent", void 0);
49
+ __decorate([
50
+ query('aside')
51
+ ], ExmNavigationDrawerBase.prototype, "drawer", void 0);
52
+ //# sourceMappingURL=exm-navigation-drawer-base.js.map
@@ -0,0 +1,12 @@
1
+ import { ExmgElement } from '@exmg/lit-base/index.js';
2
+ import { MenuItem } from './types.js';
3
+ import './exm-navigation-rail-nav-item.js';
4
+ import './exm-navigation-drawer-nav-item.js';
5
+ import '@material/web/list/list.js';
6
+ import '@exmg/exm-collapsed/exm-collapsed.js';
7
+ export declare class ExmNavigationDrawerMenuBase extends ExmgElement {
8
+ items: MenuItem[];
9
+ path: string[];
10
+ private handleDrawerMenuItemClick;
11
+ render(): import("lit-html").TemplateResult<1>;
12
+ }