@internetarchive/ia-topnav 1.3.13-alpha1 → 1.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/demo/app-root.ts CHANGED
@@ -12,9 +12,9 @@ export class AppRoot extends LitElement {
12
12
 
13
13
  @state() private canManageFlags = false;
14
14
 
15
- @state() private username = '';
15
+ @state() private username = '@foo';
16
16
 
17
- @state() private screenName = '';
17
+ @state() private screenName = '@foo-user';
18
18
 
19
19
  @state() private itemIdentifier = '';
20
20
 
package/demo/index.html CHANGED
@@ -4,6 +4,7 @@
4
4
  <head>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <meta charset="utf-8">
7
+ <title>Internet Archive topnav component</title>
7
8
  <style>
8
9
  html {
9
10
  font-size: 10px;
@@ -7,8 +7,8 @@ let AppRoot = class AppRoot extends LitElement {
7
7
  super(...arguments);
8
8
  this.admin = false;
9
9
  this.canManageFlags = false;
10
- this.username = '';
11
- this.screenName = '';
10
+ this.username = '@foo';
11
+ this.screenName = '@foo-user';
12
12
  this.itemIdentifier = '';
13
13
  }
14
14
  render() {
@@ -1 +1 @@
1
- {"version":3,"file":"app-root.js","sourceRoot":"","sources":["../../demo/app-root.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, LitElement, TemplateResult } from 'lit';\nimport { customElement, query, state } from 'lit/decorators.js';\nimport '../src/ia-topnav';\nimport type { IATopNav } from '../src/ia-topnav';\n\n@customElement('app-root')\nexport class AppRoot extends LitElement {\n @query('ia-topnav')\n private topnav!: IATopNav;\n\n @state() private admin = false;\n\n @state() private canManageFlags = false;\n\n @state() private username = '';\n\n @state() private screenName = '';\n\n @state() private itemIdentifier = '';\n\n render() {\n return html`\n <ia-topnav\n ?admin=${this.admin}\n ?canManageFlags=${this.canManageFlags}\n .username=${this.username}\n .screenName=${this.screenName}\n .itemIdentifier=${this.itemIdentifier}\n >\n </ia-topnav>\n\n ${this.devTools}\n `;\n }\n\n private get devTools(): TemplateResult {\n return html`\n <div id=\"dev-tools\">\n <h1>Dev Tools</h1>\n\n <h2>User menu</h2>\n <fieldset>\n <ul>\n <li>\n <button\n @click=${() => {\n this.screenName = 'brewster';\n this.username = '@brewster';\n }}\n >\n Switch username to brewster\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.screenName = 'a😊b😊c😊d😊e😊f😊g😊h😊i😊';\n this.username = '@test';\n }}\n >\n Switch username to a😊b😊c😊d😊e😊f😊g😊h😊i😊\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.screenName =\n 'الدكتور محمالدكتور محمد العجوز محمالدكتور محمد العجوز';\n this.username = '@test';\n }}\n >\n Switch username to محمالدكتور محمد العجوز الدكتور محمالدكتور\n محمد العجوز\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.username = '';\n this.screenName = '';\n }}\n >\n Switch to logged out\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.itemIdentifier = this.admin ? '' : 'boop';\n this.admin = !this.admin;\n }}\n >\n Toggle admin mode (${this.admin ? 'on' : 'off'}) (requires\n logged in)\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.canManageFlags = !this.canManageFlags;\n }}\n >\n Toggle manage flags mode (${this.canManageFlags ? 'on' : 'off'})\n (requires admin mode)\n </button>\n </li>\n </ul>\n </fieldset>\n\n <h2>Local Links</h2>\n <fieldset>\n <button\n @click=${() => {\n this.topnav.localLinks = false;\n }}\n >\n Disable local links\n </button>\n <button\n @click=${() => {\n this.topnav.localLinks = true;\n }}\n >\n Enable local links\n </button>\n </fieldset>\n\n <h2>Wayback Count</h2>\n <fieldset>\n <button\n @click=${() => {\n this.topnav.waybackPagesArchived = 'many, MAAAANNNY';\n }}\n >\n Change WB pages count\n </button>\n\n <button\n @click=${() => {\n this.topnav.waybackPagesArchived = '740 billion';\n }}\n >\n Reset WB pages count\n </button>\n </fieldset>\n\n <h2>Search</h2>\n <fieldset>\n <button\n @click=${() => {\n this.topnav.hideSearch = true;\n }}\n >\n Hide Top Row Search button, like on mobile\n </button>\n <button\n @click=${() => {\n this.topnav.hideSearch = false;\n }}\n >\n Show Top Row Search button, like on mobile\n </button>\n </fieldset>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: block;\n font-family: sans-serif;\n }\n\n #dev-tools {\n margin: 1rem;\n }\n `;\n}\n"]}
1
+ {"version":3,"file":"app-root.js","sourceRoot":"","sources":["../../demo/app-root.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, LitElement, TemplateResult } from 'lit';\nimport { customElement, query, state } from 'lit/decorators.js';\nimport '../src/ia-topnav';\nimport type { IATopNav } from '../src/ia-topnav';\n\n@customElement('app-root')\nexport class AppRoot extends LitElement {\n @query('ia-topnav')\n private topnav!: IATopNav;\n\n @state() private admin = false;\n\n @state() private canManageFlags = false;\n\n @state() private username = '@foo';\n\n @state() private screenName = '@foo-user';\n\n @state() private itemIdentifier = '';\n\n render() {\n return html`\n <ia-topnav\n ?admin=${this.admin}\n ?canManageFlags=${this.canManageFlags}\n .username=${this.username}\n .screenName=${this.screenName}\n .itemIdentifier=${this.itemIdentifier}\n >\n </ia-topnav>\n\n ${this.devTools}\n `;\n }\n\n private get devTools(): TemplateResult {\n return html`\n <div id=\"dev-tools\">\n <h1>Dev Tools</h1>\n\n <h2>User menu</h2>\n <fieldset>\n <ul>\n <li>\n <button\n @click=${() => {\n this.screenName = 'brewster';\n this.username = '@brewster';\n }}\n >\n Switch username to brewster\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.screenName = 'a😊b😊c😊d😊e😊f😊g😊h😊i😊';\n this.username = '@test';\n }}\n >\n Switch username to a😊b😊c😊d😊e😊f😊g😊h😊i😊\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.screenName =\n 'الدكتور محمالدكتور محمد العجوز محمالدكتور محمد العجوز';\n this.username = '@test';\n }}\n >\n Switch username to محمالدكتور محمد العجوز الدكتور محمالدكتور\n محمد العجوز\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.username = '';\n this.screenName = '';\n }}\n >\n Switch to logged out\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.itemIdentifier = this.admin ? '' : 'boop';\n this.admin = !this.admin;\n }}\n >\n Toggle admin mode (${this.admin ? 'on' : 'off'}) (requires\n logged in)\n </button>\n </li>\n\n <li>\n <button\n @click=${() => {\n this.canManageFlags = !this.canManageFlags;\n }}\n >\n Toggle manage flags mode (${this.canManageFlags ? 'on' : 'off'})\n (requires admin mode)\n </button>\n </li>\n </ul>\n </fieldset>\n\n <h2>Local Links</h2>\n <fieldset>\n <button\n @click=${() => {\n this.topnav.localLinks = false;\n }}\n >\n Disable local links\n </button>\n <button\n @click=${() => {\n this.topnav.localLinks = true;\n }}\n >\n Enable local links\n </button>\n </fieldset>\n\n <h2>Wayback Count</h2>\n <fieldset>\n <button\n @click=${() => {\n this.topnav.waybackPagesArchived = 'many, MAAAANNNY';\n }}\n >\n Change WB pages count\n </button>\n\n <button\n @click=${() => {\n this.topnav.waybackPagesArchived = '740 billion';\n }}\n >\n Reset WB pages count\n </button>\n </fieldset>\n\n <h2>Search</h2>\n <fieldset>\n <button\n @click=${() => {\n this.topnav.hideSearch = true;\n }}\n >\n Hide Top Row Search button, like on mobile\n </button>\n <button\n @click=${() => {\n this.topnav.hideSearch = false;\n }}\n >\n Show Top Row Search button, like on mobile\n </button>\n </fieldset>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: block;\n font-family: sans-serif;\n }\n\n #dev-tools {\n margin: 1rem;\n }\n `;\n}\n"]}
@@ -31,12 +31,15 @@ export declare class IATopNav extends LitElement {
31
31
  moveTo: string;
32
32
  };
33
33
  private menus;
34
+ private previousKeydownListener;
35
+ private keyboardNavigation?;
34
36
  private get normalizedBaseHost();
35
37
  static get styles(): import("lit").CSSResult;
36
38
  updated(props: PropertyValues): void;
37
39
  firstUpdated(): void;
38
40
  menuSetup(): void;
39
41
  menuToggled(e: CustomEvent): void;
42
+ navSearchBlurEvent(e: CustomEvent): void;
40
43
  openMediaSlider(): void;
41
44
  closeMediaSlider(): void;
42
45
  closeMenus(): void;
@@ -10,6 +10,7 @@ import './search-menu';
10
10
  import './signed-out-dropdown';
11
11
  import iaTopNavCSS from './styles/ia-topnav';
12
12
  import './user-menu';
13
+ import KeyboardNavigation from './lib/keyboard-navigation';
13
14
  let IATopNav = class IATopNav extends LitElement {
14
15
  constructor() {
15
16
  super(...arguments);
@@ -40,6 +41,7 @@ let IATopNav = class IATopNav extends LitElement {
40
41
  return iaTopNavCSS;
41
42
  }
42
43
  updated(props) {
44
+ var _a;
43
45
  if (props.has('username') ||
44
46
  props.has('waybackPagesArchived') ||
45
47
  props.has('itemIdentifier') ||
@@ -47,6 +49,17 @@ let IATopNav = class IATopNav extends LitElement {
47
49
  props.has('baseHost')) {
48
50
  this.menuSetup();
49
51
  }
52
+ if (this.openMenu === 'search') {
53
+ const targetElement = (_a = this.renderRoot.querySelector('search-menu')) === null || _a === void 0 ? void 0 : _a.shadowRoot;
54
+ if (targetElement) {
55
+ this.keyboardNavigation = new KeyboardNavigation(targetElement, this.openMenu);
56
+ if (this.previousKeydownListener) {
57
+ this.removeEventListener('keydown', this.previousKeydownListener);
58
+ }
59
+ this.addEventListener('keydown', this.keyboardNavigation.handleKeyDown);
60
+ this.previousKeydownListener = this.keyboardNavigation.handleKeyDown;
61
+ }
62
+ }
50
63
  }
51
64
  firstUpdated() {
52
65
  // close open menu on `esc` click
@@ -70,6 +83,20 @@ let IATopNav = class IATopNav extends LitElement {
70
83
  }
71
84
  this.closeMediaSlider();
72
85
  }
86
+ navSearchBlurEvent(e) {
87
+ var _a, _b;
88
+ if (this.previousKeydownListener) {
89
+ this.removeEventListener('keydown', this.previousKeydownListener);
90
+ }
91
+ const isUploadButton = (_a = e.detail) === null || _a === void 0 ? void 0 : _a.isUploadButton;
92
+ if (!isUploadButton) {
93
+ const searchMenu = this.renderRoot.querySelector('search-menu');
94
+ const elements = (_b = this.keyboardNavigation) === null || _b === void 0 ? void 0 : _b.getFocusableElements();
95
+ if (searchMenu && (elements === null || elements === void 0 ? void 0 : elements.length)) {
96
+ elements[0].focus();
97
+ }
98
+ }
99
+ }
73
100
  openMediaSlider() {
74
101
  this.mediaSliderOpen = true;
75
102
  }
@@ -208,14 +235,10 @@ let IATopNav = class IATopNav extends LitElement {
208
235
  @trackClick=${this.trackClick}
209
236
  @trackSubmit=${this.trackSubmit}
210
237
  @menuToggled=${this.menuToggled}
238
+ @navSearchBlur=${this.navSearchBlurEvent}
211
239
  >
212
240
  ${this.secondLogoSlot}
213
241
  </primary-nav>
214
- <desktop-subnav
215
- .baseHost=${this.normalizedBaseHost}
216
- .menuItems=${this.menus.more.links}
217
- @focus=${this.closeMenus}
218
- ></desktop-subnav>
219
242
  <media-slider
220
243
  .baseHost=${this.normalizedBaseHost}
221
244
  .config=${this.config}
@@ -237,6 +260,11 @@ let IATopNav = class IATopNav extends LitElement {
237
260
  @trackClick=${this.trackClick}
238
261
  @trackSubmit=${this.trackSubmit}
239
262
  ></search-menu>
263
+ <desktop-subnav
264
+ .baseHost=${this.normalizedBaseHost}
265
+ .menuItems=${this.menus.more.links}
266
+ @focus=${this.closeMenus}
267
+ ></desktop-subnav>
240
268
  <div
241
269
  id="close-layer"
242
270
  class="${this.closeLayerClass}"
@@ -1 +1 @@
1
- {"version":3,"file":"ia-topnav.js","sourceRoot":"","sources":["../../src/ia-topnav.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, PropertyValues, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { buildTopNavMenus, defaultTopNavConfig } from './data/menus';\nimport './desktop-subnav';\nimport './dropdown-menu';\nimport './media-slider';\nimport {\n IATopNavConfig,\n IATopNavMenuConfig,\n IATopNavSecondIdentitySlotMode,\n} from './models';\nimport './primary-nav';\nimport './search-menu';\nimport './signed-out-dropdown';\nimport iaTopNavCSS from './styles/ia-topnav';\nimport './user-menu';\n\n@customElement('ia-topnav')\nexport class IATopNav extends LitElement {\n @property({ type: Boolean }) localLinks = false;\n\n @property({ type: String }) waybackPagesArchived = '';\n\n @property({ type: String }) baseHost = 'https://archive.org';\n\n @property({ type: String }) mediaBaseHost = 'https://archive.org';\n\n @property({ type: Boolean }) admin = false;\n\n @property({ type: Boolean }) canManageFlags = false;\n\n @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;\n\n @property({ type: Boolean }) hideSearch = false;\n\n @property({ type: String }) itemIdentifier = '';\n\n @property({ type: Boolean }) mediaSliderOpen = false;\n\n @property({ type: String }) openMenu = '';\n\n @property({ type: String }) screenName: string = '';\n\n @property({ type: String }) searchIn = '';\n\n @property({ type: String }) searchQuery = '';\n\n @property({ type: String }) selectedMenuOption = '';\n\n @property({ type: String }) username: string = '';\n\n @property({ type: String }) userProfileImagePath =\n '/services/img/user/profile';\n\n @property({ type: String })\n secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';\n\n @property({ type: Object }) currentTab?: {\n mediatype: string;\n moveTo: string;\n };\n\n @state() private menus: IATopNavMenuConfig = buildTopNavMenus();\n\n private get normalizedBaseHost() {\n return !this.localLinks ? this.baseHost : '';\n }\n\n static get styles() {\n return iaTopNavCSS;\n }\n\n updated(props: PropertyValues) {\n if (\n props.has('username') ||\n props.has('waybackPagesArchived') ||\n props.has('itemIdentifier') ||\n props.has('localLinks') ||\n props.has('baseHost')\n ) {\n this.menuSetup();\n }\n }\n\n firstUpdated() {\n // close open menu on `esc` click\n document.addEventListener(\n 'keydown',\n (e) => {\n if (e.key === 'Escape') {\n this.openMenu = '';\n this.mediaSliderOpen = false;\n }\n },\n false,\n );\n }\n\n menuSetup() {\n // re/build the nav\n this.menus = buildTopNavMenus(\n this.username,\n this.normalizedBaseHost,\n this.waybackPagesArchived,\n this.itemIdentifier,\n );\n }\n\n menuToggled(e: CustomEvent) {\n const currentMenu = this.openMenu;\n this.openMenu = currentMenu === e.detail.menuName ? '' : e.detail.menuName;\n // Keeps media slider open if media menu is open\n if (this.openMenu === 'media') {\n return;\n }\n this.closeMediaSlider();\n }\n\n openMediaSlider() {\n this.mediaSliderOpen = true;\n }\n\n closeMediaSlider() {\n this.mediaSliderOpen = false;\n this.selectedMenuOption = '';\n }\n\n closeMenus() {\n this.openMenu = '';\n this.closeMediaSlider();\n }\n\n searchInChanged(e: CustomEvent) {\n this.searchIn = e.detail.searchIn;\n }\n\n trackClick(e: CustomEvent) {\n this.dispatchEvent(\n new CustomEvent('analyticsClick', {\n bubbles: true,\n composed: true,\n detail: e.detail,\n }),\n );\n }\n\n trackSubmit(e: CustomEvent) {\n this.dispatchEvent(\n new CustomEvent('analyticsSubmit', {\n bubbles: true,\n composed: true,\n detail: e.detail,\n }),\n );\n }\n\n mediaTypeSelected(e: CustomEvent) {\n if (this.selectedMenuOption === e.detail.mediatype) {\n this.closeMediaSlider();\n return;\n }\n this.selectedMenuOption = e.detail.mediatype;\n this.openMediaSlider();\n }\n\n get searchMenuOpened() {\n return this.openMenu === 'search';\n }\n\n get signedOutOpened() {\n return this.openMenu === 'login';\n }\n\n get userMenuOpened() {\n return this.openMenu === 'user';\n }\n\n get searchMenuTabIndex() {\n return this.searchMenuOpened ? '' : '-1';\n }\n\n get userMenuTabIndex() {\n return this.userMenuOpened ? '' : '-1';\n }\n\n get signedOutTabIndex() {\n return this.signedOutOpened ? '' : '-1';\n }\n\n get closeLayerClass() {\n return !!this.openMenu || this.mediaSliderOpen ? 'visible' : '';\n }\n\n get userMenu() {\n return html`\n <user-menu\n .baseHost=${this.normalizedBaseHost}\n .config=${this.config}\n .menuItems=${this.userMenuItems}\n ?open=${this.openMenu === 'user'}\n .username=${this.username}\n ?hideSearch=${this.hideSearch}\n tabindex=\"${this.userMenuTabIndex}\"\n @menuToggled=${this.menuToggled}\n @trackClick=${this.trackClick}\n @focusToOtherMenuItem=${(e: CustomEvent) =>\n (this.currentTab = e.detail)}\n ></user-menu>\n `;\n }\n\n get signedOutDropdown() {\n return html`\n <signed-out-dropdown\n .baseHost=${this.normalizedBaseHost}\n .config=${this.config}\n .open=${this.signedOutOpened}\n ?hideSearch=${this.hideSearch}\n tabindex=\"${this.signedOutTabIndex}\"\n .menuItems=${this.signedOutMenuItems}\n ></signed-out-dropdown>\n `;\n }\n\n get signedOutMenuItems() {\n return this.menus.signedOut;\n }\n\n /**\n * Most users just get the basic menu items.\n * For users with `/items` priv, additional admin menu items are included too.\n * Having the `/flags` priv adds a further admin item for managing flags.\n */\n get userMenuItems() {\n const basicItems = this.menus.user;\n\n let adminItems = this.menus.userAdmin;\n if (this.canManageFlags) {\n adminItems = adminItems.concat(this.menus.userAdminFlags);\n }\n\n return this.itemIdentifier && this.admin\n ? [basicItems, adminItems]\n : [basicItems];\n }\n\n get allowSecondaryIcon() {\n return this.secondIdentitySlotMode === 'allow';\n }\n\n get secondLogoSlot() {\n return this.allowSecondaryIcon\n ? html`\n <slot name=\"opt-sec-logo\" slot=\"opt-sec-logo\"></slot>\n <slot name=\"opt-sec-logo-mobile\" slot=\"opt-sec-logo-mobile\"></slot>\n `\n : nothing;\n }\n\n get separatorTemplate() {\n return html`<li class=\"divider\" role=\"presentation\"></li>`;\n }\n\n render() {\n return html`\n <div class=\"topnav\">\n <primary-nav\n .baseHost=${this.normalizedBaseHost}\n .mediaBaseHost=${this.mediaBaseHost}\n .config=${this.config}\n .openMenu=${this.openMenu}\n .screenName=${this.screenName}\n .searchIn=${this.searchIn}\n .searchQuery=${this.searchQuery}\n .secondIdentitySlotMode=${this.secondIdentitySlotMode}\n .selectedMenuOption=${this.selectedMenuOption}\n .username=${this.username}\n .userProfileImagePath=${this.userProfileImagePath}\n .currentTab=${this.currentTab}\n ?hideSearch=${this.hideSearch}\n @mediaTypeSelected=${this.mediaTypeSelected}\n @trackClick=${this.trackClick}\n @trackSubmit=${this.trackSubmit}\n @menuToggled=${this.menuToggled}\n >\n ${this.secondLogoSlot}\n </primary-nav>\n <desktop-subnav\n .baseHost=${this.normalizedBaseHost}\n .menuItems=${this.menus.more.links}\n @focus=${this.closeMenus}\n ></desktop-subnav>\n <media-slider\n .baseHost=${this.normalizedBaseHost}\n .config=${this.config}\n .selectedMenuOption=${this.selectedMenuOption}\n .mediaSliderOpen=${this.mediaSliderOpen}\n .menus=${this.menus}\n tabindex=\"${this.mediaSliderOpen ? '1' : '-1'}\"\n @focusToOtherMenuItem=${(e: CustomEvent) =>\n (this.currentTab = e.detail)}\n ></media-slider>\n </div>\n ${this.username ? this.userMenu : this.signedOutDropdown}\n <search-menu\n .baseHost=${this.normalizedBaseHost}\n .config=${this.config}\n .openMenu=${this.openMenu}\n tabindex=\"${this.searchMenuTabIndex}\"\n ?hideSearch=${this.hideSearch}\n @searchInChanged=${this.searchInChanged}\n @trackClick=${this.trackClick}\n @trackSubmit=${this.trackSubmit}\n ></search-menu>\n <div\n id=\"close-layer\"\n class=\"${this.closeLayerClass}\"\n @click=${this.closeMenus}\n ></div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"ia-topnav.js","sourceRoot":"","sources":["../../src/ia-topnav.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, PropertyValues, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { buildTopNavMenus, defaultTopNavConfig } from './data/menus';\nimport './desktop-subnav';\nimport './dropdown-menu';\nimport './media-slider';\nimport {\n IATopNavConfig,\n IATopNavMenuConfig,\n IATopNavSecondIdentitySlotMode,\n} from './models';\nimport './primary-nav';\nimport './search-menu';\nimport './signed-out-dropdown';\nimport iaTopNavCSS from './styles/ia-topnav';\nimport './user-menu';\nimport KeyboardNavigation from './lib/keyboard-navigation';\n\n@customElement('ia-topnav')\nexport class IATopNav extends LitElement {\n @property({ type: Boolean }) localLinks = false;\n\n @property({ type: String }) waybackPagesArchived = '';\n\n @property({ type: String }) baseHost = 'https://archive.org';\n\n @property({ type: String }) mediaBaseHost = 'https://archive.org';\n\n @property({ type: Boolean }) admin = false;\n\n @property({ type: Boolean }) canManageFlags = false;\n\n @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;\n\n @property({ type: Boolean }) hideSearch = false;\n\n @property({ type: String }) itemIdentifier = '';\n\n @property({ type: Boolean }) mediaSliderOpen = false;\n\n @property({ type: String }) openMenu = '';\n\n @property({ type: String }) screenName: string = '';\n\n @property({ type: String }) searchIn = '';\n\n @property({ type: String }) searchQuery = '';\n\n @property({ type: String }) selectedMenuOption = '';\n\n @property({ type: String }) username: string = '';\n\n @property({ type: String }) userProfileImagePath =\n '/services/img/user/profile';\n\n @property({ type: String })\n secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';\n\n @property({ type: Object }) currentTab?: {\n mediatype: string;\n moveTo: string;\n };\n\n @state() private menus: IATopNavMenuConfig = buildTopNavMenus();\n private previousKeydownListener: // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((this: HTMLElement, ev: KeyboardEvent) => any) | undefined;\n\n private keyboardNavigation?: KeyboardNavigation;\n\n private get normalizedBaseHost() {\n return !this.localLinks ? this.baseHost : '';\n }\n\n static get styles() {\n return iaTopNavCSS;\n }\n\n updated(props: PropertyValues) {\n if (\n props.has('username') ||\n props.has('waybackPagesArchived') ||\n props.has('itemIdentifier') ||\n props.has('localLinks') ||\n props.has('baseHost')\n ) {\n this.menuSetup();\n }\n\n if (this.openMenu === 'search') {\n const targetElement =\n this.renderRoot.querySelector('search-menu')?.shadowRoot;\n if (targetElement) {\n this.keyboardNavigation = new KeyboardNavigation(\n targetElement as unknown as HTMLElement,\n this.openMenu,\n );\n\n if (this.previousKeydownListener) {\n this.removeEventListener('keydown', this.previousKeydownListener);\n }\n this.addEventListener('keydown', this.keyboardNavigation.handleKeyDown);\n this.previousKeydownListener = this.keyboardNavigation.handleKeyDown;\n }\n }\n }\n\n firstUpdated() {\n // close open menu on `esc` click\n document.addEventListener(\n 'keydown',\n (e) => {\n if (e.key === 'Escape') {\n this.openMenu = '';\n this.mediaSliderOpen = false;\n }\n },\n false,\n );\n }\n\n menuSetup() {\n // re/build the nav\n this.menus = buildTopNavMenus(\n this.username,\n this.normalizedBaseHost,\n this.waybackPagesArchived,\n this.itemIdentifier,\n );\n }\n\n menuToggled(e: CustomEvent) {\n const currentMenu = this.openMenu;\n this.openMenu = currentMenu === e.detail.menuName ? '' : e.detail.menuName;\n // Keeps media slider open if media menu is open\n if (this.openMenu === 'media') {\n return;\n }\n this.closeMediaSlider();\n }\n\n navSearchBlurEvent(e: CustomEvent) {\n if (this.previousKeydownListener) {\n this.removeEventListener('keydown', this.previousKeydownListener);\n }\n\n const isUploadButton = e.detail?.isUploadButton;\n if (!isUploadButton) {\n const searchMenu = this.renderRoot.querySelector(\n 'search-menu',\n ) as HTMLElement;\n const elements = this.keyboardNavigation?.getFocusableElements();\n if (searchMenu && elements?.length) {\n elements[0].focus();\n }\n }\n }\n\n openMediaSlider() {\n this.mediaSliderOpen = true;\n }\n\n closeMediaSlider() {\n this.mediaSliderOpen = false;\n this.selectedMenuOption = '';\n }\n\n closeMenus() {\n this.openMenu = '';\n this.closeMediaSlider();\n }\n\n searchInChanged(e: CustomEvent) {\n this.searchIn = e.detail.searchIn;\n }\n\n trackClick(e: CustomEvent) {\n this.dispatchEvent(\n new CustomEvent('analyticsClick', {\n bubbles: true,\n composed: true,\n detail: e.detail,\n }),\n );\n }\n\n trackSubmit(e: CustomEvent) {\n this.dispatchEvent(\n new CustomEvent('analyticsSubmit', {\n bubbles: true,\n composed: true,\n detail: e.detail,\n }),\n );\n }\n\n mediaTypeSelected(e: CustomEvent) {\n if (this.selectedMenuOption === e.detail.mediatype) {\n this.closeMediaSlider();\n return;\n }\n this.selectedMenuOption = e.detail.mediatype;\n this.openMediaSlider();\n }\n\n get searchMenuOpened() {\n return this.openMenu === 'search';\n }\n\n get signedOutOpened() {\n return this.openMenu === 'login';\n }\n\n get userMenuOpened() {\n return this.openMenu === 'user';\n }\n\n get searchMenuTabIndex() {\n return this.searchMenuOpened ? '' : '-1';\n }\n\n get userMenuTabIndex() {\n return this.userMenuOpened ? '' : '-1';\n }\n\n get signedOutTabIndex() {\n return this.signedOutOpened ? '' : '-1';\n }\n\n get closeLayerClass() {\n return !!this.openMenu || this.mediaSliderOpen ? 'visible' : '';\n }\n\n get userMenu() {\n return html`\n <user-menu\n .baseHost=${this.normalizedBaseHost}\n .config=${this.config}\n .menuItems=${this.userMenuItems}\n ?open=${this.openMenu === 'user'}\n .username=${this.username}\n ?hideSearch=${this.hideSearch}\n tabindex=\"${this.userMenuTabIndex}\"\n @menuToggled=${this.menuToggled}\n @trackClick=${this.trackClick}\n @focusToOtherMenuItem=${(e: CustomEvent) =>\n (this.currentTab = e.detail)}\n ></user-menu>\n `;\n }\n\n get signedOutDropdown() {\n return html`\n <signed-out-dropdown\n .baseHost=${this.normalizedBaseHost}\n .config=${this.config}\n .open=${this.signedOutOpened}\n ?hideSearch=${this.hideSearch}\n tabindex=\"${this.signedOutTabIndex}\"\n .menuItems=${this.signedOutMenuItems}\n ></signed-out-dropdown>\n `;\n }\n\n get signedOutMenuItems() {\n return this.menus.signedOut;\n }\n\n /**\n * Most users just get the basic menu items.\n * For users with `/items` priv, additional admin menu items are included too.\n * Having the `/flags` priv adds a further admin item for managing flags.\n */\n get userMenuItems() {\n const basicItems = this.menus.user;\n\n let adminItems = this.menus.userAdmin;\n if (this.canManageFlags) {\n adminItems = adminItems.concat(this.menus.userAdminFlags);\n }\n\n return this.itemIdentifier && this.admin\n ? [basicItems, adminItems]\n : [basicItems];\n }\n\n get allowSecondaryIcon() {\n return this.secondIdentitySlotMode === 'allow';\n }\n\n get secondLogoSlot() {\n return this.allowSecondaryIcon\n ? html`\n <slot name=\"opt-sec-logo\" slot=\"opt-sec-logo\"></slot>\n <slot name=\"opt-sec-logo-mobile\" slot=\"opt-sec-logo-mobile\"></slot>\n `\n : nothing;\n }\n\n get separatorTemplate() {\n return html`<li class=\"divider\" role=\"presentation\"></li>`;\n }\n\n render() {\n return html`\n <div class=\"topnav\">\n <primary-nav\n .baseHost=${this.normalizedBaseHost}\n .mediaBaseHost=${this.mediaBaseHost}\n .config=${this.config}\n .openMenu=${this.openMenu}\n .screenName=${this.screenName}\n .searchIn=${this.searchIn}\n .searchQuery=${this.searchQuery}\n .secondIdentitySlotMode=${this.secondIdentitySlotMode}\n .selectedMenuOption=${this.selectedMenuOption}\n .username=${this.username}\n .userProfileImagePath=${this.userProfileImagePath}\n .currentTab=${this.currentTab}\n ?hideSearch=${this.hideSearch}\n @mediaTypeSelected=${this.mediaTypeSelected}\n @trackClick=${this.trackClick}\n @trackSubmit=${this.trackSubmit}\n @menuToggled=${this.menuToggled}\n @navSearchBlur=${this.navSearchBlurEvent}\n >\n ${this.secondLogoSlot}\n </primary-nav>\n <media-slider\n .baseHost=${this.normalizedBaseHost}\n .config=${this.config}\n .selectedMenuOption=${this.selectedMenuOption}\n .mediaSliderOpen=${this.mediaSliderOpen}\n .menus=${this.menus}\n tabindex=\"${this.mediaSliderOpen ? '1' : '-1'}\"\n @focusToOtherMenuItem=${(e: CustomEvent) =>\n (this.currentTab = e.detail)}\n ></media-slider>\n </div>\n ${this.username ? this.userMenu : this.signedOutDropdown}\n <search-menu\n .baseHost=${this.normalizedBaseHost}\n .config=${this.config}\n .openMenu=${this.openMenu}\n tabindex=\"${this.searchMenuTabIndex}\"\n ?hideSearch=${this.hideSearch}\n @searchInChanged=${this.searchInChanged}\n @trackClick=${this.trackClick}\n @trackSubmit=${this.trackSubmit}\n ></search-menu>\n <desktop-subnav\n .baseHost=${this.normalizedBaseHost}\n .menuItems=${this.menus.more.links}\n @focus=${this.closeMenus}\n ></desktop-subnav>\n <div\n id=\"close-layer\"\n class=\"${this.closeLayerClass}\"\n @click=${this.closeMenus}\n ></div>\n `;\n }\n}\n"]}
@@ -29,6 +29,11 @@ export default class KeyboardNavigation {
29
29
  * @param {string} key - The key that was pressed ('ArrowDown', 'ArrowRight', 'ArrowUp', or 'ArrowLeft').
30
30
  */
31
31
  handleArrowKey(key: string): void;
32
+ /**
33
+ * Handles the Tab key event and focuses the next or previous menu item.
34
+ * @param {KeyboardEvent} event - The keyboard event object.
35
+ */
36
+ handleTabKey(event: KeyboardEvent): void;
32
37
  /**
33
38
  * Focuses the previous focusable element in the container.
34
39
  */
@@ -37,14 +42,9 @@ export default class KeyboardNavigation {
37
42
  * Focuses the next focusable element in the container.
38
43
  */
39
44
  focusNext(): void;
40
- /**
41
- * Handles the Tab key event and focuses the next or previous menu item.
42
- * @param {KeyboardEvent} event - The keyboard event object.
43
- */
44
- handleTabKey(event: KeyboardEvent): void;
45
45
  /**
46
46
  * Focuses the other parent menu items based on the provided flag.
47
47
  * @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.
48
48
  */
49
- focusToOtherMenuItems(isPrevious?: boolean): void;
49
+ emitFocusToOtherMenuItems(isPrevious?: boolean): void;
50
50
  }
@@ -10,7 +10,9 @@ export default class KeyboardNavigation {
10
10
  this.menuOption = menuOption;
11
11
  this.focusableElements = this.getFocusableElements();
12
12
  this.focusedIndex = this.getInitialFocusedIndex();
13
- (_a = this.focusableElements[this.focusedIndex]) === null || _a === void 0 ? void 0 : _a.focus();
13
+ if (menuOption !== 'search') {
14
+ (_a = this.focusableElements[this.focusedIndex]) === null || _a === void 0 ? void 0 : _a.focus();
15
+ }
14
16
  this.handleKeyDown = this.handleKeyDown.bind(this);
15
17
  }
16
18
  /**
@@ -47,7 +49,7 @@ export default class KeyboardNavigation {
47
49
  else {
48
50
  elements = this.elementsContainer.querySelectorAll(focusableTagSelectors);
49
51
  }
50
- return Array.from(elements).filter(isDisabledOrHidden);
52
+ return Array.from(elements !== null && elements !== void 0 ? elements : []).filter(isDisabledOrHidden);
51
53
  }
52
54
  /**
53
55
  * Handles keyboard events and focuses the appropriate element.
@@ -83,6 +85,19 @@ export default class KeyboardNavigation {
83
85
  this.focusPrevious();
84
86
  }
85
87
  }
88
+ /**
89
+ * Handles the Tab key event and focuses the next or previous menu item.
90
+ * @param {KeyboardEvent} event - The keyboard event object.
91
+ */
92
+ handleTabKey(event) {
93
+ var _a;
94
+ const isShiftPressed = event.shiftKey;
95
+ this.emitFocusToOtherMenuItems(isShiftPressed);
96
+ (_a = this.focusableElements[this.focusedIndex]) === null || _a === void 0 ? void 0 : _a.blur();
97
+ if (!['search'].includes(this.menuOption)) {
98
+ event.preventDefault();
99
+ }
100
+ }
86
101
  /**
87
102
  * Focuses the previous focusable element in the container.
88
103
  */
@@ -105,24 +120,11 @@ export default class KeyboardNavigation {
105
120
  this.focusedIndex = (this.focusedIndex + 1) % this.focusableElements.length;
106
121
  (_a = this.focusableElements[this.focusedIndex]) === null || _a === void 0 ? void 0 : _a.focus();
107
122
  }
108
- /**
109
- * Handles the Tab key event and focuses the next or previous menu item.
110
- * @param {KeyboardEvent} event - The keyboard event object.
111
- */
112
- handleTabKey(event) {
113
- var _a;
114
- if (this.menuOption) {
115
- const isShiftPressed = event.shiftKey;
116
- this.focusToOtherMenuItems(isShiftPressed);
117
- }
118
- (_a = this.focusableElements[this.focusedIndex]) === null || _a === void 0 ? void 0 : _a.blur();
119
- event.preventDefault();
120
- }
121
123
  /**
122
124
  * Focuses the other parent menu items based on the provided flag.
123
125
  * @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.
124
126
  */
125
- focusToOtherMenuItems(isPrevious = false) {
127
+ emitFocusToOtherMenuItems(isPrevious = false) {
126
128
  this.elementsContainer.dispatchEvent(new CustomEvent('focusToOtherMenuItem', {
127
129
  bubbles: true,
128
130
  composed: true,
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-navigation.js","sourceRoot":"","sources":["../../../src/lib/keyboard-navigation.ts"],"names":[],"mappings":"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","sourcesContent":["export default class KeyboardNavigation {\n elementsContainer: HTMLElement;\n menuOption: string;\n focusableElements: HTMLElement[];\n focusedIndex: number;\n\n /**\n * Constructor for the KeyboardNavigation class.\n * @param {HTMLElement} elementsContainer - The container element that holds the focusable elements.\n * @param {string} menuOption - The type of menu option ('web' or 'usermenu').\n */\n constructor(elementsContainer: HTMLElement, menuOption: string) {\n this.elementsContainer = elementsContainer;\n this.menuOption = menuOption;\n this.focusableElements = this.getFocusableElements();\n this.focusedIndex = this.getInitialFocusedIndex();\n\n this.focusableElements[this.focusedIndex]?.focus();\n this.handleKeyDown = this.handleKeyDown.bind(this);\n }\n\n /**\n * Returns the initial focused index based on the menu option.\n * @returns {number} The initial focused index (0 for 'web', 1 for 'usermenu').\n */\n getInitialFocusedIndex(): number {\n return this.menuOption === 'usermenu' ? 1 : 0;\n }\n\n /**\n * Gets an array of focusable elements within the container.\n * @returns {HTMLElement[]} An array of focusable elements.\n */\n getFocusableElements(): HTMLElement[] {\n const focusableTagSelectors =\n 'a[href], button, input, [tabindex]:not([tabindex=\"-1\"])';\n const isDisabledOrHidden = (el: Element) =>\n !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden');\n\n let elements;\n if (this.menuOption === 'web') {\n // wayback focusable elements\n const waybackSlider =\n this.elementsContainer.querySelector('wayback-slider')?.shadowRoot;\n const waybackSearch = waybackSlider?.querySelector('wayback-search');\n const waybackSearchElements = Array.from(\n waybackSearch?.shadowRoot?.querySelectorAll(focusableTagSelectors) ??\n [],\n );\n\n const normalElements = Array.from(\n waybackSlider?.querySelectorAll(focusableTagSelectors) ?? [],\n );\n\n // wayback save-form focusable elements\n const savePageForm = waybackSlider?.querySelector('save-page-form');\n const savePageFormElements = Array.from(\n savePageForm?.shadowRoot?.querySelectorAll(focusableTagSelectors) ?? [],\n );\n\n elements = [\n ...waybackSearchElements,\n ...normalElements,\n ...savePageFormElements,\n ];\n } else {\n elements = this.elementsContainer.querySelectorAll(focusableTagSelectors);\n }\n\n return Array.from(elements).filter(isDisabledOrHidden) as HTMLElement[];\n }\n\n /**\n * Handles keyboard events and focuses the appropriate element.\n * @param {KeyboardEvent} event - The keyboard event object.\n */\n handleKeyDown(event: KeyboardEvent) {\n const { key } = event;\n const isArrowKey = [\n 'ArrowDown',\n 'ArrowRight',\n 'ArrowUp',\n 'ArrowLeft',\n ].includes(key);\n const isTabKey = key === 'Tab';\n\n if (isArrowKey) {\n this.handleArrowKey(key);\n event.preventDefault();\n } else if (isTabKey) {\n this.handleTabKey(event);\n }\n }\n\n /**\n * Handles arrow key events and focuses the next or previous element for topnav sub-nav and usermenu\n * @param {string} key - The key that was pressed ('ArrowDown', 'ArrowRight', 'ArrowUp', or 'ArrowLeft').\n */\n handleArrowKey(key: string) {\n const isDownOrRight = ['ArrowDown', 'ArrowRight'].includes(key);\n if (isDownOrRight) {\n this.focusNext();\n } else {\n this.focusPrevious();\n }\n }\n\n /**\n * Focuses the previous focusable element in the container.\n */\n focusPrevious() {\n if (this.focusableElements.length === 0) return;\n this.focusedIndex =\n (this.focusedIndex - 1 + this.focusableElements.length) %\n this.focusableElements.length;\n this.focusableElements[this.focusedIndex]?.focus();\n }\n\n /**\n * Focuses the next focusable element in the container.\n */\n focusNext() {\n if (this.focusableElements.length === 0) return;\n this.focusedIndex = (this.focusedIndex + 1) % this.focusableElements.length;\n this.focusableElements[this.focusedIndex]?.focus();\n }\n\n /**\n * Handles the Tab key event and focuses the next or previous menu item.\n * @param {KeyboardEvent} event - The keyboard event object.\n */\n handleTabKey(event: KeyboardEvent) {\n if (this.menuOption) {\n const isShiftPressed = event.shiftKey;\n this.focusToOtherMenuItems(isShiftPressed);\n }\n\n this.focusableElements[this.focusedIndex]?.blur();\n event.preventDefault();\n }\n\n /**\n * Focuses the other parent menu items based on the provided flag.\n * @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.\n */\n focusToOtherMenuItems(isPrevious: boolean = false) {\n this.elementsContainer.dispatchEvent(\n new CustomEvent('focusToOtherMenuItem', {\n bubbles: true,\n composed: true,\n detail: {\n mediatype: this.menuOption,\n moveTo: isPrevious ? 'prev' : 'next',\n },\n }),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"keyboard-navigation.js","sourceRoot":"","sources":["../../../src/lib/keyboard-navigation.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,OAAO,kBAAkB;IAMrC;;;;OAIG;IACH,YAAY,iBAA8B,EAAE,UAAkB;;QAC5D,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAElD,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,0CAAE,KAAK,EAAE,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,sBAAsB;QACpB,OAAO,IAAI,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAED;;;OAGG;IACH,oBAAoB;;QAClB,MAAM,qBAAqB,GACzB,yDAAyD,CAAC;QAC5D,MAAM,kBAAkB,GAAG,CAAC,EAAW,EAAE,EAAE,CACzC,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAElE,IAAI,QAAQ,CAAC;QACb,IAAI,IAAI,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;YAC9B,6BAA6B;YAC7B,MAAM,aAAa,GACjB,MAAA,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,gBAAgB,CAAC,0CAAE,UAAU,CAAC;YACrE,MAAM,aAAa,GAAG,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACrE,MAAM,qBAAqB,GAAG,KAAK,CAAC,IAAI,CACtC,MAAA,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,UAAU,0CAAE,gBAAgB,CAAC,qBAAqB,CAAC,mCAChE,EAAE,CACL,CAAC;YAEF,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAC/B,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,gBAAgB,CAAC,qBAAqB,CAAC,mCAAI,EAAE,CAC7D,CAAC;YAEF,uCAAuC;YACvC,MAAM,YAAY,GAAG,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACpE,MAAM,oBAAoB,GAAG,KAAK,CAAC,IAAI,CACrC,MAAA,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,UAAU,0CAAE,gBAAgB,CAAC,qBAAqB,CAAC,mCAAI,EAAE,CACxE,CAAC;YAEF,QAAQ,GAAG;gBACT,GAAG,qBAAqB;gBACxB,GAAG,cAAc;gBACjB,GAAG,oBAAoB;aACxB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,CAAC,MAAM,CACtC,kBAAkB,CACF,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,KAAoB;QAChC,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACtB,MAAM,UAAU,GAAG;YACjB,WAAW;YACX,YAAY;YACZ,SAAS;YACT,WAAW;SACZ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChB,MAAM,QAAQ,GAAG,GAAG,KAAK,KAAK,CAAC;QAE/B,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YACzB,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,GAAW;QACxB,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChE,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,KAAoB;;QAC/B,MAAM,cAAc,GAAG,KAAK,CAAC,QAAQ,CAAC;QAEtC,IAAI,CAAC,yBAAyB,CAAC,cAAc,CAAC,CAAC;QAE/C,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,0CAAE,IAAI,EAAE,CAAC;QAClD,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa;;QACX,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChD,IAAI,CAAC,YAAY;YACf,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;gBACvD,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAChC,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,SAAS;;QACP,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChD,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAC5E,MAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,yBAAyB,CAAC,aAAsB,KAAK;QACnD,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAClC,IAAI,WAAW,CAAC,sBAAsB,EAAE;YACtC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,SAAS,EAAE,IAAI,CAAC,UAAU;gBAC1B,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;aACrC;SACF,CAAC,CACH,CAAC;IACJ,CAAC;CACF","sourcesContent":["export default class KeyboardNavigation {\n elementsContainer: HTMLElement;\n menuOption: string;\n focusableElements: HTMLElement[];\n focusedIndex: number;\n\n /**\n * Constructor for the KeyboardNavigation class.\n * @param {HTMLElement} elementsContainer - The container element that holds the focusable elements.\n * @param {string} menuOption - The type of menu option ('web' or 'usermenu').\n */\n constructor(elementsContainer: HTMLElement, menuOption: string) {\n this.elementsContainer = elementsContainer;\n this.menuOption = menuOption;\n this.focusableElements = this.getFocusableElements();\n this.focusedIndex = this.getInitialFocusedIndex();\n\n if (menuOption !== 'search') {\n this.focusableElements[this.focusedIndex]?.focus();\n }\n this.handleKeyDown = this.handleKeyDown.bind(this);\n }\n\n /**\n * Returns the initial focused index based on the menu option.\n * @returns {number} The initial focused index (0 for 'web', 1 for 'usermenu').\n */\n getInitialFocusedIndex(): number {\n return this.menuOption === 'usermenu' ? 1 : 0;\n }\n\n /**\n * Gets an array of focusable elements within the container.\n * @returns {HTMLElement[]} An array of focusable elements.\n */\n getFocusableElements(): HTMLElement[] {\n const focusableTagSelectors =\n 'a[href], button, input, [tabindex]:not([tabindex=\"-1\"])';\n const isDisabledOrHidden = (el: Element) =>\n !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden');\n\n let elements;\n if (this.menuOption === 'web') {\n // wayback focusable elements\n const waybackSlider =\n this.elementsContainer.querySelector('wayback-slider')?.shadowRoot;\n const waybackSearch = waybackSlider?.querySelector('wayback-search');\n const waybackSearchElements = Array.from(\n waybackSearch?.shadowRoot?.querySelectorAll(focusableTagSelectors) ??\n [],\n );\n\n const normalElements = Array.from(\n waybackSlider?.querySelectorAll(focusableTagSelectors) ?? [],\n );\n\n // wayback save-form focusable elements\n const savePageForm = waybackSlider?.querySelector('save-page-form');\n const savePageFormElements = Array.from(\n savePageForm?.shadowRoot?.querySelectorAll(focusableTagSelectors) ?? [],\n );\n\n elements = [\n ...waybackSearchElements,\n ...normalElements,\n ...savePageFormElements,\n ];\n } else {\n elements = this.elementsContainer.querySelectorAll(focusableTagSelectors);\n }\n\n return Array.from(elements ?? []).filter(\n isDisabledOrHidden,\n ) as HTMLElement[];\n }\n\n /**\n * Handles keyboard events and focuses the appropriate element.\n * @param {KeyboardEvent} event - The keyboard event object.\n */\n handleKeyDown(event: KeyboardEvent) {\n const { key } = event;\n const isArrowKey = [\n 'ArrowDown',\n 'ArrowRight',\n 'ArrowUp',\n 'ArrowLeft',\n ].includes(key);\n const isTabKey = key === 'Tab';\n\n if (isArrowKey) {\n this.handleArrowKey(key);\n event.preventDefault();\n } else if (isTabKey) {\n this.handleTabKey(event);\n }\n }\n\n /**\n * Handles arrow key events and focuses the next or previous element for topnav sub-nav and usermenu\n * @param {string} key - The key that was pressed ('ArrowDown', 'ArrowRight', 'ArrowUp', or 'ArrowLeft').\n */\n handleArrowKey(key: string) {\n const isDownOrRight = ['ArrowDown', 'ArrowRight'].includes(key);\n if (isDownOrRight) {\n this.focusNext();\n } else {\n this.focusPrevious();\n }\n }\n\n /**\n * Handles the Tab key event and focuses the next or previous menu item.\n * @param {KeyboardEvent} event - The keyboard event object.\n */\n handleTabKey(event: KeyboardEvent) {\n const isShiftPressed = event.shiftKey;\n\n this.emitFocusToOtherMenuItems(isShiftPressed);\n\n this.focusableElements[this.focusedIndex]?.blur();\n if (!['search'].includes(this.menuOption)) {\n event.preventDefault();\n }\n }\n\n /**\n * Focuses the previous focusable element in the container.\n */\n focusPrevious() {\n if (this.focusableElements.length === 0) return;\n this.focusedIndex =\n (this.focusedIndex - 1 + this.focusableElements.length) %\n this.focusableElements.length;\n this.focusableElements[this.focusedIndex]?.focus();\n }\n\n /**\n * Focuses the next focusable element in the container.\n */\n focusNext() {\n if (this.focusableElements.length === 0) return;\n this.focusedIndex = (this.focusedIndex + 1) % this.focusableElements.length;\n this.focusableElements[this.focusedIndex]?.focus();\n }\n\n /**\n * Focuses the other parent menu items based on the provided flag.\n * @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.\n */\n emitFocusToOtherMenuItems(isPrevious: boolean = false) {\n this.elementsContainer.dispatchEvent(\n new CustomEvent('focusToOtherMenuItem', {\n bubbles: true,\n composed: true,\n detail: {\n mediatype: this.menuOption,\n moveTo: isPrevious ? 'prev' : 'next',\n },\n }),\n );\n }\n}\n"]}
@@ -18,15 +18,15 @@ let MediaSlider = class MediaSlider extends LitElement {
18
18
  return mediaSliderCSS;
19
19
  }
20
20
  updated(props) {
21
- var _a;
21
+ var _a, _b;
22
22
  if (props.has('selectedMenuOption') && this.selectedMenuOption) {
23
- const container = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.has-focused'); //?.shadowRoot;
23
+ const container = (_b = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.has-focused')) === null || _b === void 0 ? void 0 : _b.shadowRoot;
24
24
  if (container) {
25
25
  const keyboardNavigation = new KeyboardNavigation(container, this.selectedMenuOption);
26
- this.addEventListener('keydown', keyboardNavigation.handleKeyDown);
27
26
  if (this.previousKeydownListener) {
28
27
  this.removeEventListener('keydown', this.previousKeydownListener);
29
28
  }
29
+ this.addEventListener('keydown', keyboardNavigation.handleKeyDown);
30
30
  this.previousKeydownListener = keyboardNavigation.handleKeyDown;
31
31
  }
32
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"media-slider.js","sourceRoot":"","sources":["../../src/media-slider.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAkB,IAAI,EAAE,MAAM,KAAK,CAAC;AACvD,OAAO,gBAAgB,CAAC;AACxB,OAAO,cAAc,MAAM,uBAAuB,CAAC;AACnD,OAAO,kBAAkB,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAG9D,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,UAAU;IAApC;;QACuB,aAAQ,GAAG,EAAE,CAAC;QACd,WAAM,GAAmB,mBAAmB,CAAC;QAC5C,oBAAe,GAAG,KAAK,CAAC;QACzB,UAAK,GAAuB,gBAAgB,EAAE,CAAC;QAC/C,uBAAkB,GAAG,OAAO,CAAC;IAmH3D,CAAC;IA9GC,MAAM,KAAK,MAAM;QACf,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,KAAqB;;QAC3B,IAAI,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/D,MAAM,SAAS,GAAG,MAAA,IAAI,CAAC,UAAU,0CAAE,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe;YAEjF,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,CAC/C,SAAwB,EACxB,IAAI,CAAC,kBAAkB,CACxB,CAAC;gBACF,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;gBACnE,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;oBACjC,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;gBACpE,CAAC;gBACD,IAAI,CAAC,uBAAuB,GAAG,kBAAkB,CAAC,aAAa,CAAC;YAClE,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY;QACV,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU;YAChC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,CAAC;YACpD,CAAC,CAAC,IAAI,CAAC;QAET,IAAI,UAAU,EAAE,CAAC;YACf,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM;QACJ,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEpE,OAAO,IAAI,CAAA;;oCAEqB,kBAAkB;yCACb,kBAAkB;;;4BAG/B,IAAI,CAAC,QAAQ;0BACf,IAAI,CAAC,MAAM;yBACZ,IAAI,CAAC,kBAAkB,KAAK,OAAO;YAC1C,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,QAAQ;;6BAEC,IAAI,CAAC,KAAK,CAAC,KAAK;;;4BAGjB,IAAI,CAAC,QAAQ;0BACf,IAAI,CAAC,MAAM;yBACZ,IAAI,CAAC,kBAAkB,KAAK,QAAQ;YAC3C,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,QAAQ;;6BAEC,IAAI,CAAC,KAAK,CAAC,MAAM;;;4BAGlB,IAAI,CAAC,QAAQ;0BACf,IAAI,CAAC,MAAM;yBACZ,IAAI,CAAC,kBAAkB,KAAK,UAAU;YAC7C,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,QAAQ;;6BAEC,IAAI,CAAC,KAAK,CAAC,QAAQ;;;4BAGpB,IAAI,CAAC,QAAQ;0BACf,IAAI,CAAC,MAAM;yBACZ,IAAI,CAAC,kBAAkB,KAAK,OAAO;YAC1C,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,QAAQ;;6BAEC,IAAI,CAAC,KAAK,CAAC,KAAK;;;4BAGjB,IAAI,CAAC,QAAQ;0BACf,IAAI,CAAC,MAAM;yBACZ,IAAI,CAAC,kBAAkB,KAAK,OAAO;YAC1C,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,QAAQ;;6BAEC,IAAI,CAAC,KAAK,CAAC,KAAK;;;4BAGjB,IAAI,CAAC,QAAQ;0BACf,IAAI,CAAC,MAAM;yBACZ,IAAI,CAAC,kBAAkB,KAAK,KAAK;YACxC,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,QAAQ;;6BAEC,IAAI,CAAC,KAAK,CAAC,GAAG;;;4BAGf,IAAI,CAAC,QAAQ;0BACf,IAAI,CAAC,MAAM;yBACZ,IAAI,CAAC,kBAAkB,KAAK,MAAM;YACzC,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,QAAQ;;6BAEC,IAAI,CAAC,KAAK,CAAC,IAAI;;;;;;KAMvC,CAAC;IACJ,CAAC;CACF,CAAA;AAvH6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6CAAe;AACd;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CAA8C;AAC5C;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;oDAAyB;AACzB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAAgD;AAC/C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uDAA8B;AAL9C,WAAW;IADvB,aAAa,CAAC,cAAc,CAAC;GACjB,WAAW,CAwHvB","sourcesContent":["import { LitElement, PropertyValues, html } from 'lit';\nimport './media-subnav';\nimport mediaSliderCSS from './styles/media-slider';\nimport KeyboardNavigation from './lib/keyboard-navigation';\nimport { customElement, property } from 'lit/decorators.js';\nimport { IATopNavConfig, IATopNavMenuConfig } from './models';\nimport { buildTopNavMenus, defaultTopNavConfig } from './data/menus';\n\n@customElement('media-slider')\nexport class MediaSlider extends LitElement {\n @property({ type: String }) baseHost = '';\n @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;\n @property({ type: Boolean }) mediaSliderOpen = false;\n @property({ type: Object }) menus: IATopNavMenuConfig = buildTopNavMenus();\n @property({ type: String }) selectedMenuOption = 'texts';\n\n private previousKeydownListener: // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((this: HTMLElement, ev: KeyboardEvent) => any) | undefined;\n\n static get styles() {\n return mediaSliderCSS;\n }\n\n updated(props: PropertyValues) {\n if (props.has('selectedMenuOption') && this.selectedMenuOption) {\n const container = this.shadowRoot?.querySelector('.has-focused'); //?.shadowRoot;\n\n if (container) {\n const keyboardNavigation = new KeyboardNavigation(\n container as HTMLElement,\n this.selectedMenuOption,\n );\n this.addEventListener('keydown', keyboardNavigation.handleKeyDown);\n if (this.previousKeydownListener) {\n this.removeEventListener('keydown', this.previousKeydownListener);\n }\n this.previousKeydownListener = keyboardNavigation.handleKeyDown;\n }\n }\n }\n\n shouldUpdate() {\n const scrollPane = this.shadowRoot\n ? this.shadowRoot.querySelector('.information-menu')\n : null;\n\n if (scrollPane) {\n scrollPane.scrollTop = 0;\n }\n return true;\n }\n\n render() {\n const sliderDetailsClass = this.mediaSliderOpen ? 'open' : 'closed';\n\n return html`\n <div class=\"media-slider-container\">\n <div class=\"overflow-clip ${sliderDetailsClass}\">\n <div class=\"information-menu ${sliderDetailsClass}\">\n <div class=\"info-box\">\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'audio'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"audio\"\n .menuItems=${this.menus.audio}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'images'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"images\"\n .menuItems=${this.menus.images}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'software'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"software\"\n .menuItems=${this.menus.software}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'texts'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"texts\"\n .menuItems=${this.menus.texts}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'video'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"video\"\n .menuItems=${this.menus.video}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'web'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"web\"\n .menuItems=${this.menus.web}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'more'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"more\"\n .menuItems=${this.menus.more}\n ></media-subnav>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"media-slider.js","sourceRoot":"","sources":["../../src/media-slider.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, PropertyValues, html } from 'lit';\nimport './media-subnav';\nimport mediaSliderCSS from './styles/media-slider';\nimport KeyboardNavigation from './lib/keyboard-navigation';\nimport { customElement, property } from 'lit/decorators.js';\nimport { IATopNavConfig, IATopNavMenuConfig } from './models';\nimport { buildTopNavMenus, defaultTopNavConfig } from './data/menus';\n\n@customElement('media-slider')\nexport class MediaSlider extends LitElement {\n @property({ type: String }) baseHost = '';\n @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;\n @property({ type: Boolean }) mediaSliderOpen = false;\n @property({ type: Object }) menus: IATopNavMenuConfig = buildTopNavMenus();\n @property({ type: String }) selectedMenuOption = 'texts';\n\n private previousKeydownListener: // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((this: HTMLElement, ev: KeyboardEvent) => any) | undefined;\n\n static get styles() {\n return mediaSliderCSS;\n }\n\n updated(props: PropertyValues) {\n if (props.has('selectedMenuOption') && this.selectedMenuOption) {\n const container =\n this.shadowRoot?.querySelector('.has-focused')?.shadowRoot;\n if (container) {\n const keyboardNavigation = new KeyboardNavigation(\n container as unknown as HTMLElement,\n this.selectedMenuOption,\n );\n\n if (this.previousKeydownListener) {\n this.removeEventListener('keydown', this.previousKeydownListener);\n }\n this.addEventListener('keydown', keyboardNavigation.handleKeyDown);\n this.previousKeydownListener = keyboardNavigation.handleKeyDown;\n }\n }\n }\n\n shouldUpdate() {\n const scrollPane = this.shadowRoot\n ? this.shadowRoot.querySelector('.information-menu')\n : null;\n\n if (scrollPane) {\n scrollPane.scrollTop = 0;\n }\n return true;\n }\n\n render() {\n const sliderDetailsClass = this.mediaSliderOpen ? 'open' : 'closed';\n\n return html`\n <div class=\"media-slider-container\">\n <div class=\"overflow-clip ${sliderDetailsClass}\">\n <div class=\"information-menu ${sliderDetailsClass}\">\n <div class=\"info-box\">\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'audio'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"audio\"\n .menuItems=${this.menus.audio}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'images'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"images\"\n .menuItems=${this.menus.images}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'software'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"software\"\n .menuItems=${this.menus.software}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'texts'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"texts\"\n .menuItems=${this.menus.texts}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'video'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"video\"\n .menuItems=${this.menus.video}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'web'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"web\"\n .menuItems=${this.menus.web}\n ></media-subnav>\n <media-subnav\n .baseHost=${this.baseHost}\n .config=${this.config}\n class=\"${this.selectedMenuOption === 'more'\n ? 'has-focused'\n : 'hidden'}\"\n menu=\"more\"\n .menuItems=${this.menus.more}\n ></media-subnav>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n}\n"]}
@@ -36,6 +36,7 @@ export declare class PrimaryNav extends TrackedElement {
36
36
  get searchMenuOpen(): boolean;
37
37
  get allowSecondaryIcon(): boolean;
38
38
  get searchMenu(): import("lit").TemplateResult<1> | typeof nothing;
39
+ private emitNavSearchBlurEvent;
39
40
  get mobileDonateHeart(): import("lit").TemplateResult<1>;
40
41
  get uploadButtonTemplate(): import("lit").TemplateResult<1>;
41
42
  get userStateTemplate(): import("lit").TemplateResult<1>;
@@ -144,9 +144,25 @@ let PrimaryNav = class PrimaryNav extends TrackedElement {
144
144
  .openMenu=${this.openMenu}
145
145
  .searchIn=${this.searchIn}
146
146
  .searchQuery=${this.searchQuery}
147
+ @blur=${this.emitNavSearchBlurEvent}
147
148
  ></nav-search>
148
149
  `;
149
150
  }
151
+ emitNavSearchBlurEvent(e) {
152
+ var _a;
153
+ const relatedTarget = e.relatedTarget;
154
+ const isUploadButton = relatedTarget === null || relatedTarget === void 0 ? void 0 : relatedTarget.classList.contains('upload');
155
+ if (isUploadButton) {
156
+ ((_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('a.upload')).focus();
157
+ }
158
+ this.dispatchEvent(new CustomEvent('navSearchBlur', {
159
+ detail: {
160
+ isUploadButton: !!isUploadButton,
161
+ },
162
+ bubbles: true,
163
+ composed: true,
164
+ }));
165
+ }
150
166
  get mobileDonateHeart() {
151
167
  return html `
152
168
  <a
@@ -1 +1 @@
1
- {"version":3,"file":"primary-nav.js","sourceRoot":"","sources":["../../src/primary-nav.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, nothing, PropertyValues } from 'lit';\nimport TrackedElement from './tracked-element';\nimport icons from './assets/img/icons';\nimport './assets/img/hamburger';\nimport './login-button';\nimport './nav-search';\nimport './media-menu';\nimport logoWordmarkStacked from './assets/img/wordmark-stacked';\nimport primaryNavCSS from './styles/primary-nav';\nimport locationHandler from './lib/location-handler';\nimport formatUrl from './lib/format-url';\nimport { customElement, property } from 'lit/decorators.js';\nimport { IATopNavConfig, IATopNavSecondIdentitySlotMode } from './models';\nimport { defaultTopNavConfig } from './data/menus';\n\n@customElement('primary-nav')\nexport class PrimaryNav extends TrackedElement {\n @property({ type: String }) mediaBaseHost = 'https://archive.org';\n @property({ type: String }) baseHost = '';\n @property({ type: Boolean }) hideSearch = false;\n @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;\n @property({ type: String }) openMenu = '';\n @property({ type: String }) screenName = '';\n @property({ type: String }) searchIn = '';\n @property({ type: String }) searchQuery = '';\n @property({ type: String })\n secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';\n @property({ type: String }) selectedMenuOption = '';\n @property({ type: Boolean }) signedOutMenuOpen = false;\n @property({ type: Boolean }) userMenuOpen = false;\n @property({ type: Boolean }) mediaMenuAnimate = false;\n @property({ type: String }) username = '';\n @property({ type: String }) userProfileImagePath = '';\n @property({ type: Object }) currentTab:\n | { mediatype: string; moveTo: string }\n | undefined;\n signedOutMenuToggled: unknown;\n\n static get styles() {\n return primaryNavCSS;\n }\n\n toggleMediaMenu(e: Event) {\n this.trackClick(e);\n this.dispatchEvent(\n new CustomEvent('menuToggled', {\n detail: {\n menuName: 'media',\n },\n }),\n );\n }\n\n toggleSearchMenu(e: Event) {\n this.trackClick(e);\n this.dispatchEvent(\n new CustomEvent('menuToggled', {\n detail: {\n menuName: 'search',\n },\n }),\n );\n }\n\n toggleUserMenu(e: Event) {\n this.trackClick(e);\n this.dispatchEvent(\n new CustomEvent('menuToggled', {\n detail: {\n menuName: 'user',\n },\n }),\n );\n }\n\n updated(props: PropertyValues) {\n if (props.has('currentTab')) {\n // early return\n if (!this.currentTab || Object.keys(this.currentTab).length === 0)\n return nothing;\n\n const isUserMenuTab =\n this.currentTab && this.currentTab.mediatype === 'usermenu';\n if (isUserMenuTab) {\n const mediaButtons = Array.from(\n this.shadowRoot\n ?.querySelector('media-menu')\n ?.shadowRoot?.querySelectorAll('media-button') ?? [],\n );\n const lastMediaButton = mediaButtons.filter((element) => {\n return element.shadowRoot\n ?.querySelector('a')\n ?.classList.contains('images');\n });\n\n const focusElement =\n this.currentTab.moveTo === 'next'\n ? this.shadowRoot?.querySelector('a.upload')\n : lastMediaButton[0]?.shadowRoot?.querySelector('a.menu-item');\n\n if (focusElement) {\n (focusElement as HTMLElement).focus();\n }\n } else if (this.currentTab.moveTo === 'next') {\n if (this.shadowRoot?.querySelector('.user-menu')) {\n (this.shadowRoot?.querySelector('.user-menu') as HTMLElement).focus();\n } else {\n (\n this.shadowRoot\n ?.querySelector('login-button')\n ?.shadowRoot?.querySelectorAll('span a')[0] as HTMLElement\n )?.focus();\n }\n }\n }\n }\n\n get userIcon() {\n const userMenuClass = this.openMenu === 'user' ? 'active' : '';\n const userMenuToolTip =\n this.openMenu === 'user' ? 'Close user menu' : 'Expand user menu';\n\n return html`\n <button\n class=\"user-menu ${userMenuClass}\"\n title=\"${userMenuToolTip}\"\n @click=\"${this.toggleUserMenu}\"\n data-event-click-tracking=\"${this.config?.eventCategory}|NavUserMenu\"\n >\n <img\n src=\"${this.mediaBaseHost}${this.userProfileImagePath}\"\n alt=\"${this.screenName}\"\n />\n <span class=\"screen-name\" dir=\"auto\">${this.screenName}</span>\n </button>\n `;\n }\n\n get loginIcon() {\n return html`\n <login-button\n .baseHost=${this.baseHost}\n .config=${this.config}\n .dropdownOpen=${this.signedOutMenuOpen}\n .openMenu=${this.openMenu}\n @signedOutMenuToggled=${this.signedOutMenuToggled}\n ></login-button>\n `;\n }\n\n get searchMenuOpen() {\n return this.openMenu === 'search';\n }\n\n get allowSecondaryIcon() {\n return this.secondIdentitySlotMode === 'allow';\n }\n\n get searchMenu() {\n if (this.hideSearch) return nothing;\n\n return html`\n <button\n class=\"search-trigger\"\n @click=\"${this.toggleSearchMenu}\"\n data-event-click-tracking=\"${this.config?.eventCategory}|NavSearchOpen\"\n >\n ${icons.search}\n </button>\n <nav-search\n .baseHost=${this.baseHost}\n .config=${this.config}\n .locationHandler=${locationHandler}\n .open=${this.searchMenuOpen}\n .openMenu=${this.openMenu}\n .searchIn=${this.searchIn}\n .searchQuery=${this.searchQuery}\n ></nav-search>\n `;\n }\n\n get mobileDonateHeart() {\n return html`\n <a\n class=\"mobile-donate-link\"\n .href=${formatUrl(\n '/donate/?origin=iawww-mbhrt' as string & Location,\n this.baseHost,\n )}\n >\n ${icons.donateUnpadded}\n <span class=\"sr-only\">\"Donate to the archive\"</span>\n </a>\n `;\n }\n\n get uploadButtonTemplate() {\n return html` <a\n .href=\"${formatUrl('/create' as string & Location, this.baseHost)}\"\n class=\"upload\"\n @focus=${this.toggleMediaMenu}\n >\n ${icons.upload}\n <span>Upload</span>\n </a>`;\n }\n\n get userStateTemplate() {\n return html`<div class=\"user-info\">\n ${this.username ? this.userIcon : this.loginIcon}\n </div>`;\n }\n\n get secondLogoSlot() {\n return this.allowSecondaryIcon\n ? html`\n <slot name=\"opt-sec-logo\"></slot>\n <slot name=\"opt-sec-logo-mobile\"></slot>\n `\n : nothing;\n }\n\n get secondLogoClass() {\n return this.allowSecondaryIcon ? 'second-logo' : '';\n }\n\n render() {\n // const mediaMenuTabIndex = this.openMenu === 'media' ? '' : '-1';\n return html`\n <nav class=${this.hideSearch ? 'hide-search' : ''}>\n <button\n class=\"hamburger\"\n @click=\"${this.toggleMediaMenu}\"\n data-event-click-tracking=\"${this.config?.eventCategory}|NavHamburger\"\n title=\"Open main menu\"\n >\n <icon-hamburger ?active=${this.openMenu === 'media'}></icon-hamburger>\n </button>\n\n <div class=${`branding ${this.secondLogoClass}`}>\n <a\n .href=${formatUrl('/' as string & Location, this.baseHost)}\n @click=${this.trackClick}\n data-event-click-tracking=\"${this.config?.eventCategory}|NavHome\"\n title=\"Go home\"\n class=\"link-home\"\n >${icons.iaLogo}${logoWordmarkStacked}</a\n >\n ${this.secondLogoSlot}\n </div>\n <media-menu\n .baseHost=${this.baseHost}\n .config=${this.config}\n ?mediaMenuAnimate=${this.mediaMenuAnimate}\n .selectedMenuOption=${this.selectedMenuOption}\n .openMenu=${this.openMenu}\n .currentTab=${this.currentTab}\n ></media-menu>\n <div class=\"right-side-section\">\n ${this.mobileDonateHeart} ${this.userStateTemplate}\n ${this.uploadButtonTemplate} ${this.searchMenu}\n </div>\n </nav>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"primary-nav.js","sourceRoot":"","sources":["../../src/primary-nav.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, nothing, PropertyValues } from 'lit';\nimport TrackedElement from './tracked-element';\nimport icons from './assets/img/icons';\nimport './assets/img/hamburger';\nimport './login-button';\nimport './nav-search';\nimport './media-menu';\nimport logoWordmarkStacked from './assets/img/wordmark-stacked';\nimport primaryNavCSS from './styles/primary-nav';\nimport locationHandler from './lib/location-handler';\nimport formatUrl from './lib/format-url';\nimport { customElement, property } from 'lit/decorators.js';\nimport { IATopNavConfig, IATopNavSecondIdentitySlotMode } from './models';\nimport { defaultTopNavConfig } from './data/menus';\n\n@customElement('primary-nav')\nexport class PrimaryNav extends TrackedElement {\n @property({ type: String }) mediaBaseHost = 'https://archive.org';\n @property({ type: String }) baseHost = '';\n @property({ type: Boolean }) hideSearch = false;\n @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;\n @property({ type: String }) openMenu = '';\n @property({ type: String }) screenName = '';\n @property({ type: String }) searchIn = '';\n @property({ type: String }) searchQuery = '';\n @property({ type: String })\n secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';\n @property({ type: String }) selectedMenuOption = '';\n @property({ type: Boolean }) signedOutMenuOpen = false;\n @property({ type: Boolean }) userMenuOpen = false;\n @property({ type: Boolean }) mediaMenuAnimate = false;\n @property({ type: String }) username = '';\n @property({ type: String }) userProfileImagePath = '';\n @property({ type: Object }) currentTab:\n | { mediatype: string; moveTo: string }\n | undefined;\n signedOutMenuToggled: unknown;\n\n static get styles() {\n return primaryNavCSS;\n }\n\n toggleMediaMenu(e: Event) {\n this.trackClick(e);\n this.dispatchEvent(\n new CustomEvent('menuToggled', {\n detail: {\n menuName: 'media',\n },\n }),\n );\n }\n\n toggleSearchMenu(e: Event) {\n this.trackClick(e);\n this.dispatchEvent(\n new CustomEvent('menuToggled', {\n detail: {\n menuName: 'search',\n },\n }),\n );\n }\n\n toggleUserMenu(e: Event) {\n this.trackClick(e);\n this.dispatchEvent(\n new CustomEvent('menuToggled', {\n detail: {\n menuName: 'user',\n },\n }),\n );\n }\n\n updated(props: PropertyValues) {\n if (props.has('currentTab')) {\n // early return\n if (!this.currentTab || Object.keys(this.currentTab).length === 0)\n return nothing;\n\n const isUserMenuTab =\n this.currentTab && this.currentTab.mediatype === 'usermenu';\n if (isUserMenuTab) {\n const mediaButtons = Array.from(\n this.shadowRoot\n ?.querySelector('media-menu')\n ?.shadowRoot?.querySelectorAll('media-button') ?? [],\n );\n const lastMediaButton = mediaButtons.filter((element) => {\n return element.shadowRoot\n ?.querySelector('a')\n ?.classList.contains('images');\n });\n\n const focusElement =\n this.currentTab.moveTo === 'next'\n ? this.shadowRoot?.querySelector('a.upload')\n : lastMediaButton[0]?.shadowRoot?.querySelector('a.menu-item');\n\n if (focusElement) {\n (focusElement as HTMLElement).focus();\n }\n } else if (this.currentTab.moveTo === 'next') {\n if (this.shadowRoot?.querySelector('.user-menu')) {\n (this.shadowRoot?.querySelector('.user-menu') as HTMLElement).focus();\n } else {\n (\n this.shadowRoot\n ?.querySelector('login-button')\n ?.shadowRoot?.querySelectorAll('span a')[0] as HTMLElement\n )?.focus();\n }\n }\n }\n }\n\n get userIcon() {\n const userMenuClass = this.openMenu === 'user' ? 'active' : '';\n const userMenuToolTip =\n this.openMenu === 'user' ? 'Close user menu' : 'Expand user menu';\n\n return html`\n <button\n class=\"user-menu ${userMenuClass}\"\n title=\"${userMenuToolTip}\"\n @click=\"${this.toggleUserMenu}\"\n data-event-click-tracking=\"${this.config?.eventCategory}|NavUserMenu\"\n >\n <img\n src=\"${this.mediaBaseHost}${this.userProfileImagePath}\"\n alt=\"${this.screenName}\"\n />\n <span class=\"screen-name\" dir=\"auto\">${this.screenName}</span>\n </button>\n `;\n }\n\n get loginIcon() {\n return html`\n <login-button\n .baseHost=${this.baseHost}\n .config=${this.config}\n .dropdownOpen=${this.signedOutMenuOpen}\n .openMenu=${this.openMenu}\n @signedOutMenuToggled=${this.signedOutMenuToggled}\n ></login-button>\n `;\n }\n\n get searchMenuOpen() {\n return this.openMenu === 'search';\n }\n\n get allowSecondaryIcon() {\n return this.secondIdentitySlotMode === 'allow';\n }\n\n get searchMenu() {\n if (this.hideSearch) return nothing;\n\n return html`\n <button\n class=\"search-trigger\"\n @click=\"${this.toggleSearchMenu}\"\n data-event-click-tracking=\"${this.config?.eventCategory}|NavSearchOpen\"\n >\n ${icons.search}\n </button>\n <nav-search\n .baseHost=${this.baseHost}\n .config=${this.config}\n .locationHandler=${locationHandler}\n .open=${this.searchMenuOpen}\n .openMenu=${this.openMenu}\n .searchIn=${this.searchIn}\n .searchQuery=${this.searchQuery}\n @blur=${this.emitNavSearchBlurEvent}\n ></nav-search>\n `;\n }\n\n private emitNavSearchBlurEvent(e: FocusEvent) {\n const relatedTarget = e.relatedTarget as HTMLElement;\n const isUploadButton = relatedTarget?.classList.contains('upload');\n\n if (isUploadButton) {\n (this.shadowRoot?.querySelector('a.upload') as HTMLElement).focus();\n }\n\n this.dispatchEvent(\n new CustomEvent('navSearchBlur', {\n detail: {\n isUploadButton: !!isUploadButton,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n get mobileDonateHeart() {\n return html`\n <a\n class=\"mobile-donate-link\"\n .href=${formatUrl(\n '/donate/?origin=iawww-mbhrt' as string & Location,\n this.baseHost,\n )}\n >\n ${icons.donateUnpadded}\n <span class=\"sr-only\">\"Donate to the archive\"</span>\n </a>\n `;\n }\n\n get uploadButtonTemplate() {\n return html` <a\n .href=\"${formatUrl('/create' as string & Location, this.baseHost)}\"\n class=\"upload\"\n @focus=${this.toggleMediaMenu}\n >\n ${icons.upload}\n <span>Upload</span>\n </a>`;\n }\n\n get userStateTemplate() {\n return html`<div class=\"user-info\">\n ${this.username ? this.userIcon : this.loginIcon}\n </div>`;\n }\n\n get secondLogoSlot() {\n return this.allowSecondaryIcon\n ? html`\n <slot name=\"opt-sec-logo\"></slot>\n <slot name=\"opt-sec-logo-mobile\"></slot>\n `\n : nothing;\n }\n\n get secondLogoClass() {\n return this.allowSecondaryIcon ? 'second-logo' : '';\n }\n\n render() {\n // const mediaMenuTabIndex = this.openMenu === 'media' ? '' : '-1';\n return html`\n <nav class=${this.hideSearch ? 'hide-search' : ''}>\n <button\n class=\"hamburger\"\n @click=\"${this.toggleMediaMenu}\"\n data-event-click-tracking=\"${this.config?.eventCategory}|NavHamburger\"\n title=\"Open main menu\"\n >\n <icon-hamburger ?active=${this.openMenu === 'media'}></icon-hamburger>\n </button>\n\n <div class=${`branding ${this.secondLogoClass}`}>\n <a\n .href=${formatUrl('/' as string & Location, this.baseHost)}\n @click=${this.trackClick}\n data-event-click-tracking=\"${this.config?.eventCategory}|NavHome\"\n title=\"Go home\"\n class=\"link-home\"\n >${icons.iaLogo}${logoWordmarkStacked}</a\n >\n ${this.secondLogoSlot}\n </div>\n <media-menu\n .baseHost=${this.baseHost}\n .config=${this.config}\n ?mediaMenuAnimate=${this.mediaMenuAnimate}\n .selectedMenuOption=${this.selectedMenuOption}\n .openMenu=${this.openMenu}\n .currentTab=${this.currentTab}\n ></media-menu>\n <div class=\"right-side-section\">\n ${this.mobileDonateHeart} ${this.userStateTemplate}\n ${this.uploadButtonTemplate} ${this.searchMenu}\n </div>\n </nav>\n `;\n }\n}\n"]}
@@ -19,6 +19,7 @@ export default css `
19
19
  a {
20
20
  text-decoration: none;
21
21
  color: var(--subnavLinkColor);
22
+ outline: none;
22
23
  }
23
24
 
24
25
  a:hover,
@@ -1 +1 @@
1
- {"version":3,"file":"desktop-subnav.js","sourceRoot":"","sources":["../../../src/styles/desktop-subnav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCjB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport default css`\n ul {\n position: relative;\n z-index: 3;\n padding: 0.8rem 0;\n margin: 0;\n font-size: 1.2rem;\n text-transform: uppercase;\n text-align: center;\n background: var(--desktopSubnavBg);\n }\n\n li {\n display: inline-block;\n padding: 0 15px;\n }\n\n a {\n text-decoration: none;\n color: var(--subnavLinkColor);\n }\n\n a:hover,\n a:active,\n a:focus {\n color: var(--linkHoverColor);\n }\n\n .donate svg {\n width: 1.6rem;\n height: 1.6rem;\n vertical-align: top;\n fill: #f00;\n }\n`;\n"]}
1
+ {"version":3,"file":"desktop-subnav.js","sourceRoot":"","sources":["../../../src/styles/desktop-subnav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCjB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport default css`\n ul {\n position: relative;\n z-index: 3;\n padding: 0.8rem 0;\n margin: 0;\n font-size: 1.2rem;\n text-transform: uppercase;\n text-align: center;\n background: var(--desktopSubnavBg);\n }\n\n li {\n display: inline-block;\n padding: 0 15px;\n }\n\n a {\n text-decoration: none;\n color: var(--subnavLinkColor);\n outline: none;\n }\n\n a:hover,\n a:active,\n a:focus {\n color: var(--linkHoverColor);\n }\n\n .donate svg {\n width: 1.6rem;\n height: 1.6rem;\n vertical-align: top;\n fill: #f00;\n }\n`;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-topnav",
3
- "version": "1.3.13-alpha1",
3
+ "version": "1.3.14",
4
4
  "description": "Top nav for Internet Archive",
5
5
  "license": "AGPL-3.0-only",
6
6
  "main": "dist/index.js",
package/src/ia-topnav.ts CHANGED
@@ -15,6 +15,7 @@ import './search-menu';
15
15
  import './signed-out-dropdown';
16
16
  import iaTopNavCSS from './styles/ia-topnav';
17
17
  import './user-menu';
18
+ import KeyboardNavigation from './lib/keyboard-navigation';
18
19
 
19
20
  @customElement('ia-topnav')
20
21
  export class IATopNav extends LitElement {
@@ -62,6 +63,10 @@ export class IATopNav extends LitElement {
62
63
  };
63
64
 
64
65
  @state() private menus: IATopNavMenuConfig = buildTopNavMenus();
66
+ private previousKeydownListener: // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ ((this: HTMLElement, ev: KeyboardEvent) => any) | undefined;
68
+
69
+ private keyboardNavigation?: KeyboardNavigation;
65
70
 
66
71
  private get normalizedBaseHost() {
67
72
  return !this.localLinks ? this.baseHost : '';
@@ -81,6 +86,23 @@ export class IATopNav extends LitElement {
81
86
  ) {
82
87
  this.menuSetup();
83
88
  }
89
+
90
+ if (this.openMenu === 'search') {
91
+ const targetElement =
92
+ this.renderRoot.querySelector('search-menu')?.shadowRoot;
93
+ if (targetElement) {
94
+ this.keyboardNavigation = new KeyboardNavigation(
95
+ targetElement as unknown as HTMLElement,
96
+ this.openMenu,
97
+ );
98
+
99
+ if (this.previousKeydownListener) {
100
+ this.removeEventListener('keydown', this.previousKeydownListener);
101
+ }
102
+ this.addEventListener('keydown', this.keyboardNavigation.handleKeyDown);
103
+ this.previousKeydownListener = this.keyboardNavigation.handleKeyDown;
104
+ }
105
+ }
84
106
  }
85
107
 
86
108
  firstUpdated() {
@@ -117,6 +139,23 @@ export class IATopNav extends LitElement {
117
139
  this.closeMediaSlider();
118
140
  }
119
141
 
142
+ navSearchBlurEvent(e: CustomEvent) {
143
+ if (this.previousKeydownListener) {
144
+ this.removeEventListener('keydown', this.previousKeydownListener);
145
+ }
146
+
147
+ const isUploadButton = e.detail?.isUploadButton;
148
+ if (!isUploadButton) {
149
+ const searchMenu = this.renderRoot.querySelector(
150
+ 'search-menu',
151
+ ) as HTMLElement;
152
+ const elements = this.keyboardNavigation?.getFocusableElements();
153
+ if (searchMenu && elements?.length) {
154
+ elements[0].focus();
155
+ }
156
+ }
157
+ }
158
+
120
159
  openMediaSlider() {
121
160
  this.mediaSliderOpen = true;
122
161
  }
@@ -283,14 +322,10 @@ export class IATopNav extends LitElement {
283
322
  @trackClick=${this.trackClick}
284
323
  @trackSubmit=${this.trackSubmit}
285
324
  @menuToggled=${this.menuToggled}
325
+ @navSearchBlur=${this.navSearchBlurEvent}
286
326
  >
287
327
  ${this.secondLogoSlot}
288
328
  </primary-nav>
289
- <desktop-subnav
290
- .baseHost=${this.normalizedBaseHost}
291
- .menuItems=${this.menus.more.links}
292
- @focus=${this.closeMenus}
293
- ></desktop-subnav>
294
329
  <media-slider
295
330
  .baseHost=${this.normalizedBaseHost}
296
331
  .config=${this.config}
@@ -313,6 +348,11 @@ export class IATopNav extends LitElement {
313
348
  @trackClick=${this.trackClick}
314
349
  @trackSubmit=${this.trackSubmit}
315
350
  ></search-menu>
351
+ <desktop-subnav
352
+ .baseHost=${this.normalizedBaseHost}
353
+ .menuItems=${this.menus.more.links}
354
+ @focus=${this.closeMenus}
355
+ ></desktop-subnav>
316
356
  <div
317
357
  id="close-layer"
318
358
  class="${this.closeLayerClass}"
@@ -15,7 +15,9 @@ export default class KeyboardNavigation {
15
15
  this.focusableElements = this.getFocusableElements();
16
16
  this.focusedIndex = this.getInitialFocusedIndex();
17
17
 
18
- this.focusableElements[this.focusedIndex]?.focus();
18
+ if (menuOption !== 'search') {
19
+ this.focusableElements[this.focusedIndex]?.focus();
20
+ }
19
21
  this.handleKeyDown = this.handleKeyDown.bind(this);
20
22
  }
21
23
 
@@ -67,7 +69,9 @@ export default class KeyboardNavigation {
67
69
  elements = this.elementsContainer.querySelectorAll(focusableTagSelectors);
68
70
  }
69
71
 
70
- return Array.from(elements).filter(isDisabledOrHidden) as HTMLElement[];
72
+ return Array.from(elements ?? []).filter(
73
+ isDisabledOrHidden,
74
+ ) as HTMLElement[];
71
75
  }
72
76
 
73
77
  /**
@@ -105,6 +109,21 @@ export default class KeyboardNavigation {
105
109
  }
106
110
  }
107
111
 
112
+ /**
113
+ * Handles the Tab key event and focuses the next or previous menu item.
114
+ * @param {KeyboardEvent} event - The keyboard event object.
115
+ */
116
+ handleTabKey(event: KeyboardEvent) {
117
+ const isShiftPressed = event.shiftKey;
118
+
119
+ this.emitFocusToOtherMenuItems(isShiftPressed);
120
+
121
+ this.focusableElements[this.focusedIndex]?.blur();
122
+ if (!['search'].includes(this.menuOption)) {
123
+ event.preventDefault();
124
+ }
125
+ }
126
+
108
127
  /**
109
128
  * Focuses the previous focusable element in the container.
110
129
  */
@@ -125,25 +144,11 @@ export default class KeyboardNavigation {
125
144
  this.focusableElements[this.focusedIndex]?.focus();
126
145
  }
127
146
 
128
- /**
129
- * Handles the Tab key event and focuses the next or previous menu item.
130
- * @param {KeyboardEvent} event - The keyboard event object.
131
- */
132
- handleTabKey(event: KeyboardEvent) {
133
- if (this.menuOption) {
134
- const isShiftPressed = event.shiftKey;
135
- this.focusToOtherMenuItems(isShiftPressed);
136
- }
137
-
138
- this.focusableElements[this.focusedIndex]?.blur();
139
- event.preventDefault();
140
- }
141
-
142
147
  /**
143
148
  * Focuses the other parent menu items based on the provided flag.
144
149
  * @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.
145
150
  */
146
- focusToOtherMenuItems(isPrevious: boolean = false) {
151
+ emitFocusToOtherMenuItems(isPrevious: boolean = false) {
147
152
  this.elementsContainer.dispatchEvent(
148
153
  new CustomEvent('focusToOtherMenuItem', {
149
154
  bubbles: true,
@@ -23,17 +23,18 @@ export class MediaSlider extends LitElement {
23
23
 
24
24
  updated(props: PropertyValues) {
25
25
  if (props.has('selectedMenuOption') && this.selectedMenuOption) {
26
- const container = this.shadowRoot?.querySelector('.has-focused'); //?.shadowRoot;
27
-
26
+ const container =
27
+ this.shadowRoot?.querySelector('.has-focused')?.shadowRoot;
28
28
  if (container) {
29
29
  const keyboardNavigation = new KeyboardNavigation(
30
- container as HTMLElement,
30
+ container as unknown as HTMLElement,
31
31
  this.selectedMenuOption,
32
32
  );
33
- this.addEventListener('keydown', keyboardNavigation.handleKeyDown);
33
+
34
34
  if (this.previousKeydownListener) {
35
35
  this.removeEventListener('keydown', this.previousKeydownListener);
36
36
  }
37
+ this.addEventListener('keydown', keyboardNavigation.handleKeyDown);
37
38
  this.previousKeydownListener = keyboardNavigation.handleKeyDown;
38
39
  }
39
40
  }
@@ -175,10 +175,30 @@ export class PrimaryNav extends TrackedElement {
175
175
  .openMenu=${this.openMenu}
176
176
  .searchIn=${this.searchIn}
177
177
  .searchQuery=${this.searchQuery}
178
+ @blur=${this.emitNavSearchBlurEvent}
178
179
  ></nav-search>
179
180
  `;
180
181
  }
181
182
 
183
+ private emitNavSearchBlurEvent(e: FocusEvent) {
184
+ const relatedTarget = e.relatedTarget as HTMLElement;
185
+ const isUploadButton = relatedTarget?.classList.contains('upload');
186
+
187
+ if (isUploadButton) {
188
+ (this.shadowRoot?.querySelector('a.upload') as HTMLElement).focus();
189
+ }
190
+
191
+ this.dispatchEvent(
192
+ new CustomEvent('navSearchBlur', {
193
+ detail: {
194
+ isUploadButton: !!isUploadButton,
195
+ },
196
+ bubbles: true,
197
+ composed: true,
198
+ }),
199
+ );
200
+ }
201
+
182
202
  get mobileDonateHeart() {
183
203
  return html`
184
204
  <a
@@ -20,6 +20,7 @@ export default css`
20
20
  a {
21
21
  text-decoration: none;
22
22
  color: var(--subnavLinkColor);
23
+ outline: none;
23
24
  }
24
25
 
25
26
  a:hover,