@exmg/exm-navigation 1.0.3 → 1.1.1

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 (74) hide show
  1. package/README.md +72 -0
  2. package/index.d.ts +11 -15
  3. package/index.js +11 -15
  4. package/package.json +9 -8
  5. package/src/exm-navigation-base.d.ts +94 -19
  6. package/src/exm-navigation-base.js +293 -58
  7. package/src/exm-navigation-drawer-base.d.ts +8 -23
  8. package/src/exm-navigation-drawer-base.js +25 -149
  9. package/src/exm-navigation-drawer-menu-base.d.ts +12 -0
  10. package/src/exm-navigation-drawer-menu-base.js +45 -0
  11. package/src/exm-navigation-drawer-menu.d.ts +9 -0
  12. package/src/exm-navigation-drawer-menu.js +12 -0
  13. package/src/exm-navigation-drawer-nav-item-base.d.ts +14 -0
  14. package/src/exm-navigation-drawer-nav-item-base.js +45 -0
  15. package/src/exm-navigation-drawer-nav-item.d.ts +8 -0
  16. package/src/exm-navigation-drawer-nav-item.js +10 -0
  17. package/src/exm-navigation-drawer.d.ts +0 -1
  18. package/src/exm-navigation-drawer.js +0 -2
  19. package/src/exm-navigation-icon-base.d.ts +7 -0
  20. package/src/exm-navigation-icon-base.js +20 -0
  21. package/src/exm-navigation-icon-button-base.d.ts +9 -0
  22. package/src/exm-navigation-icon-button-base.js +34 -0
  23. package/src/exm-navigation-icon-button.d.ts +8 -0
  24. package/src/exm-navigation-icon-button.js +10 -0
  25. package/src/exm-navigation-icon.d.ts +8 -0
  26. package/src/exm-navigation-icon.js +10 -0
  27. package/src/exm-navigation-rail-base.d.ts +8 -0
  28. package/src/exm-navigation-rail-base.js +48 -3
  29. package/src/exm-navigation-rail-nav-item-base.d.ts +2 -4
  30. package/src/exm-navigation-rail-nav-item-base.js +7 -39
  31. package/src/exm-navigation-rail-nav-item.d.ts +0 -1
  32. package/src/exm-navigation-rail-nav-item.js +0 -2
  33. package/src/exm-navigation-rail.d.ts +0 -1
  34. package/src/exm-navigation-rail.js +0 -2
  35. package/src/exm-navigation-sub-menu-base.d.ts +17 -0
  36. package/src/exm-navigation-sub-menu-base.js +88 -0
  37. package/src/exm-navigation-sub-menu.d.ts +8 -0
  38. package/src/exm-navigation-sub-menu.js +10 -0
  39. package/src/exm-navigation-topbar-base.d.ts +10 -0
  40. package/src/exm-navigation-topbar-base.js +34 -0
  41. package/src/exm-navigation-topbar.d.ts +8 -0
  42. package/src/exm-navigation-topbar.js +10 -0
  43. package/src/exm-navigation.d.ts +8 -0
  44. package/src/exm-navigation.js +10 -0
  45. package/src/mixins/media-queries.d.ts +7 -0
  46. package/src/mixins/media-queries.js +44 -0
  47. package/src/styles/exm-navigate-drawer-nav-item-css.d.ts +1 -0
  48. package/src/styles/exm-navigate-drawer-nav-item-css.js +40 -0
  49. package/src/styles/exm-navigation-css.d.ts +1 -0
  50. package/src/styles/exm-navigation-css.js +56 -0
  51. package/src/styles/exm-navigation-drawer-css.d.ts +0 -1
  52. package/src/styles/exm-navigation-drawer-css.js +22 -2
  53. package/src/styles/exm-navigation-drawer-nav-item-css.d.ts +1 -0
  54. package/src/styles/exm-navigation-drawer-nav-item-css.js +40 -0
  55. package/src/styles/exm-navigation-icon-button-css.d.ts +1 -0
  56. package/src/styles/exm-navigation-icon-button-css.js +23 -0
  57. package/src/styles/exm-navigation-icon-css.d.ts +1 -0
  58. package/src/styles/exm-navigation-icon-css.js +22 -0
  59. package/src/styles/exm-navigation-rail-css.d.ts +0 -1
  60. package/src/styles/exm-navigation-rail-css.js +47 -2
  61. package/src/styles/exm-navigation-rail-nav-item-css.d.ts +0 -1
  62. package/src/styles/exm-navigation-rail-nav-item-css.js +92 -2
  63. package/src/styles/exm-navigation-sub-menu-css.d.ts +1 -0
  64. package/src/styles/exm-navigation-sub-menu-css.js +38 -0
  65. package/src/styles/exm-navigation-topbar-css.d.ts +1 -0
  66. package/src/styles/exm-navigation-topbar-css.js +29 -0
  67. package/src/types.d.ts +8 -0
  68. package/src/types.js +2 -0
  69. package/src/styles/exm-navigation-drawer.scss +0 -29
  70. package/src/styles/exm-navigation-rail-nav-item.scss +0 -107
  71. package/src/styles/exm-navigation-rail-nav.scss +0 -7
  72. package/src/styles/exm-navigation-rail.scss +0 -35
  73. package/src/styles/exm-navigation-styles.scss +0 -46
  74. package/src/styles/exm-navigation-toolbar.scss +0 -18
