@internetarchive/ia-topnav 1.4.0 → 1.4.1-alpha-webdev8259.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.prettierignore +1 -1
  2. package/LICENSE +661 -661
  3. package/README.md +147 -147
  4. package/demo/index.html +28 -28
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/src/data/menus.js.map +1 -1
  8. package/dist/src/dropdown-menu.js +26 -26
  9. package/dist/src/dropdown-menu.js.map +1 -1
  10. package/dist/src/ia-topnav.d.ts +4 -1
  11. package/dist/src/ia-topnav.js +96 -81
  12. package/dist/src/ia-topnav.js.map +1 -1
  13. package/dist/src/lib/keyboard-navigation.js.map +1 -1
  14. package/dist/src/login-button.js +17 -17
  15. package/dist/src/login-button.js.map +1 -1
  16. package/dist/src/media-menu.js +21 -21
  17. package/dist/src/media-menu.js.map +1 -1
  18. package/dist/src/models.d.ts +1 -0
  19. package/dist/src/models.js.map +1 -1
  20. package/dist/src/primary-nav.d.ts +3 -1
  21. package/dist/src/primary-nav.js +118 -95
  22. package/dist/src/primary-nav.js.map +1 -1
  23. package/dist/src/styles/login-button.js +87 -87
  24. package/dist/src/styles/login-button.js.map +1 -1
  25. package/dist/src/styles/primary-nav.js +343 -308
  26. package/dist/src/styles/primary-nav.js.map +1 -1
  27. package/dist/src/user-menu.js +13 -13
  28. package/dist/src/user-menu.js.map +1 -1
  29. package/dist/test/ia-topnav.test.js +39 -9
  30. package/dist/test/ia-topnav.test.js.map +1 -1
  31. package/dist/test/primary-nav.test.js +55 -7
  32. package/dist/test/primary-nav.test.js.map +1 -1
  33. package/eslint.config.mjs +53 -53
  34. package/index.ts +4 -3
  35. package/package.json +72 -72
  36. package/prettier.config.js +9 -9
  37. package/src/data/menus.ts +652 -652
  38. package/src/dropdown-menu.ts +132 -132
  39. package/src/ia-topnav.ts +383 -366
  40. package/src/lib/keyboard-navigation.ts +166 -166
  41. package/src/login-button.ts +78 -78
  42. package/src/media-menu.ts +143 -143
  43. package/src/models.ts +65 -63
  44. package/src/primary-nav.ts +324 -296
  45. package/src/styles/login-button.ts +90 -90
  46. package/src/styles/primary-nav.ts +346 -311
  47. package/src/user-menu.ts +32 -32
  48. package/ssl/server.key +28 -28
  49. package/test/ia-topnav.test.ts +381 -343
  50. package/test/primary-nav.test.ts +163 -94
  51. package/tsconfig.json +31 -31
  52. package/web-dev-server.config.mjs +32 -32
  53. package/web-test-runner.config.mjs +41 -41
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,63 +1,65 @@
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' | '';
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' | '';