@internetarchive/ia-topnav 2.0.0 → 2.0.1-alpha-webdev8396.0

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 (52) hide show
  1. package/dist/src/data/menus.js.map +1 -1
  2. package/dist/src/dropdown-menu.d.ts +3 -4
  3. package/dist/src/dropdown-menu.js +6 -13
  4. package/dist/src/dropdown-menu.js.map +1 -1
  5. package/dist/src/ia-topnav.d.ts +3 -0
  6. package/dist/src/ia-topnav.js +79 -69
  7. package/dist/src/ia-topnav.js.map +1 -1
  8. package/dist/src/login-button.d.ts +3 -0
  9. package/dist/src/login-button.js +28 -18
  10. package/dist/src/login-button.js.map +1 -1
  11. package/dist/src/models.js.map +1 -1
  12. package/dist/src/primary-nav.d.ts +4 -0
  13. package/dist/src/primary-nav.js +109 -90
  14. package/dist/src/primary-nav.js.map +1 -1
  15. package/dist/src/signed-out-dropdown.d.ts +1 -1
  16. package/dist/src/signed-out-dropdown.js +1 -2
  17. package/dist/src/signed-out-dropdown.js.map +1 -1
  18. package/dist/src/styles/dropdown-menu.js +1 -0
  19. package/dist/src/styles/dropdown-menu.js.map +1 -1
  20. package/dist/src/styles/ia-topnav.js +82 -82
  21. package/dist/src/styles/ia-topnav.js.map +1 -1
  22. package/dist/src/styles/primary-nav.js +353 -353
  23. package/dist/src/styles/primary-nav.js.map +1 -1
  24. package/dist/src/user-menu.d.ts +1 -2
  25. package/dist/src/user-menu.js +1 -2
  26. package/dist/src/user-menu.js.map +1 -1
  27. package/dist/test/ia-topnav.test.js +9 -9
  28. package/dist/test/ia-topnav.test.js.map +1 -1
  29. package/dist/test/primary-nav.test.js +7 -7
  30. package/dist/test/primary-nav.test.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/data/menus.ts +650 -650
  33. package/src/dropdown-menu.ts +6 -12
  34. package/src/ia-topnav.ts +332 -318
  35. package/src/login-button.ts +89 -78
  36. package/src/models.ts +58 -58
  37. package/src/primary-nav.ts +300 -277
  38. package/src/signed-out-dropdown.ts +1 -2
  39. package/src/styles/dropdown-menu.ts +1 -0
  40. package/src/styles/ia-topnav.ts +85 -85
  41. package/src/styles/primary-nav.ts +356 -356
  42. package/src/user-menu.ts +3 -4
  43. package/test/ia-topnav.test.ts +282 -282
  44. package/test/primary-nav.test.ts +135 -135
  45. package/dist/src/styles/signed-out-dropdown.d.ts +0 -2
  46. package/dist/src/styles/signed-out-dropdown.js +0 -31
  47. package/dist/src/styles/signed-out-dropdown.js.map +0 -1
  48. package/dist/src/styles/user-menu.d.ts +0 -2
  49. package/dist/src/styles/user-menu.js +0 -31
  50. package/dist/src/styles/user-menu.js.map +0 -1
  51. package/src/styles/signed-out-dropdown.ts +0 -31
  52. package/src/styles/user-menu.ts +0 -31