@@ -1,85 +1,320 @@
1
1
  import { __decorate } from "tslib";
2
- import { SignalWatcher } from '@lit-labs/preact-signals';
3
- import { LitElement, html } from 'lit';
4
- import { navigationDrawerHover, navigationDrawerPersistent, navigationItemHover, navigationRailActive, navigationRailSelected, navigationSubSelected, } from './exm-navigation-signals.js';
5
- import { property, query } from 'lit/decorators.js';
6
- // eslint-disable-next-line
7
- export class ExmNavigationBase extends SignalWatcher(LitElement) {
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 './exm-navigation-icon-button.js';
10
+ import './exm-navigation-topbar.js';
11
+ import './exm-navigation-rail.js';
12
+ import './exm-navigation-sub-menu.js';
13
+ import './exm-navigation-drawer-menu.js';
14
+ import './exm-navigation-drawer.js';
15
+ // eslint-disable-next-line new-cap
16
+ export class ExmNavigationBase extends MediaQueries(ExmgElement) {
8
17
  constructor() {
9
18
  super(...arguments);
10
- this.pageId = 'chat';
19
+ this.items = [];
20
+ this.path = ['chat'];
21
+ this.drawerWidth = 319;
22
+ this.persistent = true;
23
+ this.selectedItem = [];
24
+ this.activeItem = [];
25
+ this.railOpen = true;
26
+ this.drawerOpen = false;
27
+ this.drawerHover = false;
28
+ this.navigationHasSubmenu = {};
11
29
  this.menu = [];
12
30
  this.expandedItems = {};
31
+ this.unSubscribeSelected = () => { };
32
+ }
33
+ updated(changedProperties) {
34
+ if (changedProperties.has('media')) {
35
+ this.handleMediaTypeChange.bind(this)();
36
+ }
37
+ if (changedProperties.has('items')) {
38
+ for (const item of this.items) {
39
+ this.navigationHasSubmenu[item.id] = (item.items || []).length > 0;
40
+ }
41
+ if (this.navigationHasSubmenu[this.path[0]] && this.persistent) {
42
+ this.drawerOpen = true;
43
+ }
44
+ }
45
+ }
46
+ firstUpdated(changedProperties) {
47
+ if (changedProperties.has('media')) {
48
+ this.handleMediaTypeChange.bind(this)();
49
+ }
13
50
  }
14
51
  connectedCallback() {
15
52
  super.connectedCallback();
16
- navigationRailSelected.value = this.pageId;
17
- navigationRailActive.value = this.pageId;
53
+ this.selectedItem = [...this.path];
54
+ this.activeItem = [...this.path];
18
55
  }
19
- isSubMenuExpanded(id) {
20
- return !!this.expandedItems[id];
56
+ /**
57
+ * Set the correct values when the media changes.
58
+ */
59
+ handleMediaTypeChange() {
60
+ this.persistent = this.media === 'desktop';
61
+ this.drawerOpen = this.media === 'desktop' && this.navigationHasSubmenu[this.selectedItem[0]];
62
+ this.railOpen = this.media !== 'mobile';
21
63
  }
22
- toggleExpanded(id) {
23
- const expanded = this.isSubMenuExpanded(id);
24
- this.expandedItems[id] = !expanded;
25
- this.requestUpdate();
64
+ loadPage(path) {
65
+ this.path = path;
66
+ this.selectedItem = path;
67
+ this.fire('navigation-change', path);
26
68
  }
27
- getItemsFromParentId(id) {
69
+ /**
70
+ * Handle Rail item click or Drawer sub menu click.
71
+ * If the selected menu item has children, we add the first item to the list (as per Google implementation).
72
+ * In this case we also do not close the drawer in non persistent mode, so the user is able to select a next level in the menu
73
+ */
74
+ handleRailItemClick({ detail }) {
28
75
  var _a;
29
- return ((_a = this.menu.find((i) => i.id === id)) === null || _a === void 0 ? void 0 : _a.items) || [];
30
- }
31
- getActiveSubmenuParent() {
32
- // On hover show howver content and otherwise show the selected submenu
33
- const parentId = !navigationItemHover.value && !navigationDrawerHover.value
34
- ? navigationRailSelected.value
35
- : navigationRailActive.value;
36
- if (parentId === null) {
37
- return null;
76
+ if (this.selectedItem[0] !== detail) {
77
+ const items = ((_a = this.items.find((item) => item.id === detail)) === null || _a === void 0 ? void 0 : _a.items) || [];
78
+ if (items.length) {
79
+ this.selectedItem = [detail, items[0].id];
80
+ }
81
+ else {
82
+ this.selectedItem = [detail];
83
+ }
84
+ // copy the selected item to the active item
85
+ this.activeItem = this.selectedItem;
86
+ /**
87
+ * If persistent menu close the drawer when a item is clicked and does not has children items
88
+ */
89
+ if (this.persistent) {
90
+ this.drawerOpen = items.length > 0 || this.navigationHasSubmenu[detail];
91
+ }
92
+ else if (items.length === 0) {
93
+ this.drawerOpen = false;
94
+ }
95
+ this.loadPage(this.selectedItem);
38
96
  }
39
- return parentId;
40
97
  }
41
- loadPage(id) {
42
- this.pageId = id;
43
- }
44
- handlSubMenuBackClick() {
45
- navigationRailActive.value = null;
46
- }
47
- handleNavigationSubClicked(i, parentId) {
48
- navigationRailSelected.value = parentId;
49
- if ((i.items || []).length > 0) {
50
- this.toggleExpanded(i.id);
98
+ /**
99
+ * Handle the mouse enter of the rail item.
100
+ */
101
+ handleRailItemMouseEnter({ detail }) {
102
+ if (this.navigationHasSubmenu[detail]) {
103
+ this.drawerOpen = true;
104
+ if (detail !== this.selectedItem[0]) {
105
+ this.activeItem = [detail];
106
+ return;
107
+ }
108
+ }
109
+ else if (this.navigationHasSubmenu[this.selectedItem[0]] && this.persistent) {
110
+ this.activeItem = this.selectedItem;
111
+ this.drawerOpen = true;
51
112
  }
52
113
  else {
53
- navigationSubSelected.value = i.id;
54
- this.loadPage(navigationSubSelected.value);
114
+ this.activeItem = this.selectedItem;
115
+ this.drawerOpen = false;
55
116
  }
117
+ this.activeItem = this.selectedItem;
56
118
  }
57
- handleRailClick(id) {
58
- var _a;
59
- if (navigationRailSelected.value !== id) {
60
- // Set new selected rail item
61
- navigationRailSelected.value = id;
62
- // Reset selected sub menu item
63
- navigationSubSelected.value = null;
64
- const items = ((_a = this.menu.find((i) => i.id === id)) === null || _a === void 0 ? void 0 : _a.items) || [];
65
- if (items.length > 0) {
66
- navigationRailActive.value = id;
67
- }
68
- // If persistent menu close the drawer when a item is clicked and does not has children items
69
- if (navigationDrawerPersistent.value) {
70
- this.drawer.open = items.length > 0 ? true : false;
71
- }
72
- this.loadPage(navigationRailSelected.value);
119
+ /**
120
+ * Handle the mouse leave of the rail item.
121
+ * If the item has no submenu and the current selected item has no submenu, it is safe to close the drawer
122
+ */
123
+ handleRailItemMouseLeave({ detail }) {
124
+ if (!this.navigationHasSubmenu[detail] && !this.navigationHasSubmenu[this.selectedItem[0]]) {
125
+ this.drawerOpen = false;
126
+ }
127
+ if (!this.persistent && !this.navigationHasSubmenu[detail]) {
128
+ this.drawerOpen = false;
129
+ }
130
+ }
131
+ /**
132
+ * Handle drawer mouse leave. Should close the drawer
133
+ */
134
+ handleDrawerMouseLeave() {
135
+ if (!this.navigationHasSubmenu[this.selectedItem[0]] || !this.persistent) {
136
+ this.drawerOpen = false;
73
137
  }
138
+ /**
139
+ * On mouse leave the drawer we want to set the active item to the selected item.
140
+ * If not, it will show the active item on every hover and will make navigating in the selected item impossible
141
+ */
142
+ this.activeItem = this.selectedItem;
143
+ }
144
+ /**
145
+ * Handle the click on a sub menu item
146
+ * @param param Contains detail. This has the new path to go to.
147
+ * If the rail is hidden and the selected item has no children, we close the drawer
148
+ */
149
+ handleSubMenuClick({ detail }) {
150
+ this.selectedItem = detail;
151
+ this.activeItem = detail;
152
+ if ((!this.railOpen || !this.persistent) && !this.currentSelectedHasChildren(detail)) {
153
+ this.drawerOpen = false;
154
+ }
155
+ }
156
+ /**
157
+ * Handle the topbar menu click.
158
+ * Clicking the menu button in the topbar wil toggle the drawer
159
+ */
160
+ handleTopbarMenuClick() {
161
+ this.drawerOpen = !this.drawerOpen;
162
+ }
163
+ /**
164
+ * Handle the drawer back button click.
165
+ * This should reset the active item, so the root-level menu gets triggered
166
+ */
167
+ handleDrawerBackClick() {
168
+ this.activeItem = [];
169
+ }
170
+ /**
171
+ * Check if the passed paths last item has children yes or no
172
+ * @param path Path array
173
+ * @returns True if the given path has children
174
+ */
175
+ currentSelectedHasChildren(path) {
176
+ let currentItems = this.items;
177
+ return path.reduce((_, pathSection) => {
178
+ const item = currentItems.find((currentItem) => currentItem.id === pathSection);
179
+ currentItems = (item === null || item === void 0 ? void 0 : item.items) || [];
180
+ return ((item === null || item === void 0 ? void 0 : item.items) || []).length > 0;
181
+ }, false);
182
+ }
183
+ /**
184
+ * When the rail is not open, show the menu button on top of the drawer to close it
185
+ */
186
+ renderDrawerMenuButton() {
187
+ return !this.railOpen
188
+ ? html `
189
+ <section>
190
+ <exm-navigation-icon-button
191
+ icon=${this.drawerOpen ? 'menu_open' : 'menu'}
192
+ @navigation-icon-button-click=${this.handleTopbarMenuClick}
193
+ ></exm-navigation-icon-button>
194
+ </section>
195
+ `
196
+ : nothing;
197
+ }
198
+ /**
199
+ * When no menu item selected, ot only toplevel without children, show the start menu (same as in the rail)
200
+ * If more levels deep, show the back button
201
+ */
202
+ renderStartMenu() {
203
+ return !this.railOpen &&
204
+ (this.activeItem.length === 0 ||
205
+ (this.activeItem.length === 1 && !this.currentSelectedHasChildren(this.activeItem)))
206
+ ? html `<exm-navigation-drawer-menu
207
+ .items=${this.items}
208
+ .path=${this.activeItem}
209
+ @drawer-menu-item-click=${this.handleRailItemClick}
210
+ ></exm-navigation-drawer-menu>`
211
+ : !this.railOpen
212
+ ? html `
213
+ <section>
214
+ <exm-navigation-icon-button
215
+ icon="arrow_back"
216
+ label="Main menu"
217
+ @navigation-icon-button-click=${this.handleDrawerBackClick}
218
+ ></exm-navigation-icon-button>
219
+ </section>
220
+ `
221
+ : nothing;
222
+ }
223
+ /**
224
+ * return the sub menus. More then 1 level deep
225
+ */
226
+ renderDrawerSubMenu() {
227
+ return html `
228
+ <exm-navigation-sub-menu
229
+ .items=${this.items}
230
+ .path=${this.activeItem}
231
+ @sub-menu-item-click=${this.handleSubMenuClick}
232
+ ></exm-navigation-sub-menu>
233
+ `;
234
+ }
235
+ /**
236
+ * Return the Rail
237
+ */
238
+ renderRail() {
239
+ return html `<exm-navigation-rail
240
+ .items=${this.items}
241
+ .selected=${this.selectedItem}
242
+ @rail-item-click=${this.handleRailItemClick}
243
+ @rail-item-mouseenter=${this.handleRailItemMouseEnter}
244
+ @rail-item-mouseleave=${this.handleRailItemMouseLeave}
245
+ >
246
+ <slot name="rail-top" slot="rail-top"></slot>
247
+ <slot name="rail-bottom" slot="rail-bottom"></slot>
248
+ </exm-navigation-rail>`;
249
+ }
250
+ /**
251
+ * Render the topbar. This is displayed on mobile and contains the menu button and a slot for the title
252
+ */
253
+ renderTopbar() {
254
+ return html `<exm-navigation-topbar ?drawer-open=${this.drawerOpen} @topbar-menu-click=${this.handleTopbarMenuClick}>
255
+ <slot name="topbar-title" slot="topbar-title"></slot>
256
+ <slot name="topbar-actions" slot="topbar-actions"></slot>
257
+ </exm-navigation-topbar>`;
74
258
  }
75
259
  render() {
76
- return html ``;
260
+ var _a;
261
+ const containerStyle = {
262
+ '--exm-drawer-width': `${(((_a = this.items.find((item) => item.id === this.selectedItem[0])) === null || _a === void 0 ? void 0 : _a.items) || []).length > 0 && this.persistent ? this.drawerWidth : 0}px`,
263
+ };
264
+ const containerClass = { 'show-topbar': !this.railOpen };
265
+ return html `
266
+ <section
267
+ class="navigation-container ${classMap(containerClass)}"
268
+ id="navigation-container"
269
+ style=${styleMap(containerStyle)}
270
+ >
271
+ ${this.railOpen ? this.renderRail() : this.renderTopbar()}
272
+ <exm-navigation-drawer ?open=${this.drawerOpen} @drawer-mouseleave=${this.handleDrawerMouseLeave}>
273
+ ${[this.renderDrawerMenuButton(), this.renderStartMenu(), this.renderDrawerSubMenu()]}
274
+ </exm-navigation-drawer>
275
+ <section class="content">
276
+ <slot></slot>
277
+ </section>
278
+ </section>
279
+ <slot></slot>
280
+ `;
77
281
  }
78
282
  }
283
+ ExmNavigationBase.styles = [style];
79
284
  __decorate([
80
- property({ type: String })
81
- ], ExmNavigationBase.prototype, "pageId", void 0);
285
+ property({ type: Array })
286
+ ], ExmNavigationBase.prototype, "items", void 0);
82
287
  __decorate([
83
- query('#drawer')
288
+ property({ type: Array })
289
+ ], ExmNavigationBase.prototype, "path", void 0);
290
+ __decorate([
291
+ property({ type: Number, attribute: 'drawer-width' })
292
+ ], ExmNavigationBase.prototype, "drawerWidth", void 0);
293
+ __decorate([
294
+ query('exm-navigation-drawer')
84
295
  ], ExmNavigationBase.prototype, "drawer", void 0);
296
+ __decorate([
297
+ query('#navigation-container')
298
+ ], ExmNavigationBase.prototype, "navContent", void 0);
299
+ __decorate([
300
+ state()
301
+ ], ExmNavigationBase.prototype, "persistent", void 0);
302
+ __decorate([
303
+ state()
304
+ ], ExmNavigationBase.prototype, "selectedItem", void 0);
305
+ __decorate([
306
+ state()
307
+ ], ExmNavigationBase.prototype, "activeItem", void 0);
308
+ __decorate([
309
+ state()
310
+ ], ExmNavigationBase.prototype, "railOpen", void 0);
311
+ __decorate([
312
+ state()
313
+ ], ExmNavigationBase.prototype, "drawerOpen", void 0);
314
+ __decorate([
315
+ state()
316
+ ], ExmNavigationBase.prototype, "drawerHover", void 0);
317
+ __decorate([
318
+ state()
319
+ ], ExmNavigationBase.prototype, "navigationHasSubmenu", void 0);
85
320
  //# sourceMappingURL=exm-navigation-base.js.map
@@ -1,29 +1,14 @@
1
- import { LitElement } from 'lit';
2
- import '@material/mwc-drawer';
3
1
  import { Drawer } from '@material/mwc-drawer';
4
- declare const ExmNavigationDrawerBase_base: typeof LitElement;
5
- export declare class ExmNavigationDrawerBase extends ExmNavigationDrawerBase_base {
2
+ import { ExmgElement } from '@exmg/lit-base';
3
+ import '@material/mwc-drawer';
4
+ export declare class ExmNavigationDrawerBase extends ExmgElement {
6
5
  open: boolean;
7
- drawer?: Drawer;
8
6
  persistent: boolean;
9
- hoverIn: () => void;
10
- handleClose: () => void;
11
- hoverOut: () => void;
12
- private _itemHover;
13
- private _drawerHover;
14
- private _asideElement?;
15
- private _observer;
16
- hasActiveSubmenu(): boolean;
17
- updateInlineStyles(): void;
18
- constructor();
19
- disconnectedCallback(): void;
20
- toggle(): void;
21
- _handleClose(): void;
22
- _hoverIn(): void;
23
- _hoverOut(): void;
24
- hidemenu(): void;
25
- protected updated(): void;
7
+ drawer?: Drawer;
8
+ static styles: import("lit").CSSResult[];
9
+ private handleMouseEnter;
10
+ private handleMouseLeave;
11
+ private handleDrawerClose;
26
12
  protected firstUpdated(): Promise<void>;
27
13
  render(): import("lit-html").TemplateResult<1>;
28
14
  }
29
- export {};
@@ -1,173 +1,49 @@
1
1
  import { __decorate } from "tslib";
2
- import { LitElement, html } from 'lit';
2
+ import { html } from 'lit';
3
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';
4
6
  import '@material/mwc-drawer';
5
- import { ResizeController } from '@lit-labs/observers/resize-controller.js';
6
- import { navigationDrawerHover, navigationItemHover, navigationDrawerOpen, navigationRailHidden, navigationDrawerPersistent, navigationActiveHasSubmenu, } from './exm-navigation-signals.js';
7
- import { SignalWatcher } from '@lit-labs/preact-signals';
8
- import { observer } from '@exmg/lit-base';
9
- // eslint-disable-next-line
10
- export class ExmNavigationDrawerBase extends SignalWatcher(LitElement) {
11
- hasActiveSubmenu() {
12
- let activeHasSubMenu = false;
13
- for (const key in navigationActiveHasSubmenu.value) {
14
- // eslint-disable-next-line
15
- if (navigationActiveHasSubmenu.value.hasOwnProperty(key) && navigationActiveHasSubmenu.value[key]) {
16
- activeHasSubMenu = true;
17
- }
18
- }
19
- return activeHasSubMenu;
20
- }
21
- updateInlineStyles() {
22
- const drawer = this.drawer;
23
- if (drawer) {
24
- const shadowRoot = drawer.shadowRoot;
25
- const asideElement = shadowRoot.querySelector('aside');
26
- if (asideElement) {
27
- asideElement.style.left = navigationRailHidden.value ? '0px' : 'var(--_exm-navigation-rail-nav-width)';
28
- }
29
- const contentElement = shadowRoot.querySelector('div.mdc-drawer-app-content');
30
- if (contentElement) {
31
- // @ts-ignore
32
- contentElement.style.marginLeft = navigationRailHidden.value
33
- ? '0px'
34
- : this.open
35
- ? 'var(--mdc-drawer-width, 256px)'
36
- : '0px';
37
- }
38
- }
39
- }
7
+ export class ExmNavigationDrawerBase extends ExmgElement {
40
8
  constructor() {
41
- super();
9
+ super(...arguments);
42
10
  this.open = false;
43
11
  this.persistent = false;
44
- this._itemHover = false;
45
- this._drawerHover = false;
46
- // @ts-ignore
47
- this._observer = new ResizeController(this, {
48
- target: window.document.body,
49
- callback: (entries) => {
50
- const entry = entries.pop();
51
- if (!entry || !entry.contentRect)
52
- return;
53
- const width = entry.contentRect.width;
54
- const persistentWidth = width > 1560;
55
- const activeHasSubMenu = this.hasActiveSubmenu();
56
- // If root nav item set and has submenu and persistent width meets the criteria
57
- const persistent = activeHasSubMenu && persistentWidth;
58
- if (this.persistent !== persistent) {
59
- if (!persistent) {
60
- this.open = false;
61
- }
62
- else {
63
- this.open = true;
64
- }
65
- this.persistent = persistent;
66
- }
67
- navigationRailHidden.value = width < 961;
68
- this.updateInlineStyles();
69
- },
70
- });
71
- // Bind methods to ensure the correct 'this' context
72
- this.hoverIn = this._hoverIn.bind(this);
73
- this.hoverOut = this._hoverOut.bind(this);
74
- this.handleClose = this._handleClose.bind(this);
75
- }
76
- disconnectedCallback() {
77
- // Clean up listeners
78
- this._asideElement.removeEventListener('mouseenter', this.hoverIn);
79
- this._asideElement.removeEventListener('mouseleave', this.hoverOut);
80
- this.removeEventListener('drawer-close', this.handleClose);
81
- }
82
- toggle() {
83
- this.open = !this.open;
84
- }
85
- _handleClose() {
86
- this.open = false;
87
12
  }
88
- _hoverIn() {
89
- navigationDrawerHover.value = true;
13
+ handleMouseEnter() {
14
+ this.fire('drawer-mouseenter');
90
15
  }
91
- _hoverOut() {
92
- navigationDrawerHover.value = false;
16
+ handleMouseLeave() {
17
+ this.fire('drawer-mouseleave');
93
18
  }
94
- hidemenu() {
95
- // Hide submenu when drawer is not persistent when mouse leaves the drawer or menu items
96
- if (!this._itemHover && !this._drawerHover && !(this.persistent && this.hasActiveSubmenu())) {
97
- this.open = false;
98
- }
99
- }
100
- updated() {
101
- if (this._itemHover !== navigationItemHover.value) {
102
- this._itemHover = navigationItemHover.value;
103
- if (this._itemHover) {
104
- this.open = true;
105
- }
106
- if (!this._itemHover) {
107
- // Timeout to allow for mouse transition to the content element
108
- setTimeout(this.hidemenu.bind(this), 100);
109
- }
110
- else {
111
- this.hidemenu();
112
- }
113
- }
114
- if (this._drawerHover !== navigationDrawerHover.value) {
115
- this._drawerHover = navigationDrawerHover.value;
116
- this.hidemenu();
117
- }
19
+ handleDrawerClose() {
20
+ this.fire('drawer-mouseleave');
118
21
  }
119
22
  async firstUpdated() {
23
+ var _a;
120
24
  await this.updateComplete;
121
- const drawer = this.drawer;
122
- if (drawer) {
123
- const shadowRoot = drawer.shadowRoot;
124
- if (shadowRoot) {
125
- const asideElement = shadowRoot.querySelector('aside');
126
- if (asideElement) {
127
- // Hack custom styles in the aside element
128
- asideElement.style.borderRightWidth = '0px';
129
- asideElement.style.borderRadius = '0px 16px 16px 0px';
130
- asideElement.style.top = '0px';
131
- asideElement.style.bottom = '0px';
132
- asideElement.style.height = 'unset';
133
- asideElement.style.transitionProperty = 'transform, box-shadow';
134
- asideElement.style.transitionDuration = '300ms';
135
- asideElement.style.transitionTimingFunction = 'cubic-bezier(0.2, 0, 0, 1)';
136
- asideElement.style.background = `var(--md-sys-color-surface-container)`;
137
- asideElement.style.borderLeft = '1px solid var(--md-sys-color-outline-variant)';
138
- asideElement.style.left = 'var(--_exm-navigation-rail-nav-width)';
139
- // Add event listeners to the aside element
140
- asideElement.addEventListener('mouseenter', this.hoverIn);
141
- asideElement.addEventListener('mouseleave', this.hoverOut);
142
- this._asideElement = asideElement;
143
- }
25
+ if ((_a = this.drawer) === null || _a === void 0 ? void 0 : _a.shadowRoot) {
26
+ const asideElement = this.drawer.shadowRoot.querySelector('aside');
27
+ if (asideElement) {
28
+ // Add event listeners to the aside element
29
+ asideElement.addEventListener('mouseenter', this.handleMouseEnter.bind(this));
30
+ asideElement.addEventListener('mouseleave', this.handleMouseLeave.bind(this));
144
31
  }
145
32
  }
146
- this.addEventListener('drawer-close', this.handleClose);
33
+ this.addEventListener('drawer-close', this.handleDrawerClose.bind(this));
147
34
  }
148
35
  render() {
149
- return html `<mwc-drawer type="dismissible" ?open=${this.open}>
150
- <div class="content">
151
- <slot></slot>
152
- </div>
153
- <slot name="appContent" slot="appContent"></slot>
154
- </mwc-drawer>`;
36
+ return html `<mwc-drawer type="dismissible" ?open=${this.open}><slot></slot></mwc-drawer>`;
155
37
  }
156
38
  }
39
+ ExmNavigationDrawerBase.styles = [style];
157
40
  __decorate([
158
- property({ type: Boolean }),
159
- observer(function (value) {
160
- navigationDrawerOpen.value = value;
161
- this.updateInlineStyles();
162
- })
41
+ property({ type: Boolean })
163
42
  ], ExmNavigationDrawerBase.prototype, "open", void 0);
43
+ __decorate([
44
+ property({ type: Boolean })
45
+ ], ExmNavigationDrawerBase.prototype, "persistent", void 0);
164
46
  __decorate([
165
47
  query('mwc-drawer')
166
48
  ], ExmNavigationDrawerBase.prototype, "drawer", void 0);
167
- __decorate([
168
- property({ type: Boolean }),
169
- observer(function (value) {
170
- navigationDrawerPersistent.value = value;
171
- })
172
- ], ExmNavigationDrawerBase.prototype, "persistent", void 0);
173
49
  //# 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
+ }
@@ -0,0 +1,45 @@
1
+ import { __decorate } from "tslib";
2
+ import { html } from 'lit';
3
+ import { ExmgElement } from '@exmg/lit-base/index.js';
4
+ import { property } from 'lit/decorators.js';
5
+ import { repeat } from 'lit/directives/repeat.js';
6
+ import './exm-navigation-rail-nav-item.js';
7
+ import './exm-navigation-drawer-nav-item.js';
8
+ import '@material/web/list/list.js';
9
+ import '@exmg/exm-collapsed/exm-collapsed.js';
10
+ export class ExmNavigationDrawerMenuBase extends ExmgElement {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.items = [];
14
+ this.path = [];
15
+ }
16
+ handleDrawerMenuItemClick(path) {
17
+ this.fire('drawer-menu-item-click', path);
18
+ }
19
+ render() {
20
+ return html `<div class="top"><slot name="top"></slot></div>
21
+ <nav class="nav">
22
+ <md-list>
23
+ ${repeat(this.items || [], ({ id }) => id, (item) => html `
24
+ <exm-navigation-drawer-nav-item
25
+ type="button"
26
+ @click=${this.handleDrawerMenuItemClick.bind(this, item.id)}
27
+ ?has-submenu=${(item.items || []).length > 0}
28
+ ?selected=${item.id === this.path[0]}
29
+ icon=${item.icon || ''}
30
+ >
31
+ ${item.label}
32
+ </exm-navigation-drawer-nav-item>
33
+ `)}
34
+ </md-list>
35
+ </nav>
36
+ <div class="bottom"><slot name="bottom"></slot></div>`;
37
+ }
38
+ }
39
+ __decorate([
40
+ property({ type: Array })
41
+ ], ExmNavigationDrawerMenuBase.prototype, "items", void 0);
42
+ __decorate([
43
+ property({ type: Array })
44
+ ], ExmNavigationDrawerMenuBase.prototype, "path", void 0);
45
+ //# sourceMappingURL=exm-navigation-drawer-menu-base.js.map