@internetarchive/ia-topnav 1.4.1 → 2.0.1-alpha-webdev8396.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 (92) 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/src/data/menus.js +0 -2
  6. package/dist/src/data/menus.js.map +1 -1
  7. package/dist/src/dropdown-menu.d.ts +3 -4
  8. package/dist/src/dropdown-menu.js +6 -13
  9. package/dist/src/dropdown-menu.js.map +1 -1
  10. package/dist/src/ia-topnav.d.ts +10 -10
  11. package/dist/src/ia-topnav.js +39 -67
  12. package/dist/src/ia-topnav.js.map +1 -1
  13. package/dist/src/login-button.d.ts +3 -0
  14. package/dist/src/login-button.js +11 -1
  15. package/dist/src/login-button.js.map +1 -1
  16. package/dist/src/models.d.ts +0 -4
  17. package/dist/src/models.js.map +1 -1
  18. package/dist/src/primary-nav.d.ts +9 -4
  19. package/dist/src/primary-nav.js +34 -36
  20. package/dist/src/primary-nav.js.map +1 -1
  21. package/dist/src/signed-out-dropdown.d.ts +1 -1
  22. package/dist/src/signed-out-dropdown.js +1 -2
  23. package/dist/src/signed-out-dropdown.js.map +1 -1
  24. package/dist/src/styles/dropdown-menu.js +1 -0
  25. package/dist/src/styles/dropdown-menu.js.map +1 -1
  26. package/dist/src/styles/ia-topnav.js +0 -5
  27. package/dist/src/styles/ia-topnav.js.map +1 -1
  28. package/dist/src/styles/primary-nav.js +50 -5
  29. package/dist/src/styles/primary-nav.js.map +1 -1
  30. package/dist/src/user-menu.d.ts +1 -2
  31. package/dist/src/user-menu.js +1 -2
  32. package/dist/src/user-menu.js.map +1 -1
  33. package/dist/test/ia-topnav.test.js +18 -60
  34. package/dist/test/ia-topnav.test.js.map +1 -1
  35. package/dist/test/primary-nav.test.js +31 -2
  36. package/dist/test/primary-nav.test.js.map +1 -1
  37. package/eslint.config.mjs +53 -53
  38. package/package.json +72 -72
  39. package/prettier.config.js +9 -9
  40. package/src/data/menus.ts +0 -2
  41. package/src/dropdown-menu.ts +6 -12
  42. package/src/ia-topnav.ts +44 -78
  43. package/src/login-button.ts +12 -1
  44. package/src/models.ts +0 -5
  45. package/src/primary-nav.ts +38 -34
  46. package/src/signed-out-dropdown.ts +1 -2
  47. package/src/styles/dropdown-menu.ts +1 -0
  48. package/src/styles/ia-topnav.ts +0 -5
  49. package/src/styles/primary-nav.ts +50 -5
  50. package/src/user-menu.ts +3 -4
  51. package/ssl/server.key +28 -28
  52. package/test/ia-topnav.test.ts +20 -81
  53. package/test/primary-nav.test.ts +43 -2
  54. package/tsconfig.json +31 -31
  55. package/web-dev-server.config.mjs +32 -32
  56. package/web-test-runner.config.mjs +41 -41
  57. package/dist/src/lib/location-handler.d.ts +0 -1
  58. package/dist/src/lib/location-handler.js +0 -5
  59. package/dist/src/lib/location-handler.js.map +0 -1
  60. package/dist/src/nav-search.d.ts +0 -19
  61. package/dist/src/nav-search.js +0 -127
  62. package/dist/src/nav-search.js.map +0 -1
  63. package/dist/src/search-menu.d.ts +0 -20
  64. package/dist/src/search-menu.js +0 -162
  65. package/dist/src/search-menu.js.map +0 -1
  66. package/dist/src/styles/nav-search.d.ts +0 -2
  67. package/dist/src/styles/nav-search.js +0 -136
  68. package/dist/src/styles/nav-search.js.map +0 -1
  69. package/dist/src/styles/search-menu.d.ts +0 -2
  70. package/dist/src/styles/search-menu.js +0 -118
  71. package/dist/src/styles/search-menu.js.map +0 -1
  72. package/dist/src/styles/signed-out-dropdown.d.ts +0 -2
  73. package/dist/src/styles/signed-out-dropdown.js +0 -31
  74. package/dist/src/styles/signed-out-dropdown.js.map +0 -1
  75. package/dist/src/styles/user-menu.d.ts +0 -2
  76. package/dist/src/styles/user-menu.js +0 -31
  77. package/dist/src/styles/user-menu.js.map +0 -1
  78. package/dist/test/nav-search.test.d.ts +0 -1
  79. package/dist/test/nav-search.test.js +0 -47
  80. package/dist/test/nav-search.test.js.map +0 -1
  81. package/dist/test/search-menu.test.d.ts +0 -1
  82. package/dist/test/search-menu.test.js +0 -42
  83. package/dist/test/search-menu.test.js.map +0 -1
  84. package/src/lib/location-handler.ts +0 -5
  85. package/src/nav-search.ts +0 -117
  86. package/src/search-menu.ts +0 -156
  87. package/src/styles/nav-search.ts +0 -136
  88. package/src/styles/search-menu.ts +0 -118
  89. package/src/styles/signed-out-dropdown.ts +0 -31
  90. package/src/styles/user-menu.ts +0 -31
  91. package/test/nav-search.test.ts +0 -70
  92. package/test/search-menu.test.ts +0 -58
