@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.
- package/dist/index.d.ts +0 -1
- package/dist/index.js.map +1 -1
- package/dist/src/data/menus.js.map +1 -1
- package/dist/src/dropdown-menu.js +26 -26
- package/dist/src/dropdown-menu.js.map +1 -1
- package/dist/src/ia-topnav.d.ts +2 -13
- package/dist/src/ia-topnav.js +70 -140
- package/dist/src/ia-topnav.js.map +1 -1
- package/dist/src/lib/keyboard-navigation.js.map +1 -1
- package/dist/src/login-button.js +17 -17
- package/dist/src/login-button.js.map +1 -1
- package/dist/src/media-menu.js +21 -21
- package/dist/src/media-menu.js.map +1 -1
- package/dist/src/models.d.ts +0 -1
- package/dist/src/models.js.map +1 -1
- package/dist/src/primary-nav.d.ts +6 -7
- package/dist/src/primary-nav.js +98 -142
- package/dist/src/primary-nav.js.map +1 -1
- package/dist/src/styles/login-button.js +87 -87
- package/dist/src/styles/login-button.js.map +1 -1
- package/dist/src/styles/primary-nav.js +343 -343
- package/dist/src/styles/primary-nav.js.map +1 -1
- package/dist/src/user-menu.js +13 -13
- package/dist/src/user-menu.js.map +1 -1
- package/dist/test/ia-topnav.test.js +15 -87
- package/dist/test/ia-topnav.test.js.map +1 -1
- package/dist/test/primary-nav.test.js +16 -34
- package/dist/test/primary-nav.test.js.map +1 -1
- package/index.ts +3 -4
- package/package.json +1 -1
- package/src/data/menus.ts +652 -652
- package/src/dropdown-menu.ts +132 -132
- package/src/ia-topnav.ts +301 -383
- package/src/lib/keyboard-navigation.ts +166 -166
- package/src/login-button.ts +78 -78
- package/src/media-menu.ts +143 -143
- package/src/models.ts +63 -65
- package/src/primary-nav.ts +277 -324
- package/src/styles/login-button.ts +90 -90
- package/src/styles/primary-nav.ts +346 -346
- package/src/user-menu.ts +32 -32
- package/test/ia-topnav.test.ts +282 -381
- package/test/primary-nav.test.ts +136 -163
package/src/media-menu.ts
CHANGED
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
import { LitElement, PropertyValues, html } from 'lit';
|
|
2
|
-
import { customElement, property, queryAll } from 'lit/decorators.js';
|
|
3
|
-
|
|
4
|
-
import { defaultTopNavConfig } from './data/menus';
|
|
5
|
-
import formatUrl from './lib/format-url';
|
|
6
|
-
import './media-button';
|
|
7
|
-
import { MediaButton } from './media-button';
|
|
8
|
-
import { IATopNavConfig } from './models';
|
|
9
|
-
import mediaMenuCSS from './styles/media-menu';
|
|
10
|
-
|
|
11
|
-
const menuSelection = [
|
|
12
|
-
{
|
|
13
|
-
icon: 'web',
|
|
14
|
-
menu: 'web',
|
|
15
|
-
href: 'https://web.archive.org',
|
|
16
|
-
label: 'Wayback Machine',
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
icon: 'texts',
|
|
20
|
-
menu: 'texts',
|
|
21
|
-
href: '/details/texts',
|
|
22
|
-
label: 'Texts',
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
icon: 'video',
|
|
26
|
-
menu: 'video',
|
|
27
|
-
href: '/details/movies',
|
|
28
|
-
label: 'Video',
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
icon: 'audio',
|
|
32
|
-
menu: 'audio',
|
|
33
|
-
href: '/details/audio',
|
|
34
|
-
label: 'Audio',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
icon: 'software',
|
|
38
|
-
menu: 'software',
|
|
39
|
-
href: '/details/software',
|
|
40
|
-
label: 'Software',
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
icon: 'images',
|
|
44
|
-
menu: 'images',
|
|
45
|
-
href: '/details/image',
|
|
46
|
-
label: 'Images',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
icon: 'donate',
|
|
50
|
-
menu: 'donate',
|
|
51
|
-
href: '/donate/?origin=iawww-mbhmbgrmenu',
|
|
52
|
-
label: 'Donate',
|
|
53
|
-
followable: true,
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
icon: 'ellipses',
|
|
57
|
-
menu: 'more',
|
|
58
|
-
href: '/about/',
|
|
59
|
-
label: 'More',
|
|
60
|
-
},
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
@customElement('media-menu')
|
|
64
|
-
export class MediaMenu extends LitElement {
|
|
65
|
-
@property({ type: String }) baseHost = '';
|
|
66
|
-
@property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
|
|
67
|
-
@property({ type: String }) openMenu = '';
|
|
68
|
-
@property({ type: String }) selectedMenuOption = '';
|
|
69
|
-
@property({ type: Object }) currentTab: { moveTo: string } | undefined;
|
|
70
|
-
|
|
71
|
-
@queryAll('media-button') mediaButtons?: MediaButton[];
|
|
72
|
-
|
|
73
|
-
static get styles() {
|
|
74
|
-
return mediaMenuCSS;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
updated(props: PropertyValues) {
|
|
78
|
-
if (props.has('currentTab')) {
|
|
79
|
-
const mediaButtons = Array.from(this.mediaButtons ?? []);
|
|
80
|
-
|
|
81
|
-
mediaButtons.map((button, index) => {
|
|
82
|
-
const linkItem = button.shadowRoot?.querySelector('a.menu-item');
|
|
83
|
-
if (linkItem) {
|
|
84
|
-
if (linkItem.classList.contains(`${this.selectedMenuOption}`)) {
|
|
85
|
-
linkItem.classList.remove('selected');
|
|
86
|
-
(linkItem as HTMLElement).blur();
|
|
87
|
-
|
|
88
|
-
const newFocusIndex =
|
|
89
|
-
this.currentTab?.moveTo === 'next' ? index + 1 : index - 1;
|
|
90
|
-
(
|
|
91
|
-
mediaButtons[newFocusIndex]?.shadowRoot?.querySelector(
|
|
92
|
-
'a.menu-item',
|
|
93
|
-
) as HTMLElement
|
|
94
|
-
).focus();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
get mediaMenuOptionsTemplate() {
|
|
102
|
-
const buttons = menuSelection.map(
|
|
103
|
-
({ icon, menu, label, href, followable }) => {
|
|
104
|
-
const selected = this.selectedMenuOption === menu;
|
|
105
|
-
return html`
|
|
106
|
-
<media-button
|
|
107
|
-
.config=${this.config}
|
|
108
|
-
.icon=${icon}
|
|
109
|
-
.href=${formatUrl(href as string & Location, this.baseHost)}
|
|
110
|
-
?followable=${followable}
|
|
111
|
-
.label=${label}
|
|
112
|
-
.mediatype=${menu}
|
|
113
|
-
.openMenu=${this.openMenu}
|
|
114
|
-
.selected=${selected}
|
|
115
|
-
.selectedMenuOption=${this.selectedMenuOption}
|
|
116
|
-
data-mediatype="${menu}"
|
|
117
|
-
></media-button>
|
|
118
|
-
`;
|
|
119
|
-
},
|
|
120
|
-
);
|
|
121
|
-
return buttons;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
get menuOpened() {
|
|
125
|
-
return this.openMenu === 'media';
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
get menuClass() {
|
|
129
|
-
return this.menuOpened ? 'open' : 'closed';
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
render() {
|
|
133
|
-
return html`
|
|
134
|
-
<div class="media-menu-container ${this.menuClass}">
|
|
135
|
-
<div class="overflow-clip">
|
|
136
|
-
<nav class="media-menu-inner" aria-expanded="${this.menuOpened}">
|
|
137
|
-
<div class="menu-group">${this.mediaMenuOptionsTemplate}</div>
|
|
138
|
-
</nav>
|
|
139
|
-
</div>
|
|
140
|
-
</div>
|
|
141
|
-
`;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
1
|
+
import { LitElement, PropertyValues, html } from 'lit';
|
|
2
|
+
import { customElement, property, queryAll } from 'lit/decorators.js';
|
|
3
|
+
|
|
4
|
+
import { defaultTopNavConfig } from './data/menus';
|
|
5
|
+
import formatUrl from './lib/format-url';
|
|
6
|
+
import './media-button';
|
|
7
|
+
import { MediaButton } from './media-button';
|
|
8
|
+
import { IATopNavConfig } from './models';
|
|
9
|
+
import mediaMenuCSS from './styles/media-menu';
|
|
10
|
+
|
|
11
|
+
const menuSelection = [
|
|
12
|
+
{
|
|
13
|
+
icon: 'web',
|
|
14
|
+
menu: 'web',
|
|
15
|
+
href: 'https://web.archive.org',
|
|
16
|
+
label: 'Wayback Machine',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
icon: 'texts',
|
|
20
|
+
menu: 'texts',
|
|
21
|
+
href: '/details/texts',
|
|
22
|
+
label: 'Texts',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
icon: 'video',
|
|
26
|
+
menu: 'video',
|
|
27
|
+
href: '/details/movies',
|
|
28
|
+
label: 'Video',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
icon: 'audio',
|
|
32
|
+
menu: 'audio',
|
|
33
|
+
href: '/details/audio',
|
|
34
|
+
label: 'Audio',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
icon: 'software',
|
|
38
|
+
menu: 'software',
|
|
39
|
+
href: '/details/software',
|
|
40
|
+
label: 'Software',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
icon: 'images',
|
|
44
|
+
menu: 'images',
|
|
45
|
+
href: '/details/image',
|
|
46
|
+
label: 'Images',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
icon: 'donate',
|
|
50
|
+
menu: 'donate',
|
|
51
|
+
href: '/donate/?origin=iawww-mbhmbgrmenu',
|
|
52
|
+
label: 'Donate',
|
|
53
|
+
followable: true,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
icon: 'ellipses',
|
|
57
|
+
menu: 'more',
|
|
58
|
+
href: '/about/',
|
|
59
|
+
label: 'More',
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
@customElement('media-menu')
|
|
64
|
+
export class MediaMenu extends LitElement {
|
|
65
|
+
@property({ type: String }) baseHost = '';
|
|
66
|
+
@property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
|
|
67
|
+
@property({ type: String }) openMenu = '';
|
|
68
|
+
@property({ type: String }) selectedMenuOption = '';
|
|
69
|
+
@property({ type: Object }) currentTab: { moveTo: string } | undefined;
|
|
70
|
+
|
|
71
|
+
@queryAll('media-button') mediaButtons?: MediaButton[];
|
|
72
|
+
|
|
73
|
+
static get styles() {
|
|
74
|
+
return mediaMenuCSS;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
updated(props: PropertyValues) {
|
|
78
|
+
if (props.has('currentTab')) {
|
|
79
|
+
const mediaButtons = Array.from(this.mediaButtons ?? []);
|
|
80
|
+
|
|
81
|
+
mediaButtons.map((button, index) => {
|
|
82
|
+
const linkItem = button.shadowRoot?.querySelector('a.menu-item');
|
|
83
|
+
if (linkItem) {
|
|
84
|
+
if (linkItem.classList.contains(`${this.selectedMenuOption}`)) {
|
|
85
|
+
linkItem.classList.remove('selected');
|
|
86
|
+
(linkItem as HTMLElement).blur();
|
|
87
|
+
|
|
88
|
+
const newFocusIndex =
|
|
89
|
+
this.currentTab?.moveTo === 'next' ? index + 1 : index - 1;
|
|
90
|
+
(
|
|
91
|
+
mediaButtons[newFocusIndex]?.shadowRoot?.querySelector(
|
|
92
|
+
'a.menu-item',
|
|
93
|
+
) as HTMLElement
|
|
94
|
+
).focus();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
get mediaMenuOptionsTemplate() {
|
|
102
|
+
const buttons = menuSelection.map(
|
|
103
|
+
({ icon, menu, label, href, followable }) => {
|
|
104
|
+
const selected = this.selectedMenuOption === menu;
|
|
105
|
+
return html`
|
|
106
|
+
<media-button
|
|
107
|
+
.config=${this.config}
|
|
108
|
+
.icon=${icon}
|
|
109
|
+
.href=${formatUrl(href as string & Location, this.baseHost)}
|
|
110
|
+
?followable=${followable}
|
|
111
|
+
.label=${label}
|
|
112
|
+
.mediatype=${menu}
|
|
113
|
+
.openMenu=${this.openMenu}
|
|
114
|
+
.selected=${selected}
|
|
115
|
+
.selectedMenuOption=${this.selectedMenuOption}
|
|
116
|
+
data-mediatype="${menu}"
|
|
117
|
+
></media-button>
|
|
118
|
+
`;
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
return buttons;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
get menuOpened() {
|
|
125
|
+
return this.openMenu === 'media';
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
get menuClass() {
|
|
129
|
+
return this.menuOpened ? 'open' : 'closed';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
render() {
|
|
133
|
+
return html`
|
|
134
|
+
<div class="media-menu-container ${this.menuClass}">
|
|
135
|
+
<div class="overflow-clip">
|
|
136
|
+
<nav class="media-menu-inner" aria-expanded="${this.menuOpened}">
|
|
137
|
+
<div class="menu-group">${this.mediaMenuOptionsTemplate}</div>
|
|
138
|
+
</nav>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
`;
|
|
142
|
+
}
|
|
143
|
+
}
|
package/src/models.ts
CHANGED
|
@@ -1,65 +1,63 @@
|
|
|
1
|
-
export interface IATopNavConfig {
|
|
2
|
-
/**
|
|
3
|
-
* Google Analytics event category
|
|
4
|
-
*/
|
|
5
|
-
eventCategory?: string;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Copy to display for number of pages archived at the top of the Wayback search form
|
|
9
|
-
*
|
|
10
|
-
* ie. "425 billion"
|
|
11
|
-
*/
|
|
12
|
-
waybackPagesArchived?: string;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Array of strings representing the values of options that should be hidden from search options
|
|
16
|
-
*/
|
|
17
|
-
hiddenSearchOptions?: string[];
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Map from dropdown item ids to any callout text that should be applied beside them
|
|
21
|
-
*/
|
|
22
|
-
callouts?: Record<string, string>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface IATopNavLink {
|
|
26
|
-
title: string;
|
|
27
|
-
|
|
28
|
-
url?: string;
|
|
29
|
-
|
|
30
|
-
class?: string;
|
|
31
|
-
|
|
32
|
-
icon?: string;
|
|
33
|
-
|
|
34
|
-
analyticsEvent?: string;
|
|
35
|
-
|
|
36
|
-
external?: boolean;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface IATopNavMediaMenu {
|
|
40
|
-
heading: string;
|
|
41
|
-
iconLinks: IATopNavLink[];
|
|
42
|
-
featuredLinks: IATopNavLink[];
|
|
43
|
-
links: IATopNavLink[];
|
|
44
|
-
mobileAppsLinks: IATopNavLink[];
|
|
45
|
-
browserExtensionsLinks: IATopNavLink[];
|
|
46
|
-
archiveItLinks: IATopNavLink[];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface IATopNavMenuConfig {
|
|
50
|
-
audio: IATopNavMediaMenu;
|
|
51
|
-
images: IATopNavMediaMenu;
|
|
52
|
-
more: IATopNavMediaMenu;
|
|
53
|
-
signedOut: IATopNavLink[];
|
|
54
|
-
software: IATopNavMediaMenu;
|
|
55
|
-
texts: IATopNavMediaMenu;
|
|
56
|
-
user: IATopNavLink[];
|
|
57
|
-
userAdmin: IATopNavLink[];
|
|
58
|
-
userAdminFlags: IATopNavLink[];
|
|
59
|
-
video: IATopNavMediaMenu;
|
|
60
|
-
web: IATopNavMediaMenu;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export type IATopNavSecondIdentitySlotMode = 'allow' | '';
|
|
64
|
-
|
|
65
|
-
export type IATopNavSearchSlotMode = 'custom' | '';
|
|
1
|
+
export interface IATopNavConfig {
|
|
2
|
+
/**
|
|
3
|
+
* Google Analytics event category
|
|
4
|
+
*/
|
|
5
|
+
eventCategory?: string;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Copy to display for number of pages archived at the top of the Wayback search form
|
|
9
|
+
*
|
|
10
|
+
* ie. "425 billion"
|
|
11
|
+
*/
|
|
12
|
+
waybackPagesArchived?: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Array of strings representing the values of options that should be hidden from search options
|
|
16
|
+
*/
|
|
17
|
+
hiddenSearchOptions?: string[];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Map from dropdown item ids to any callout text that should be applied beside them
|
|
21
|
+
*/
|
|
22
|
+
callouts?: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface IATopNavLink {
|
|
26
|
+
title: string;
|
|
27
|
+
|
|
28
|
+
url?: string;
|
|
29
|
+
|
|
30
|
+
class?: string;
|
|
31
|
+
|
|
32
|
+
icon?: string;
|
|
33
|
+
|
|
34
|
+
analyticsEvent?: string;
|
|
35
|
+
|
|
36
|
+
external?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface IATopNavMediaMenu {
|
|
40
|
+
heading: string;
|
|
41
|
+
iconLinks: IATopNavLink[];
|
|
42
|
+
featuredLinks: IATopNavLink[];
|
|
43
|
+
links: IATopNavLink[];
|
|
44
|
+
mobileAppsLinks: IATopNavLink[];
|
|
45
|
+
browserExtensionsLinks: IATopNavLink[];
|
|
46
|
+
archiveItLinks: IATopNavLink[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface IATopNavMenuConfig {
|
|
50
|
+
audio: IATopNavMediaMenu;
|
|
51
|
+
images: IATopNavMediaMenu;
|
|
52
|
+
more: IATopNavMediaMenu;
|
|
53
|
+
signedOut: IATopNavLink[];
|
|
54
|
+
software: IATopNavMediaMenu;
|
|
55
|
+
texts: IATopNavMediaMenu;
|
|
56
|
+
user: IATopNavLink[];
|
|
57
|
+
userAdmin: IATopNavLink[];
|
|
58
|
+
userAdminFlags: IATopNavLink[];
|
|
59
|
+
video: IATopNavMediaMenu;
|
|
60
|
+
web: IATopNavMediaMenu;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type IATopNavSecondIdentitySlotMode = 'allow' | '';
|