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