@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
@@ -1,132 +1,132 @@
1
- import { CSSResult, html, nothing, PropertyValues, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators.js';
3
-
4
- import icons from './assets/img/icons';
5
- import { defaultTopNavConfig } from './data/menus';
6
- import formatUrl from './lib/format-url';
7
- import { makeBooleanString } from './lib/make-boolean-string';
8
- import { IATopNavConfig, IATopNavLink } from './models';
9
- import dropdownMenuCSS from './styles/dropdown-menu';
10
- import TrackedElement from './tracked-element';
11
- import { ifDefined } from 'lit/directives/if-defined.js';
12
- import KeyboardNavigation from './lib/keyboard-navigation';
13
-
14
- export default class DropdownMenu extends TrackedElement {
15
- @property({ type: String }) baseHost = '';
16
- @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
17
- @property({ type: Boolean }) hideSearch = false;
18
- @property({ type: Array }) menuItems: IATopNavLink[] | IATopNavLink[][] = [];
19
- @property({ type: Boolean }) animated = false;
20
- @property({ type: Boolean }) open = false;
21
-
22
- private previousKeydownListener?: // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
- (this: HTMLElement, ev: KeyboardEvent) => any;
24
-
25
- static get styles(): CSSResult[] {
26
- return [dropdownMenuCSS];
27
- }
28
-
29
- updated(props: PropertyValues) {
30
- if (props.has('open') && this.open) {
31
- const container = this.shadowRoot?.querySelector(
32
- '.nav-container',
33
- ) as HTMLElement;
34
-
35
- if (container) {
36
- const keyboardNavigation = new KeyboardNavigation(
37
- container,
38
- 'usermenu',
39
- );
40
- this.addEventListener('keydown', keyboardNavigation.handleKeyDown);
41
- if (this.previousKeydownListener) {
42
- this.removeEventListener('keydown', this.previousKeydownListener);
43
- }
44
- this.previousKeydownListener = keyboardNavigation.handleKeyDown;
45
- }
46
- }
47
- }
48
-
49
- get dropdownItems() {
50
- if (!this.menuItems) return nothing;
51
-
52
- if (!Array.isArray(this.menuItems[0])) {
53
- const submenu = this.menuItems as IATopNavLink[];
54
- return this.dropdownSection(submenu);
55
- }
56
- return this.menuItems.map((submenu, i) => {
57
- const joiner = i ? DropdownMenu.dropdownDivider : html``;
58
- if (!Array.isArray(submenu)) {
59
- return;
60
- }
61
- return [joiner, ...this.dropdownSection(submenu)];
62
- });
63
- }
64
-
65
- static get dropdownDivider() {
66
- return html`<li class="divider"></li>`;
67
- }
68
-
69
- private dropdownSection(submenu: IATopNavLink[]): TemplateResult[] {
70
- return submenu.map(
71
- (item) => html`
72
- <li>
73
- ${item.url
74
- ? this.dropdownLink(item)
75
- : DropdownMenu.dropdownText(item)}
76
- </li>
77
- `,
78
- );
79
- }
80
-
81
- dropdownLink(link: IATopNavLink): TemplateResult {
82
- const calloutText = this.config?.callouts?.[link.title];
83
- const isMobileUpload = link.class === 'mobile-upload';
84
- const isTabbable = this.open && !isMobileUpload;
85
-
86
- return html`<a
87
- href="${formatUrl(link.url, this.baseHost)}"
88
- class=${ifDefined(link.class)}
89
- tabindex="${isTabbable ? '' : '-1'}"
90
- @click=${this.trackClick}
91
- data-event-click-tracking="${this.config
92
- ?.eventCategory}|Nav${link.analyticsEvent}"
93
- aria-label=${calloutText ? `New feature: ${link.title}` : nothing}
94
- >
95
- ${isMobileUpload ? icons.uploadUnpadded : nothing} ${link.title}
96
- ${calloutText
97
- ? html`<span class="callout" aria-hidden="true">${calloutText}</span>`
98
- : nothing}
99
- </a>`;
100
- }
101
-
102
- static dropdownText(item: IATopNavLink) {
103
- return html`<span class="info-item">${item.title}</span>`;
104
- }
105
-
106
- get menuClass() {
107
- const hiddenClass = this.hideSearch ? ' search-hidden' : '';
108
- if (this.open) {
109
- return `open${hiddenClass}`;
110
- }
111
- if (this.animated) {
112
- return `closed${hiddenClass}`;
113
- }
114
- return `initial${hiddenClass}`;
115
- }
116
-
117
- render() {
118
- return html`
119
- <div class="nav-container">
120
- <nav
121
- class="${this.menuClass}"
122
- aria-hidden="${makeBooleanString(!this.open)}"
123
- aria-expanded="${makeBooleanString(this.open)}"
124
- >
125
- <ul>
126
- ${this.dropdownItems}
127
- </ul>
128
- </nav>
129
- </div>
130
- `;
131
- }
132
- }
1
+ import { CSSResult, html, nothing, PropertyValues, TemplateResult } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+
4
+ import icons from './assets/img/icons';
5
+ import { defaultTopNavConfig } from './data/menus';
6
+ import formatUrl from './lib/format-url';
7
+ import { makeBooleanString } from './lib/make-boolean-string';
8
+ import { IATopNavConfig, IATopNavLink } from './models';
9
+ import dropdownMenuCSS from './styles/dropdown-menu';
10
+ import TrackedElement from './tracked-element';
11
+ import { ifDefined } from 'lit/directives/if-defined.js';
12
+ import KeyboardNavigation from './lib/keyboard-navigation';
13
+
14
+ export default class DropdownMenu extends TrackedElement {
15
+ @property({ type: String }) baseHost = '';
16
+ @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
17
+ @property({ type: Boolean }) hideSearch = false;
18
+ @property({ type: Array }) menuItems: IATopNavLink[] | IATopNavLink[][] = [];
19
+ @property({ type: Boolean }) animated = false;
20
+ @property({ type: Boolean }) open = false;
21
+
22
+ private previousKeydownListener?: // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ (this: HTMLElement, ev: KeyboardEvent) => any;
24
+
25
+ static get styles(): CSSResult[] {
26
+ return [dropdownMenuCSS];
27
+ }
28
+
29
+ updated(props: PropertyValues) {
30
+ if (props.has('open') && this.open) {
31
+ const container = this.shadowRoot?.querySelector(
32
+ '.nav-container',
33
+ ) as HTMLElement;
34
+
35
+ if (container) {
36
+ const keyboardNavigation = new KeyboardNavigation(
37
+ container,
38
+ 'usermenu',
39
+ );
40
+ this.addEventListener('keydown', keyboardNavigation.handleKeyDown);
41
+ if (this.previousKeydownListener) {
42
+ this.removeEventListener('keydown', this.previousKeydownListener);
43
+ }
44
+ this.previousKeydownListener = keyboardNavigation.handleKeyDown;
45
+ }
46
+ }
47
+ }
48
+
49
+ get dropdownItems() {
50
+ if (!this.menuItems) return nothing;
51
+
52
+ if (!Array.isArray(this.menuItems[0])) {
53
+ const submenu = this.menuItems as IATopNavLink[];
54
+ return this.dropdownSection(submenu);
55
+ }
56
+ return this.menuItems.map((submenu, i) => {
57
+ const joiner = i ? DropdownMenu.dropdownDivider : html``;
58
+ if (!Array.isArray(submenu)) {
59
+ return;
60
+ }
61
+ return [joiner, ...this.dropdownSection(submenu)];
62
+ });
63
+ }
64
+
65
+ static get dropdownDivider() {
66
+ return html`<li class="divider"></li>`;
67
+ }
68
+
69
+ private dropdownSection(submenu: IATopNavLink[]): TemplateResult[] {
70
+ return submenu.map(
71
+ (item) => html`
72
+ <li>
73
+ ${item.url
74
+ ? this.dropdownLink(item)
75
+ : DropdownMenu.dropdownText(item)}
76
+ </li>
77
+ `,
78
+ );
79
+ }
80
+
81
+ dropdownLink(link: IATopNavLink): TemplateResult {
82
+ const calloutText = this.config?.callouts?.[link.title];
83
+ const isMobileUpload = link.class === 'mobile-upload';
84
+ const isTabbable = this.open && !isMobileUpload;
85
+
86
+ return html`<a
87
+ href="${formatUrl(link.url, this.baseHost)}"
88
+ class=${ifDefined(link.class)}
89
+ tabindex="${isTabbable ? '' : '-1'}"
90
+ @click=${this.trackClick}
91
+ data-event-click-tracking="${this.config
92
+ ?.eventCategory}|Nav${link.analyticsEvent}"
93
+ aria-label=${calloutText ? `New feature: ${link.title}` : nothing}
94
+ >
95
+ ${isMobileUpload ? icons.uploadUnpadded : nothing} ${link.title}
96
+ ${calloutText
97
+ ? html`<span class="callout" aria-hidden="true">${calloutText}</span>`
98
+ : nothing}
99
+ </a>`;
100
+ }
101
+
102
+ static dropdownText(item: IATopNavLink) {
103
+ return html`<span class="info-item">${item.title}</span>`;
104
+ }
105
+
106
+ get menuClass() {
107
+ const hiddenClass = this.hideSearch ? ' search-hidden' : '';
108
+ if (this.open) {
109
+ return `open${hiddenClass}`;
110
+ }
111
+ if (this.animated) {
112
+ return `closed${hiddenClass}`;
113
+ }
114
+ return `initial${hiddenClass}`;
115
+ }
116
+
117
+ render() {
118
+ return html`
119
+ <div class="nav-container">
120
+ <nav
121
+ class="${this.menuClass}"
122
+ aria-hidden="${makeBooleanString(!this.open)}"
123
+ aria-expanded="${makeBooleanString(this.open)}"
124
+ >
125
+ <ul>
126
+ ${this.dropdownItems}
127
+ </ul>
128
+ </nav>
129
+ </div>
130
+ `;
131
+ }
132
+ }