package/src/ia-topnav.ts CHANGED
@@ -1,318 +1,332 @@
1
- import { LitElement, PropertyValues, html, nothing } from 'lit';
2
- import { customElement, property, state } from 'lit/decorators.js';
3
-
4
- import { buildTopNavMenus, defaultTopNavConfig } from './data/menus';
5
- import './desktop-subnav';
6
- import './dropdown-menu';
7
- import './media-slider';
8
- import {
9
- IATopNavConfig,
10
- IATopNavMenuConfig,
11
- IATopNavSecondIdentitySlotMode,
12
- } from './models';
13
- import './primary-nav';
14
- import './signed-out-dropdown';
15
- import iaTopNavCSS from './styles/ia-topnav';
16
- import './user-menu';
17
-
18
- @customElement('ia-topnav')
19
- export class IATopNav extends LitElement {
20
- @property({ type: Boolean }) localLinks = false;
21
-
22
- @property({ type: String }) waybackPagesArchived = '';
23
-
24
- @property({ type: String }) baseHost = 'https://archive.org';
25
-
26
- @property({ type: String }) mediaBaseHost = 'https://archive.org';
27
-
28
- @property({ type: Boolean }) admin = false;
29
-
30
- @property({ type: Boolean }) canManageFlags = false;
31
-
32
- @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
33
-
34
- @property({ type: Boolean }) hideSearch = false;
35
-
36
- @property({ type: String }) itemIdentifier = '';
37
-
38
- @property({ type: Boolean }) mediaSliderOpen = false;
39
-
40
- @property({ type: String }) openMenu = '';
41
-
42
- @property({ type: String }) screenName: string = '';
43
-
44
- @property({ type: String }) selectedMenuOption = '';
45
-
46
- @property({ type: String }) username: string = '';
47
-
48
- @property({ type: String }) userProfileImagePath =
49
- '/services/img/user/profile';
50
-
51
- @property({ type: String })
52
- secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';
53
-
54
- @property({ type: Object }) currentTab?: {
55
- mediatype: string;
56
- moveTo: string;
57
- };
58
-
59
- @state() private menus: IATopNavMenuConfig = buildTopNavMenus();
60
-
61
- private boundHandleKeydown = this.handleDocumentKeydown.bind(this);
62
-
63
- private boundHandleClick = this.handleDocumentClick.bind(this);
64
-
65
- private get normalizedBaseHost() {
66
- return !this.localLinks ? this.baseHost : '';
67
- }
68
-
69
- static get styles() {
70
- return iaTopNavCSS;
71
- }
72
-
73
- updated(props: PropertyValues) {
74
- if (
75
- props.has('username') ||
76
- props.has('waybackPagesArchived') ||
77
- props.has('itemIdentifier') ||
78
- props.has('localLinks') ||
79
- props.has('baseHost')
80
- ) {
81
- this.menuSetup();
82
- }
83
- }
84
-
85
- connectedCallback() {
86
- super.connectedCallback();
87
- document.addEventListener('keydown', this.boundHandleKeydown);
88
- document.addEventListener('click', this.boundHandleClick);
89
- }
90
-
91
- disconnectedCallback() {
92
- super.disconnectedCallback();
93
- document.removeEventListener('keydown', this.boundHandleKeydown);
94
- document.removeEventListener('click', this.boundHandleClick);
95
- }
96
-
97
- private handleDocumentKeydown(e: KeyboardEvent) {
98
- if (e.key === 'Escape') {
99
- this.openMenu = '';
100
- this.mediaSliderOpen = false;
101
- }
102
- }
103
-
104
- private handleDocumentClick(e: MouseEvent) {
105
- if (!this.openMenu) return;
106
- const path = e.composedPath();
107
- if (!path.includes(this)) {
108
- this.closeMenus();
109
- }
110
- }
111
-
112
- menuSetup() {
113
- // re/build the nav
114
- this.menus = buildTopNavMenus(
115
- this.username,
116
- this.normalizedBaseHost,
117
- this.waybackPagesArchived,
118
- this.itemIdentifier,
119
- );
120
- }
121
-
122
- menuToggled(e: CustomEvent) {
123
- const currentMenu = this.openMenu;
124
- this.openMenu = currentMenu === e.detail.menuName ? '' : e.detail.menuName;
125
- // Keeps media slider open if media menu is open
126
- if (this.openMenu === 'media') {
127
- return;
128
- }
129
- this.closeMediaSlider();
130
- }
131
-
132
- openMediaSlider() {
133
- this.mediaSliderOpen = true;
134
- }
135
-
136
- closeMediaSlider() {
137
- this.mediaSliderOpen = false;
138
- this.selectedMenuOption = '';
139
- }
140
-
141
- closeMenus() {
142
- this.openMenu = '';
143
- this.closeMediaSlider();
144
- }
145
-
146
- trackClick(e: CustomEvent) {
147
- this.dispatchEvent(
148
- new CustomEvent('analyticsClick', {
149
- bubbles: true,
150
- composed: true,
151
- detail: e.detail,
152
- }),
153
- );
154
- }
155
-
156
- trackSubmit(e: CustomEvent) {
157
- this.dispatchEvent(
158
- new CustomEvent('analyticsSubmit', {
159
- bubbles: true,
160
- composed: true,
161
- detail: e.detail,
162
- }),
163
- );
164
- }
165
-
166
- mediaTypeSelected(e: CustomEvent) {
167
- if (this.selectedMenuOption === e.detail.mediatype) {
168
- this.closeMediaSlider();
169
- return;
170
- }
171
- this.selectedMenuOption = e.detail.mediatype;
172
- this.openMediaSlider();
173
- }
174
-
175
- get signedOutOpened() {
176
- return this.openMenu === 'login';
177
- }
178
-
179
- get userMenuOpened() {
180
- return this.openMenu === 'user';
181
- }
182
-
183
- get userMenuTabIndex() {
184
- return this.userMenuOpened ? '' : '-1';
185
- }
186
-
187
- get signedOutTabIndex() {
188
- return this.signedOutOpened ? '' : '-1';
189
- }
190
-
191
- get closeLayerClass() {
192
- return !!this.openMenu || this.mediaSliderOpen ? 'visible' : '';
193
- }
194
-
195
- get userMenu() {
196
- return html`
197
- <user-menu
198
- .baseHost=${this.normalizedBaseHost}
199
- .config=${this.config}
200
- .menuItems=${this.userMenuItems}
201
- ?open=${this.openMenu === 'user'}
202
- .username=${this.username}
203
- ?hideSearch=${this.hideSearch}
204
- tabindex="${this.userMenuTabIndex}"
205
- @menuToggled=${this.menuToggled}
206
- @trackClick=${this.trackClick}
207
- @focusToOtherMenuItem=${(e: CustomEvent) =>
208
- (this.currentTab = e.detail)}
209
- ></user-menu>
210
- `;
211
- }
212
-
213
- get signedOutDropdown() {
214
- return html`
215
- <signed-out-dropdown
216
- .baseHost=${this.normalizedBaseHost}
217
- .config=${this.config}
218
- .open=${this.signedOutOpened}
219
- ?hideSearch=${this.hideSearch}
220
- tabindex="${this.signedOutTabIndex}"
221
- .menuItems=${this.signedOutMenuItems}
222
- @focusToOtherMenuItem=${(e: CustomEvent) => {
223
- this.currentTab = e.detail;
224
- }}
225
- ></signed-out-dropdown>
226
- `;
227
- }
228
-
229
- get signedOutMenuItems() {
230
- return this.menus.signedOut;
231
- }
232
-
233
- /**
234
- * Most users just get the basic menu items.
235
- * For users with `/items` priv, additional admin menu items are included too.
236
- * Having the `/flags` priv adds a further admin item for managing flags.
237
- */
238
- get userMenuItems() {
239
- const basicItems = this.menus.user;
240
-
241
- let adminItems = this.menus.userAdmin;
242
- if (this.canManageFlags) {
243
- adminItems = adminItems.concat(this.menus.userAdminFlags);
244
- }
245
-
246
- return this.itemIdentifier && this.admin
247
- ? [basicItems, adminItems]
248
- : [basicItems];
249
- }
250
-
251
- get allowSecondaryIcon() {
252
- return this.secondIdentitySlotMode === 'allow';
253
- }
254
-
255
- get searchSlot() {
256
- return html`<slot name="search" slot="search"></slot>`;
257
- }
258
-
259
- get secondLogoSlot() {
260
- return this.allowSecondaryIcon
261
- ? html`
262
- <slot name="opt-sec-logo" slot="opt-sec-logo"></slot>
263
- <slot name="opt-sec-logo-mobile" slot="opt-sec-logo-mobile"></slot>
264
- `
265
- : nothing;
266
- }
267
-
268
- get separatorTemplate() {
269
- return html`<li class="divider" role="presentation"></li>`;
270
- }
271
-
272
- render() {
273
- return html`
274
- <div class="topnav">
275
- <primary-nav
276
- .baseHost=${this.normalizedBaseHost}
277
- .mediaBaseHost=${this.mediaBaseHost}
278
- .config=${this.config}
279
- .openMenu=${this.openMenu}
280
- .screenName=${this.screenName}
281
- .secondIdentitySlotMode=${this.secondIdentitySlotMode}
282
- .selectedMenuOption=${this.selectedMenuOption}
283
- .username=${this.username}
284
- .userProfileImagePath=${this.userProfileImagePath}
285
- .currentTab=${this.currentTab}
286
- ?hideSearch=${this.hideSearch}
287
- @mediaTypeSelected=${this.mediaTypeSelected}
288
- @trackClick=${this.trackClick}
289
- @trackSubmit=${this.trackSubmit}
290
- @menuToggled=${this.menuToggled}
291
- >
292
- ${this.secondLogoSlot} ${this.searchSlot}
293
- </primary-nav>
294
- <media-slider
295
- .baseHost=${this.normalizedBaseHost}
296
- .config=${this.config}
297
- .selectedMenuOption=${this.selectedMenuOption}
298
- .mediaSliderOpen=${this.mediaSliderOpen}
299
- .menus=${this.menus}
300
- tabindex="${this.mediaSliderOpen ? '1' : '-1'}"
301
- @focusToOtherMenuItem=${(e: CustomEvent) =>
302
- (this.currentTab = e.detail)}
303
- ></media-slider>
304
- </div>
305
- ${this.username ? this.userMenu : this.signedOutDropdown}
306
- <desktop-subnav
307
- .baseHost=${this.normalizedBaseHost}
308
- .menuItems=${this.menus.more.links}
309
- @focus=${this.closeMenus}
310
- ></desktop-subnav>
311
- <div
312
- id="close-layer"
313
- class="${this.closeLayerClass}"
314
- @click=${this.closeMenus}
315
- ></div>
316
- `;
317
- }
318
- }
1
+ import { LitElement, PropertyValues, html, nothing } from 'lit';
2
+ import { customElement, property, query, state } from 'lit/decorators.js';
3
+
4
+ import { buildTopNavMenus, defaultTopNavConfig } from './data/menus';
5
+ import './desktop-subnav';
6
+ import './dropdown-menu';
7
+ import './media-slider';
8
+ import {
9
+ IATopNavConfig,
10
+ IATopNavMenuConfig,
11
+ IATopNavSecondIdentitySlotMode,
12
+ } from './models';
13
+ import './primary-nav';
14
+ import type { PrimaryNav } from './primary-nav';
15
+ import './signed-out-dropdown';
16
+ import iaTopNavCSS from './styles/ia-topnav';
17
+ import './user-menu';
18
+
19
+ @customElement('ia-topnav')
20
+ export class IATopNav extends LitElement {
21
+ @property({ type: Boolean }) localLinks = false;
22
+
23
+ @property({ type: String }) waybackPagesArchived = '';
24
+
25
+ @property({ type: String }) baseHost = 'https://archive.org';
26
+
27
+ @property({ type: String }) mediaBaseHost = 'https://archive.org';
28
+
29
+ @property({ type: Boolean }) admin = false;
30
+
31
+ @property({ type: Boolean }) canManageFlags = false;
32
+
33
+ @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
34
+
35
+ @property({ type: Boolean }) hideSearch = false;
36
+
37
+ @property({ type: String }) itemIdentifier = '';
38
+
39
+ @property({ type: Boolean }) mediaSliderOpen = false;
40
+
41
+ @property({ type: String }) openMenu = '';
42
+
43
+ @property({ type: String }) screenName: string = '';
44
+
45
+ @property({ type: String }) selectedMenuOption = '';
46
+
47
+ @property({ type: String }) username: string = '';
48
+
49
+ @property({ type: String }) userProfileImagePath =
50
+ '/services/img/user/profile';
51
+
52
+ @property({ type: String })
53
+ secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';
54
+
55
+ @property({ type: Object }) currentTab?: {
56
+ mediatype: string;
57
+ moveTo: string;
58
+ };
59
+
60
+ @query('primary-nav') private primaryNav?: PrimaryNav;
61
+ /** Only one of user-menu or signed-out-dropdown is rendered at a time. */
62
+ @query('user-menu, signed-out-dropdown')
63
+ private accountDropdown?: HTMLElement;
64
+
65
+ @state() private menus: IATopNavMenuConfig = buildTopNavMenus();
66
+
67
+ private boundHandleKeydown = this.handleDocumentKeydown.bind(this);
68
+
69
+ private boundHandleClick = this.handleDocumentClick.bind(this);
70
+
71
+ private get normalizedBaseHost() {
72
+ return !this.localLinks ? this.baseHost : '';
73
+ }
74
+
75
+ static get styles() {
76
+ return iaTopNavCSS;
77
+ }
78
+
79
+ updated(props: PropertyValues) {
80
+ if (
81
+ props.has('username') ||
82
+ props.has('waybackPagesArchived') ||
83
+ props.has('itemIdentifier') ||
84
+ props.has('localLinks') ||
85
+ props.has('baseHost')
86
+ ) {
87
+ this.menuSetup();
88
+ }
89
+ }
90
+
91
+ connectedCallback() {
92
+ super.connectedCallback();
93
+ document.addEventListener('keydown', this.boundHandleKeydown);
94
+ document.addEventListener('click', this.boundHandleClick);
95
+ }
96
+
97
+ disconnectedCallback() {
98
+ super.disconnectedCallback();
99
+ document.removeEventListener('keydown', this.boundHandleKeydown);
100
+ document.removeEventListener('click', this.boundHandleClick);
101
+ }
102
+
103
+ private handleDocumentKeydown(e: KeyboardEvent) {
104
+ if (e.key === 'Escape') {
105
+ this.openMenu = '';
106
+ this.mediaSliderOpen = false;
107
+ }
108
+ }
109
+
110
+ private handleDocumentClick(e: MouseEvent) {
111
+ if (!this.openMenu) return;
112
+ const path = e.composedPath();
113
+ if (!path.includes(this)) {
114
+ this.closeMenus();
115
+ }
116
+ }
117
+
118
+ menuSetup() {
119
+ // re/build the nav
120
+ this.menus = buildTopNavMenus(
121
+ this.username,
122
+ this.normalizedBaseHost,
123
+ this.waybackPagesArchived,
124
+ this.itemIdentifier,
125
+ );
126
+ }
127
+
128
+ menuToggled(e: CustomEvent) {
129
+ const currentMenu = this.openMenu;
130
+ this.openMenu = currentMenu === e.detail.menuName ? '' : e.detail.menuName;
131
+ // Keeps media slider open if media menu is open
132
+ if (this.openMenu === 'media') {
133
+ return;
134
+ }
135
+ this.closeMediaSlider();
136
+
137
+ if (this.openMenu === 'user' || this.openMenu === 'login') {
138
+ if (this.primaryNav && this.accountDropdown) {
139
+ const right = this.primaryNav.getAccountDropdownOffset();
140
+ this.accountDropdown.style.setProperty(
141
+ '--dropdownMenuRight',
142
+ `${right}px`,
143
+ );
144
+ }
145
+ }
146
+ }
147
+
148
+ openMediaSlider() {
149
+ this.mediaSliderOpen = true;
150
+ }
151
+
152
+ closeMediaSlider() {
153
+ this.mediaSliderOpen = false;
154
+ this.selectedMenuOption = '';
155
+ }
156
+
157
+ closeMenus() {
158
+ this.openMenu = '';
159
+ this.closeMediaSlider();
160
+ }
161
+
162
+ trackClick(e: CustomEvent) {
163
+ this.dispatchEvent(
164
+ new CustomEvent('analyticsClick', {
165
+ bubbles: true,
166
+ composed: true,
167
+ detail: e.detail,
168
+ }),
169
+ );
170
+ }
171
+
172
+ trackSubmit(e: CustomEvent) {
173
+ this.dispatchEvent(
174
+ new CustomEvent('analyticsSubmit', {
175
+ bubbles: true,
176
+ composed: true,
177
+ detail: e.detail,
178
+ }),
179
+ );
180
+ }
181
+
182
+ mediaTypeSelected(e: CustomEvent) {
183
+ if (this.selectedMenuOption === e.detail.mediatype) {
184
+ this.closeMediaSlider();
185
+ return;
186
+ }
187
+ this.selectedMenuOption = e.detail.mediatype;
188
+ this.openMediaSlider();
189
+ }
190
+
191
+ get signedOutOpened() {
192
+ return this.openMenu === 'login';
193
+ }
194
+
195
+ get userMenuOpened() {
196
+ return this.openMenu === 'user';
197
+ }
198
+
199
+ get userMenuTabIndex() {
200
+ return this.userMenuOpened ? '' : '-1';
201
+ }
202
+
203
+ get signedOutTabIndex() {
204
+ return this.signedOutOpened ? '' : '-1';
205
+ }
206
+
207
+ get closeLayerClass() {
208
+ return !!this.openMenu || this.mediaSliderOpen ? 'visible' : '';
209
+ }
210
+
211
+ get userMenu() {
212
+ return html`
213
+ <user-menu
214
+ .baseHost=${this.normalizedBaseHost}
215
+ .config=${this.config}
216
+ .menuItems=${this.userMenuItems}
217
+ ?open=${this.openMenu === 'user'}
218
+ .username=${this.username}
219
+ tabindex="${this.userMenuTabIndex}"
220
+ @menuToggled=${this.menuToggled}
221
+ @trackClick=${this.trackClick}
222
+ @focusToOtherMenuItem=${(e: CustomEvent) =>
223
+ (this.currentTab = e.detail)}
224
+ ></user-menu>
225
+ `;
226
+ }
227
+
228
+ get signedOutDropdown() {
229
+ return html`
230
+ <signed-out-dropdown
231
+ .baseHost=${this.normalizedBaseHost}
232
+ .config=${this.config}
233
+ .open=${this.signedOutOpened}
234
+ tabindex="${this.signedOutTabIndex}"
235
+ .menuItems=${this.signedOutMenuItems}
236
+ @focusToOtherMenuItem=${(e: CustomEvent) => {
237
+ this.currentTab = e.detail;
238
+ }}
239
+ ></signed-out-dropdown>
240
+ `;
241
+ }
242
+
243
+ get signedOutMenuItems() {
244
+ return this.menus.signedOut;
245
+ }
246
+
247
+ /**
248
+ * Most users just get the basic menu items.
249
+ * For users with `/items` priv, additional admin menu items are included too.
250
+ * Having the `/flags` priv adds a further admin item for managing flags.
251
+ */
252
+ get userMenuItems() {
253
+ const basicItems = this.menus.user;
254
+
255
+ let adminItems = this.menus.userAdmin;
256
+ if (this.canManageFlags) {
257
+ adminItems = adminItems.concat(this.menus.userAdminFlags);
258
+ }
259
+
260
+ return this.itemIdentifier && this.admin
261
+ ? [basicItems, adminItems]
262
+ : [basicItems];
263
+ }
264
+
265
+ get allowSecondaryIcon() {
266
+ return this.secondIdentitySlotMode === 'allow';
267
+ }
268
+
269
+ get searchSlot() {
270
+ return html`<slot name="search" slot="search"></slot>`;
271
+ }
272
+
273
+ get secondLogoSlot() {
274
+ return this.allowSecondaryIcon
275
+ ? html`
276
+ <slot name="opt-sec-logo" slot="opt-sec-logo"></slot>
277
+ <slot name="opt-sec-logo-mobile" slot="opt-sec-logo-mobile"></slot>
278
+ `
279
+ : nothing;
280
+ }
281
+
282
+ get separatorTemplate() {
283
+ return html`<li class="divider" role="presentation"></li>`;
284
+ }
285
+
286
+ render() {
287
+ return html`
288
+ <div class="topnav">
289
+ <primary-nav
290
+ .baseHost=${this.normalizedBaseHost}
291
+ .mediaBaseHost=${this.mediaBaseHost}
292
+ .config=${this.config}
293
+ .openMenu=${this.openMenu}
294
+ .screenName=${this.screenName}
295
+ .secondIdentitySlotMode=${this.secondIdentitySlotMode}
296
+ .selectedMenuOption=${this.selectedMenuOption}
297
+ .username=${this.username}
298
+ .userProfileImagePath=${this.userProfileImagePath}
299
+ .currentTab=${this.currentTab}
300
+ ?hideSearch=${this.hideSearch}
301
+ @mediaTypeSelected=${this.mediaTypeSelected}
302
+ @trackClick=${this.trackClick}
303
+ @trackSubmit=${this.trackSubmit}
304
+ @menuToggled=${this.menuToggled}
305
+ >
306
+ ${this.secondLogoSlot} ${this.searchSlot}
307
+ </primary-nav>
308
+ <media-slider
309
+ .baseHost=${this.normalizedBaseHost}
310
+ .config=${this.config}
311
+ .selectedMenuOption=${this.selectedMenuOption}
312
+ .mediaSliderOpen=${this.mediaSliderOpen}
313
+ .menus=${this.menus}
314
+ tabindex="${this.mediaSliderOpen ? '1' : '-1'}"
315
+ @focusToOtherMenuItem=${(e: CustomEvent) =>
316
+ (this.currentTab = e.detail)}
317
+ ></media-slider>
318
+ </div>
319
+ ${this.username ? this.userMenu : this.signedOutDropdown}
320
+ <desktop-subnav
321
+ .baseHost=${this.normalizedBaseHost}
322
+ .menuItems=${this.menus.more.links}
323
+ @focus=${this.closeMenus}
324
+ ></desktop-subnav>
325
+ <div
326
+ id="close-layer"
327
+ class="${this.closeLayerClass}"
328
+ @click=${this.closeMenus}
329
+ ></div>
330
+ `;
331
+ }
332
+ }