@@ -3,13 +3,12 @@ import TrackedElement from './tracked-element';
3
3
  import icons from './assets/img/icons';
4
4
  import './assets/img/hamburger';
5
5
  import './login-button';
6
- import './nav-search';
6
+ import type { LoginButton } from './login-button';
7
7
  import './media-menu';
8
8
  import logoWordmarkStacked from './assets/img/wordmark-stacked';
9
9
  import primaryNavCSS from './styles/primary-nav';
10
- import locationHandler from './lib/location-handler';
11
10
  import formatUrl from './lib/format-url';
12
- import { customElement, property } from 'lit/decorators.js';
11
+ import { customElement, property, query } from 'lit/decorators.js';
13
12
  import { IATopNavConfig, IATopNavSecondIdentitySlotMode } from './models';
14
13
  import { defaultTopNavConfig } from './data/menus';
15
14
 
@@ -21,8 +20,6 @@ export class PrimaryNav extends TrackedElement {
21
20
  @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
22
21
  @property({ type: String }) openMenu = '';
23
22
  @property({ type: String }) screenName = '';
24
- @property({ type: String }) searchIn = '';
25
- @property({ type: String }) searchQuery = '';
26
23
  @property({ type: String })
27
24
  secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';
28
25
  @property({ type: String }) selectedMenuOption = '';
@@ -36,10 +33,32 @@ export class PrimaryNav extends TrackedElement {
36
33
  | undefined;
37
34
  signedOutMenuToggled: unknown;
38
35
 
36
+ @query('button.user-menu') private userMenuButton?: HTMLButtonElement;
37
+ @query('login-button') private loginButton?: HTMLElement;
38
+
39
39
  static get styles() {
40
40
  return primaryNavCSS;
41
41
  }
42
42
 
43
+ /** Distance (px) from this element's right edge to the right edge of the account dropdown toggle. */
44
+ getAccountDropdownOffset(): number {
45
+ const hostRect = this.getBoundingClientRect();
46
+
47
+ if (this.userMenuButton) {
48
+ return hostRect.right - this.userMenuButton.getBoundingClientRect().right;
49
+ }
50
+
51
+ if (this.loginButton) {
52
+ const loginRect = this.loginButton.getBoundingClientRect();
53
+ const innerOffset = (
54
+ this.loginButton as LoginButton
55
+ ).getDropdownToggleOffset();
56
+ return hostRect.right - loginRect.right + innerOffset;
57
+ }
58
+
59
+ return 0;
60
+ }
61
+
43
62
  toggleMediaMenu(e: Event) {
44
63
  this.trackClick(e);
45
64
  this.dispatchEvent(
@@ -166,6 +185,19 @@ export class PrimaryNav extends TrackedElement {
166
185
  return this.secondIdentitySlotMode === 'allow';
167
186
  }
168
187
 
188
+ /**
189
+ * The search slot container, rendered between media-menu and
190
+ * right-side-section so it sits left of the Upload button on desktop.
191
+ */
192
+ get searchSlotContainer() {
193
+ if (this.hideSearch) return nothing;
194
+ return html`
195
+ <div class="search-container ${this.searchMenuOpen ? 'open' : ''}">
196
+ <slot name="search"></slot>
197
+ </div>
198
+ `;
199
+ }
200
+
169
201
  get searchMenu() {
170
202
  if (this.hideSearch) return nothing;
171
203
 
@@ -177,38 +209,9 @@ export class PrimaryNav extends TrackedElement {
177
209
  >
178
210
  ${icons.search}
179
211
  </button>
180
- <nav-search
181
- .baseHost=${this.baseHost}
182
- .config=${this.config}
183
- .locationHandler=${locationHandler}
184
- .open=${this.searchMenuOpen}
185
- .openMenu=${this.openMenu}
186
- .searchIn=${this.searchIn}
187
- .searchQuery=${this.searchQuery}
188
- @blur=${this.emitNavSearchBlurEvent}
189
- ></nav-search>
190
212
  `;
191
213
  }
192
214
 
193
- private emitNavSearchBlurEvent(e: FocusEvent) {
194
- const relatedTarget = e.relatedTarget as HTMLElement;
195
- const isUploadButton = relatedTarget?.classList.contains('upload');
196
-
197
- if (isUploadButton) {
198
- (this.shadowRoot?.querySelector('a.upload') as HTMLElement).focus();
199
- }
200
-
201
- this.dispatchEvent(
202
- new CustomEvent('navSearchBlur', {
203
- detail: {
204
- isUploadButton: !!isUploadButton,
205
- },
206
- bubbles: true,
207
- composed: true,
208
- }),
209
- );
210
- }
211
-
212
215
  get mobileDonateHeart() {
213
216
  return html`
214
217
  <a
@@ -286,6 +289,7 @@ export class PrimaryNav extends TrackedElement {
286
289
  .openMenu=${this.openMenu}
287
290
  .currentTab=${this.currentTab}
288
291
  ></media-menu>
292
+ ${this.searchSlotContainer}
289
293
  <div class="right-side-section">
290
294
  ${this.mobileDonateHeart} ${this.userStateTemplate}
291
295
  ${this.uploadButtonTemplate} ${this.searchMenu}
@@ -1,11 +1,10 @@
1
1
  import { customElement } from 'lit/decorators.js';
2
2
  import DropdownMenu from './dropdown-menu';
3
3
  import dropdownMenuCSS from './styles/dropdown-menu';
4
- import signedOutDropdownStyles from './styles/signed-out-dropdown';
5
4
 
6
5
  @customElement('signed-out-dropdown')
7
6
  export class SignedOutDropdown extends DropdownMenu {
8
7
  static get styles() {
9
- return [dropdownMenuCSS, signedOutDropdownStyles];
8
+ return dropdownMenuCSS;
10
9
  }
11
10
  }
@@ -96,6 +96,7 @@ export default css`
96
96
  overflow: visible;
97
97
  top: 0;
98
98
  left: auto;
99
+ right: var(--dropdownMenuRight, 0);
99
100
  z-index: 5;
100
101
  transition: opacity 0.2s ease-in-out;
101
102
  font-size: 1.4rem;
@@ -24,11 +24,6 @@ export default css`
24
24
  --activeButtonBg: var(--grey20);
25
25
  --iconFill: var(--grey60);
26
26
 
27
- --searchActiveBg: var(--grey20);
28
- --searchActiveInputBg: var(--white);
29
- --searchMenuBg: var(--grey20);
30
- --desktopSearchIconFill: var(--grey20);
31
-
32
27
  --mediaMenuBg: var(--grey13);
33
28
  --mediaLabelDesktopColor: var(--grey60);
34
29
  --activeDesktopMenuIcon: var(--grey28);
@@ -123,9 +123,40 @@ export default css`
123
123
  fill: var(--iconFill);
124
124
  }
125
125
 
126
- .search-activated {
127
- position: relative;
126
+ .search-container {
127
+ display: none;
128
+ }
129
+
130
+ .search-container.open {
131
+ display: flex;
132
+ position: absolute;
133
+ top: 0;
134
+ right: 4rem;
135
+ bottom: 0;
136
+ left: 4rem;
128
137
  z-index: 3;
138
+ padding: 0.5rem;
139
+ border-radius: 1rem 1rem 0 0;
140
+ background: var(--primaryNavBg);
141
+ align-items: center;
142
+ animation: fade-in 0.2s forwards;
143
+ }
144
+
145
+ .search-container ::slotted(*) {
146
+ display: block;
147
+ }
148
+
149
+ .search-container slot {
150
+ width: 100%;
151
+ }
152
+
153
+ @keyframes fade-in {
154
+ 0% {
155
+ opacity: 0;
156
+ }
157
+ 100% {
158
+ opacity: 1;
159
+ }
129
160
  }
130
161
 
131
162
  .upload {
@@ -288,9 +319,23 @@ export default css`
288
319
  fill: var(--linkHoverColor);
289
320
  }
290
321
 
291
- nav-search {
292
- float: right;
293
- margin-left: 1rem;
322
+ .search-container,
323
+ .search-container.open {
324
+ display: flex;
325
+ position: static;
326
+ top: auto;
327
+ right: auto;
328
+ bottom: auto;
329
+ left: auto;
330
+ align-items: center;
331
+ padding: 0 0 0 1rem;
332
+ background: transparent;
333
+ border-radius: 0;
334
+ z-index: auto;
335
+ }
336
+
337
+ .search-container slot {
338
+ width: auto;
294
339
  }
295
340
  }
296
341
 
package/src/user-menu.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { CSSResult, html } from 'lit';
1
+ import { html } from 'lit';
2
2
  import DropdownMenu from './dropdown-menu';
3
- import userMenuCSS from './styles/user-menu';
4
3
  import dropdownStyles from './styles/dropdown-menu';
5
4
  import { customElement, property } from 'lit/decorators.js';
6
5
 
@@ -9,8 +8,8 @@ export default class UserMenu extends DropdownMenu {
9
8
  @property({ type: String }) username = '';
10
9
  @property({ type: String }) screenName = '';
11
10
 
12
- static get styles(): CSSResult[] {
13
- return [dropdownStyles, userMenuCSS];
11
+ static get styles() {
12
+ return dropdownStyles;
14
13
  }
15
14
 
16
15
  render() {
package/ssl/server.key CHANGED
@@ -1,28 +1,28 @@
1
- -----BEGIN PRIVATE KEY-----
2
- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDZqbS9hNS38Atc
3
- A7Uszq7EA7RavuHc8AcpbURa6Y7NORs0SmfDD0oLptQ7DX5pSuHyOeDHzQ3UXRCU
4
- DAhAD1XlaYQ6PPdiJPRAe4ACELzgDzepxVz3pdKPcfXd5/mHV3ghUZya2XW5DSF1
5
- CRYUX2j10a+JORJIG4bhvTg4HxTJZZDuaNfBMC6ZSn7d9YLQoAf1MLLJm43Ycj1W
6
- lOnyG4DHxNEqEk260BlbBywJH+SJA6GA0GR2bnzYZaDnZ0wqea0Zamx8ijpdJxBU
7
- xYOqLfzs2KREVkkGOmsFEu82W6G3D4bKsY1UNaWXb/jcl3UkXIJJij6CdbbMQkUJ
8
- c8dow3sVAgMBAAECggEANgLpITAhcuVDhFk9L3m4H1bF/dCpDmCXfl2pXR/guicm
9
- C4M9HUeheaOzvVWbXThiOe/HyfylpmFTmFEmCPNlPrDAyYzQXE/MNmYO/TQ3Eihk
10
- iSG68I764XKHbsG+Byoa2rW8NSaqEjniZ/7Rtkt4qasXMmdxlGgUP9bq6O45g8HV
11
- kHxneFlA2KbrvmWnBi7NTea9+tp61NWiq5n97UgHacQR6KkYIpbxd7uNSnCSdmXt
12
- pcwzO4ZPabJ2/DKRjePhU5OggPh+9AhJ3jsBo99GwYPgSZDh8E3vh2OWOtLBMUH3
13
- rmAYwlRT2aZ5hy5yi+4QD98WoUQtsr+9n757F8V6MQKBgQDzZycdgaKwWd5d34NN
14
- 0TkFtPQPwxxJTCCs3I3q02uWcS3svQzBK0cWb4nISO04TnJ3MnXo83dgGhCMF+uZ
15
- FCXxAA53z8F92iZo+ELlXFDFwNeNYih/afDA42tWZ6TlVsDnZ4zQgRjHS7jEF/JV
16
- 0ZgwGpw5725JQt64dic8wTOcDQKBgQDk7YYACQcWTnmjDhZQ3PZSX4fcTtzPZKZj
17
- fa1GrXEaUH1hSyc9VmY6qJpUmXexpvtr194nXE+O5wbThOHcBjVlo2Qv+vswmUX3
18
- WEcVzTVN4/fODCLCqFcMNIr+BzwZfwpT+p0u8g9FxDy1gGmvkxwIu8DCpnUT12Xj
19
- hm2wO+UxKQKBgFxCSDBF9+2SUtgQJYv0dwGzwiLLWMhro6MCAoT02D3w7nBihBgg
20
- GFTnuDkDc285ROfrZ4gB6MizeHwxgOrIGU2NMO62/+d9LbvyBiE76Z3bZ5i+kQ0i
21
- kc/7I69fn8ASLxJHTLenh0XbbNBfJ0riJCZvn7HSEGKShysyFdNQhAhtAoGAFYVi
22
- 0IQIv4cXFkYPwQBUw7+pVQOw7GpI3heFf5x0goXIk6nuAW0q5R7Oi192CiRphGTh
23
- xI+ABy4ezSmz1exbfreShpQwowv1sOACpsEI3s6skBlB90y+Ci6yVlk1xCvWO7jW
24
- qAAngWaGUoXE6bWJsCR+ZY4ieYAJWw9bJnMrA6kCgYAzV4Xeoh5ofENZM21wKW3W
25
- iCzRibPObv6Vb/j9A9yT57yzI3BdfvsX5zmuSvOJm1DimgGY9nCJUzUEYG0a1Dhh
26
- /rqObPoVIFGesmvwflVYFktmVHk7ycEDVreSTz23cvmraPz1fnpdKeuEs4sRQJV7
27
- iJhLoxX5SJlJc0RXMhgHGQ==
28
- -----END PRIVATE KEY-----
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDZqbS9hNS38Atc
3
+ A7Uszq7EA7RavuHc8AcpbURa6Y7NORs0SmfDD0oLptQ7DX5pSuHyOeDHzQ3UXRCU
4
+ DAhAD1XlaYQ6PPdiJPRAe4ACELzgDzepxVz3pdKPcfXd5/mHV3ghUZya2XW5DSF1
5
+ CRYUX2j10a+JORJIG4bhvTg4HxTJZZDuaNfBMC6ZSn7d9YLQoAf1MLLJm43Ycj1W
6
+ lOnyG4DHxNEqEk260BlbBywJH+SJA6GA0GR2bnzYZaDnZ0wqea0Zamx8ijpdJxBU
7
+ xYOqLfzs2KREVkkGOmsFEu82W6G3D4bKsY1UNaWXb/jcl3UkXIJJij6CdbbMQkUJ
8
+ c8dow3sVAgMBAAECggEANgLpITAhcuVDhFk9L3m4H1bF/dCpDmCXfl2pXR/guicm
9
+ C4M9HUeheaOzvVWbXThiOe/HyfylpmFTmFEmCPNlPrDAyYzQXE/MNmYO/TQ3Eihk
10
+ iSG68I764XKHbsG+Byoa2rW8NSaqEjniZ/7Rtkt4qasXMmdxlGgUP9bq6O45g8HV
11
+ kHxneFlA2KbrvmWnBi7NTea9+tp61NWiq5n97UgHacQR6KkYIpbxd7uNSnCSdmXt
12
+ pcwzO4ZPabJ2/DKRjePhU5OggPh+9AhJ3jsBo99GwYPgSZDh8E3vh2OWOtLBMUH3
13
+ rmAYwlRT2aZ5hy5yi+4QD98WoUQtsr+9n757F8V6MQKBgQDzZycdgaKwWd5d34NN
14
+ 0TkFtPQPwxxJTCCs3I3q02uWcS3svQzBK0cWb4nISO04TnJ3MnXo83dgGhCMF+uZ
15
+ FCXxAA53z8F92iZo+ELlXFDFwNeNYih/afDA42tWZ6TlVsDnZ4zQgRjHS7jEF/JV
16
+ 0ZgwGpw5725JQt64dic8wTOcDQKBgQDk7YYACQcWTnmjDhZQ3PZSX4fcTtzPZKZj
17
+ fa1GrXEaUH1hSyc9VmY6qJpUmXexpvtr194nXE+O5wbThOHcBjVlo2Qv+vswmUX3
18
+ WEcVzTVN4/fODCLCqFcMNIr+BzwZfwpT+p0u8g9FxDy1gGmvkxwIu8DCpnUT12Xj
19
+ hm2wO+UxKQKBgFxCSDBF9+2SUtgQJYv0dwGzwiLLWMhro6MCAoT02D3w7nBihBgg
20
+ GFTnuDkDc285ROfrZ4gB6MizeHwxgOrIGU2NMO62/+d9LbvyBiE76Z3bZ5i+kQ0i
21
+ kc/7I69fn8ASLxJHTLenh0XbbNBfJ0riJCZvn7HSEGKShysyFdNQhAhtAoGAFYVi
22
+ 0IQIv4cXFkYPwQBUw7+pVQOw7GpI3heFf5x0goXIk6nuAW0q5R7Oi192CiRphGTh
23
+ xI+ABy4ezSmz1exbfreShpQwowv1sOACpsEI3s6skBlB90y+Ci6yVlk1xCvWO7jW
24
+ qAAngWaGUoXE6bWJsCR+ZY4ieYAJWw9bJnMrA6kCgYAzV4Xeoh5ofENZM21wKW3W
25
+ iCzRibPObv6Vb/j9A9yT57yzI3BdfvsX5zmuSvOJm1DimgGY9nCJUzUEYG0a1Dhh
26
+ /rqObPoVIFGesmvwflVYFktmVHk7ycEDVreSTz23cvmraPz1fnpdKeuEs4sRQJV7
27
+ iJhLoxX5SJlJc0RXMhgHGQ==
28
+ -----END PRIVATE KEY-----
@@ -9,35 +9,9 @@ import {
9
9
 
10
10
  import '../src/ia-topnav';
11
11
  import { IATopNav } from '../src/ia-topnav';
12
- import { SearchMenu } from '../src/search-menu';
13
12
  import { SignedOutDropdown } from '../src/signed-out-dropdown';
14
13
  import UserMenu from '../src/user-menu';
15
14
 
16
- // const container = (
17
- // {
18
- // username = '',
19
- // screenName = '',
20
- // config = {},
21
- // localLinks = true,
22
- // secondIdentitySlotMode = '',
23
- // }: {
24
- // username?: string;
25
- // screenName?: string;
26
- // config?: IATopNavConfig;
27
- // localLinks: boolean;
28
- // secondIdentitySlotMode?: IATopNavSecondIdentitySlotMode;
29
- // } = {
30
- // localLinks: true,
31
- // },
32
- // ) =>
33
- // html`<ia-topnav
34
- // .screenName=${screenName}
35
- // username=${username}
36
- // ?localLinks=${localLinks}
37
- // .config=${config}
38
- // .secondIdentitySlotMode=${secondIdentitySlotMode}
39
- // ></ia-topnav>`;
40
-
41
15
  const verifyClosed = (instance: IATopNav) => {
42
16
  expect(instance.mediaSliderOpen).to.be.false;
43
17
  expect(instance.selectedMenuOption).to.equal('');
@@ -53,25 +27,6 @@ afterEach(() => {
53
27
  });
54
28
 
55
29
  describe('<ia-topnav>', () => {
56
- it('assigns a value to "search in" from outside event', async () => {
57
- const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
58
- const query = 'atari';
59
- const searchMenu = el.shadowRoot?.querySelector(
60
- 'search-menu',
61
- ) as SearchMenu;
62
-
63
- const inputEvent = new InputEvent('input');
64
- Object.defineProperty(inputEvent, 'target', {
65
- value: { value: query },
66
- writable: false,
67
- });
68
-
69
- searchMenu?.searchInChanged(inputEvent);
70
- await el.updateComplete;
71
-
72
- expect(el.searchIn).to.equal(query);
73
- });
74
-
75
30
  it('dispatches an analyticsClick event when trackClick event fired', async () => {
76
31
  const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
77
32
  const clickEvent = new MouseEvent('click');
@@ -87,22 +42,6 @@ describe('<ia-topnav>', () => {
87
42
  expect(response).to.exist;
88
43
  });
89
44
 
90
- it('dispatches an analyticsSubmit event when trackSubmit event fired', async () => {
91
- const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
92
- const submitEvent = new Event('submit');
93
- const form = el.shadowRoot
94
- ?.querySelector('primary-nav')
95
- ?.shadowRoot?.querySelector('nav-search')
96
- ?.shadowRoot?.querySelector('form');
97
-
98
- form?.addEventListener('submit', (e) => e.preventDefault());
99
- (form?.querySelector('[name=query]') as HTMLInputElement).value = 'atari';
100
- setTimeout(() => form?.dispatchEvent(submitEvent));
101
- const response = await oneEvent(el, 'trackSubmit');
102
-
103
- expect(response).to.exist;
104
- });
105
-
106
45
  it('closes all menus when close-layer clicked', async () => {
107
46
  const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
108
47
 
@@ -190,17 +129,6 @@ describe('<ia-topnav>', () => {
190
129
  expect(el.selectedMenuOption).to.equal('');
191
130
  });
192
131
 
193
- it('toggles search menu tabindex when dropdown open', async () => {
194
- const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
195
-
196
- el.openMenu = 'search';
197
- await el.updateComplete;
198
-
199
- expect(
200
- el.shadowRoot?.querySelector('search-menu')?.getAttribute('tabindex'),
201
- ).to.equal('');
202
- });
203
-
204
132
  it('toggles user menu tabindex when dropdown open', async () => {
205
133
  const el = await fixture<IATopNav>(
206
134
  html` <ia-topnav username="shaneriley" ?localLinks=${false}></ia-topnav>`,
@@ -246,11 +174,6 @@ describe('<ia-topnav>', () => {
246
174
  screenName="shaneriley"
247
175
  ?localLinks=${false}
248
176
  ></ia-topnav>`,
249
- // container({
250
- // username: 'shaneriley',
251
- // screenName: 'shaneriley',
252
- // localLinks: false,
253
- // }),
254
177
  );
255
178
 
256
179
  (
@@ -282,7 +205,6 @@ describe('<ia-topnav>', () => {
282
205
  'primary-nav',
283
206
  'media-slider',
284
207
  'desktop-subnav',
285
- 'search-menu',
286
208
  ];
287
209
  componentSelectors.forEach((selector) => {
288
210
  const component = el.shadowRoot?.querySelector(selector) as unknown as {
@@ -313,6 +235,24 @@ describe('<ia-topnav>', () => {
313
235
  });
314
236
  });
315
237
 
238
+ describe('search slot', () => {
239
+ it('forwards search slot to primary-nav', async () => {
240
+ const el = await fixture<IATopNav>(html`<ia-topnav></ia-topnav>`);
241
+ await el.updateComplete;
242
+
243
+ const primaryNav = el.shadowRoot?.querySelector('primary-nav');
244
+ const slot = primaryNav?.querySelector('slot[name="search"]');
245
+ expect(slot).to.exist;
246
+ });
247
+
248
+ it('does not render search-menu', async () => {
249
+ const el = await fixture<IATopNav>(html`<ia-topnav></ia-topnav>`);
250
+ await el.updateComplete;
251
+
252
+ expect(el.shadowRoot?.querySelector('search-menu')).to.not.exist;
253
+ });
254
+ });
255
+
316
256
  describe('slot pass throughs', () => {
317
257
  describe('slot for <primary-nav>', () => {
318
258
  it('opens a slot with `secondIdentitySlotMode`', async () => {
@@ -327,15 +267,14 @@ describe('<ia-topnav>', () => {
327
267
 
328
268
  const slot = el.shadowRoot
329
269
  ?.querySelector('primary-nav')
330
- ?.querySelector('slot');
270
+ ?.querySelector('slot[name="opt-sec-logo"]');
331
271
  expect(slot).to.exist;
332
- expect(slot?.getAttribute('name')).to.equal('opt-sec-logo');
333
272
 
334
273
  el.secondIdentitySlotMode = '';
335
274
  await elementUpdated(el);
336
275
  const noSlot = el.shadowRoot
337
276
  ?.querySelector('primary-nav')
338
- ?.querySelector('slot');
277
+ ?.querySelector('slot[name="opt-sec-logo"]');
339
278
  expect(noSlot).to.not.exist;
340
279
  });
341
280
  });
@@ -50,7 +50,7 @@ describe('<primary-nav>', () => {
50
50
  expect(el.shadowRoot?.querySelector('login-button')).to.not.be.undefined;
51
51
  });
52
52
 
53
- it('does not render search menu toggle and search form if hideSearch true', async () => {
53
+ it('does not render search trigger or search slot if hideSearch true', async () => {
54
54
  const el = await fixture<PrimaryNav>(
55
55
  component({
56
56
  baseHost: 'archive.org',
@@ -61,7 +61,48 @@ describe('<primary-nav>', () => {
61
61
  );
62
62
 
63
63
  expect(el.shadowRoot?.querySelector('.search-trigger')).to.equal(null);
64
- expect(el.shadowRoot?.querySelector('nav-search')).to.equal(null);
64
+ expect(el.shadowRoot?.querySelector('.search-container')).to.not.exist;
65
+ });
66
+
67
+ it('renders search slot container', async () => {
68
+ const el = await fixture<PrimaryNav>(
69
+ component({
70
+ baseHost: 'archive.org',
71
+ username: 'testuser',
72
+ screenName: 'testuser',
73
+ }),
74
+ );
75
+
76
+ expect(el.shadowRoot?.querySelector('.search-container')).to.exist;
77
+
78
+ const slot = el.shadowRoot?.querySelector<HTMLSlotElement>(
79
+ 'slot[name="search"]',
80
+ );
81
+ expect(slot).to.exist;
82
+ });
83
+
84
+ it('renders search trigger button for mobile toggle', async () => {
85
+ const el = await fixture<PrimaryNav>(
86
+ component({
87
+ baseHost: 'archive.org',
88
+ username: 'testuser',
89
+ screenName: 'testuser',
90
+ }),
91
+ );
92
+
93
+ expect(el.shadowRoot?.querySelector('.search-trigger')).to.exist;
94
+ });
95
+
96
+ it('does not render nav-search', async () => {
97
+ const el = await fixture<PrimaryNav>(
98
+ component({
99
+ baseHost: 'archive.org',
100
+ username: 'testuser',
101
+ screenName: 'testuser',
102
+ }),
103
+ );
104
+
105
+ expect(el.shadowRoot?.querySelector('nav-search')).to.not.exist;
65
106
  });
66
107
 
67
108
  it('opens a slot with `secondIdentitySlotMode`', async () => {
package/tsconfig.json CHANGED
@@ -1,31 +1,31 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es2018",
4
- "module": "esnext",
5
- "moduleResolution": "node",
6
- "noEmitOnError": true,
7
- "lib": ["es2017", "dom"],
8
- "strict": true,
9
- "esModuleInterop": false,
10
- "allowSyntheticDefaultImports": true,
11
- "experimentalDecorators": true,
12
- "importHelpers": true,
13
- "outDir": "dist",
14
- "sourceMap": true,
15
- "inlineSources": true,
16
- "rootDir": "./",
17
- "declaration": true,
18
- "plugins": [
19
- {
20
- "name": "ts-lit-plugin"
21
- }
22
- ],
23
- "paths": {
24
- // workaround for: https://github.com/vitest-dev/vitest/issues/4567
25
- "rollup/parseAst": [
26
- "./node_modules/rollup/dist/parseAst"
27
- ]
28
- }
29
- },
30
- "include": ["**/*.ts"]
31
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2018",
4
+ "module": "esnext",
5
+ "moduleResolution": "node",
6
+ "noEmitOnError": true,
7
+ "lib": ["es2017", "dom"],
8
+ "strict": true,
9
+ "esModuleInterop": false,
10
+ "allowSyntheticDefaultImports": true,
11
+ "experimentalDecorators": true,
12
+ "importHelpers": true,
13
+ "outDir": "dist",
14
+ "sourceMap": true,
15
+ "inlineSources": true,
16
+ "rootDir": "./",
17
+ "declaration": true,
18
+ "plugins": [
19
+ {
20
+ "name": "ts-lit-plugin"
21
+ }
22
+ ],
23
+ "paths": {
24
+ // workaround for: https://github.com/vitest-dev/vitest/issues/4567
25
+ "rollup/parseAst": [
26
+ "./node_modules/rollup/dist/parseAst"
27
+ ]
28
+ }
29
+ },
30
+ "include": ["**/*.ts"]
31
+ }
@@ -1,32 +1,32 @@
1
- // import { hmrPlugin, presets } from '@open-wc/dev-server-hmr';
2
-
3
- /** Use Hot Module replacement by adding --hmr to the start command */
4
- const hmr = process.argv.includes('--hmr');
5
-
6
- export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
7
- nodeResolve: true,
8
- open: '/demo',
9
- watch: !hmr,
10
- sslCert: './ssl/server.crt',
11
- sslKey: './ssl/server.key',
12
- hostname: 'local.archive.org',
13
- http2: true,
14
-
15
- /** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
16
- // esbuildTarget: 'auto'
17
-
18
- /** Set appIndex to enable SPA routing */
19
- // appIndex: 'demo/index.html',
20
-
21
- /** Configure bare import resolve plugin */
22
- // nodeResolve: {
23
- // exportConditions: ['browser', 'development']
24
- // },
25
-
26
- plugins: [
27
- /** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */
28
- // hmr && hmrPlugin({ exclude: ['**/*/node_modules/**/*'], presets: [presets.litElement] }),
29
- ],
30
-
31
- // See documentation for all available options
32
- });
1
+ // import { hmrPlugin, presets } from '@open-wc/dev-server-hmr';
2
+
3
+ /** Use Hot Module replacement by adding --hmr to the start command */
4
+ const hmr = process.argv.includes('--hmr');
5
+
6
+ export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
7
+ nodeResolve: true,
8
+ open: '/demo',
9
+ watch: !hmr,
10
+ sslCert: './ssl/server.crt',
11
+ sslKey: './ssl/server.key',
12
+ hostname: 'local.archive.org',
13
+ http2: true,
14
+
15
+ /** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
16
+ // esbuildTarget: 'auto'
17
+
18
+ /** Set appIndex to enable SPA routing */
19
+ // appIndex: 'demo/index.html',
20
+
21
+ /** Configure bare import resolve plugin */
22
+ // nodeResolve: {
23
+ // exportConditions: ['browser', 'development']
24
+ // },
25
+
26
+ plugins: [
27
+ /** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */
28
+ // hmr && hmrPlugin({ exclude: ['**/*/node_modules/**/*'], presets: [presets.litElement] }),
29
+ ],
30
+
31
+ // See documentation for all available options
32
+ });