@internetarchive/ia-topnav 2.0.0 → 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 (52) hide show
  1. package/dist/src/data/menus.js.map +1 -1
  2. package/dist/src/dropdown-menu.d.ts +3 -4
  3. package/dist/src/dropdown-menu.js +6 -13
  4. package/dist/src/dropdown-menu.js.map +1 -1
  5. package/dist/src/ia-topnav.d.ts +3 -0
  6. package/dist/src/ia-topnav.js +79 -69
  7. package/dist/src/ia-topnav.js.map +1 -1
  8. package/dist/src/login-button.d.ts +3 -0
  9. package/dist/src/login-button.js +28 -18
  10. package/dist/src/login-button.js.map +1 -1
  11. package/dist/src/models.js.map +1 -1
  12. package/dist/src/primary-nav.d.ts +4 -0
  13. package/dist/src/primary-nav.js +109 -90
  14. package/dist/src/primary-nav.js.map +1 -1
  15. package/dist/src/signed-out-dropdown.d.ts +1 -1
  16. package/dist/src/signed-out-dropdown.js +1 -2
  17. package/dist/src/signed-out-dropdown.js.map +1 -1
  18. package/dist/src/styles/dropdown-menu.js +1 -0
  19. package/dist/src/styles/dropdown-menu.js.map +1 -1
  20. package/dist/src/styles/ia-topnav.js +82 -82
  21. package/dist/src/styles/ia-topnav.js.map +1 -1
  22. package/dist/src/styles/primary-nav.js +353 -353
  23. package/dist/src/styles/primary-nav.js.map +1 -1
  24. package/dist/src/user-menu.d.ts +1 -2
  25. package/dist/src/user-menu.js +1 -2
  26. package/dist/src/user-menu.js.map +1 -1
  27. package/dist/test/ia-topnav.test.js +9 -9
  28. package/dist/test/ia-topnav.test.js.map +1 -1
  29. package/dist/test/primary-nav.test.js +7 -7
  30. package/dist/test/primary-nav.test.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/data/menus.ts +650 -650
  33. package/src/dropdown-menu.ts +6 -12
  34. package/src/ia-topnav.ts +332 -318
  35. package/src/login-button.ts +89 -78
  36. package/src/models.ts +58 -58
  37. package/src/primary-nav.ts +300 -277
  38. package/src/signed-out-dropdown.ts +1 -2
  39. package/src/styles/dropdown-menu.ts +1 -0
  40. package/src/styles/ia-topnav.ts +85 -85
  41. package/src/styles/primary-nav.ts +356 -356
  42. package/src/user-menu.ts +3 -4
  43. package/test/ia-topnav.test.ts +282 -282
  44. package/test/primary-nav.test.ts +135 -135
  45. package/dist/src/styles/signed-out-dropdown.d.ts +0 -2
  46. package/dist/src/styles/signed-out-dropdown.js +0 -31
  47. package/dist/src/styles/signed-out-dropdown.js.map +0 -1
  48. package/dist/src/styles/user-menu.d.ts +0 -2
  49. package/dist/src/styles/user-menu.js +0 -31
  50. package/dist/src/styles/user-menu.js.map +0 -1
  51. package/src/styles/signed-out-dropdown.ts +0 -31
  52. package/src/styles/user-menu.ts +0 -31
@@ -1,277 +1,300 @@
1
- import { html, nothing, PropertyValues } from 'lit';
2
- import TrackedElement from './tracked-element';
3
- import icons from './assets/img/icons';
4
- import './assets/img/hamburger';
5
- import './login-button';
6
- import './media-menu';
7
- import logoWordmarkStacked from './assets/img/wordmark-stacked';
8
- import primaryNavCSS from './styles/primary-nav';
9
- import formatUrl from './lib/format-url';
10
- import { customElement, property } from 'lit/decorators.js';
11
- import { IATopNavConfig, IATopNavSecondIdentitySlotMode } from './models';
12
- import { defaultTopNavConfig } from './data/menus';
13
-
14
- @customElement('primary-nav')
15
- export class PrimaryNav extends TrackedElement {
16
- @property({ type: String }) mediaBaseHost = 'https://archive.org';
17
- @property({ type: String }) baseHost = '';
18
- @property({ type: Boolean }) hideSearch = false;
19
- @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
20
- @property({ type: String }) openMenu = '';
21
- @property({ type: String }) screenName = '';
22
- @property({ type: String })
23
- secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';
24
- @property({ type: String }) selectedMenuOption = '';
25
- @property({ type: Boolean }) signedOutMenuOpen = false;
26
- @property({ type: Boolean }) userMenuOpen = false;
27
- @property({ type: Boolean }) mediaMenuAnimate = false;
28
- @property({ type: String }) username = '';
29
- @property({ type: String }) userProfileImagePath = '';
30
- @property({ type: Object }) currentTab:
31
- | { mediatype: string; moveTo: string }
32
- | undefined;
33
- signedOutMenuToggled: unknown;
34
-
35
- static get styles() {
36
- return primaryNavCSS;
37
- }
38
-
39
- toggleMediaMenu(e: Event) {
40
- this.trackClick(e);
41
- this.dispatchEvent(
42
- new CustomEvent('menuToggled', {
43
- detail: {
44
- menuName: 'media',
45
- },
46
- }),
47
- );
48
- }
49
-
50
- toggleSearchMenu(e: Event) {
51
- this.trackClick(e);
52
- this.dispatchEvent(
53
- new CustomEvent('menuToggled', {
54
- detail: {
55
- menuName: 'search',
56
- },
57
- }),
58
- );
59
- }
60
-
61
- toggleUserMenu(e: Event) {
62
- this.trackClick(e);
63
- this.dispatchEvent(
64
- new CustomEvent('menuToggled', {
65
- detail: {
66
- menuName: 'user',
67
- },
68
- }),
69
- );
70
- }
71
-
72
- updated(props: PropertyValues) {
73
- if (props.has('currentTab')) {
74
- // early return
75
- if (!this.currentTab || Object.keys(this.currentTab).length === 0)
76
- return nothing;
77
-
78
- const isUserMenuTab =
79
- this.currentTab && this.currentTab.mediatype === 'usermenu';
80
- if (isUserMenuTab) {
81
- const mediaButtons = Array.from(
82
- this.shadowRoot
83
- ?.querySelector('media-menu')
84
- ?.shadowRoot?.querySelectorAll('media-button') ?? [],
85
- );
86
- const lastMediaButton = mediaButtons.filter((element) => {
87
- return element.shadowRoot
88
- ?.querySelector('a')
89
- ?.classList.contains('images');
90
- });
91
-
92
- let nextElement;
93
- if (this.username) {
94
- nextElement = this.shadowRoot?.querySelector('a.upload');
95
- } else {
96
- nextElement = this.shadowRoot
97
- ?.querySelector('login-button')
98
- ?.shadowRoot?.querySelector('span a');
99
- }
100
-
101
- const menuItemElement =
102
- lastMediaButton[0]?.shadowRoot?.querySelector('a.menu-item');
103
-
104
- const focusElement =
105
- this.currentTab.moveTo === 'next' ? nextElement : menuItemElement;
106
-
107
- if (focusElement) {
108
- (focusElement as HTMLElement).focus();
109
- }
110
- } else if (this.currentTab.moveTo === 'next') {
111
- if (this.shadowRoot?.querySelector('.user-menu')) {
112
- (this.shadowRoot?.querySelector('.user-menu') as HTMLElement).focus();
113
- } else {
114
- (
115
- this.shadowRoot
116
- ?.querySelector('login-button')
117
- ?.shadowRoot?.querySelectorAll('span a')[0] as HTMLElement
118
- )?.focus();
119
- }
120
- }
121
- }
122
- }
123
-
124
- get userIcon() {
125
- const userMenuClass = this.openMenu === 'user' ? 'active' : '';
126
- const userMenuToolTip =
127
- this.openMenu === 'user' ? 'Close user menu' : 'Expand user menu';
128
-
129
- return html`
130
- <button
131
- class="user-menu ${userMenuClass}"
132
- title="${userMenuToolTip}"
133
- @click="${this.toggleUserMenu}"
134
- data-event-click-tracking="${this.config?.eventCategory}|NavUserMenu"
135
- >
136
- <img
137
- src="${this.mediaBaseHost}${this.userProfileImagePath}"
138
- alt="Profile picture for ${this.screenName}"
139
- />
140
- <span class="screen-name" dir="auto">${this.screenName}</span>
141
- </button>
142
- `;
143
- }
144
-
145
- get loginIcon() {
146
- return html`
147
- <login-button
148
- .baseHost=${this.baseHost}
149
- .config=${this.config}
150
- .dropdownOpen=${this.signedOutMenuOpen}
151
- .openMenu=${this.openMenu}
152
- @signedOutMenuToggled=${this.signedOutMenuToggled}
153
- ></login-button>
154
- `;
155
- }
156
-
157
- get searchMenuOpen() {
158
- return this.openMenu === 'search';
159
- }
160
-
161
- get allowSecondaryIcon() {
162
- return this.secondIdentitySlotMode === 'allow';
163
- }
164
-
165
- /**
166
- * The search slot container, rendered between media-menu and
167
- * right-side-section so it sits left of the Upload button on desktop.
168
- */
169
- get searchSlotContainer() {
170
- if (this.hideSearch) return nothing;
171
- return html`
172
- <div class="search-container ${this.searchMenuOpen ? 'open' : ''}">
173
- <slot name="search"></slot>
174
- </div>
175
- `;
176
- }
177
-
178
- get searchMenu() {
179
- if (this.hideSearch) return nothing;
180
-
181
- return html`
182
- <button
183
- class="search-trigger"
184
- @click="${this.toggleSearchMenu}"
185
- data-event-click-tracking="${this.config?.eventCategory}|NavSearchOpen"
186
- >
187
- ${icons.search}
188
- </button>
189
- `;
190
- }
191
-
192
- get mobileDonateHeart() {
193
- return html`
194
- <a
195
- class="mobile-donate-link"
196
- .href=${formatUrl(
197
- '/donate/?origin=iawww-mbhrt' as string & Location,
198
- this.baseHost,
199
- )}
200
- >
201
- ${icons.donateUnpadded}
202
- <span class="sr-only">"Donate to the archive"</span>
203
- </a>
204
- `;
205
- }
206
-
207
- get uploadButtonTemplate() {
208
- return html` <a
209
- .href="${formatUrl('/upload' as string & Location, this.baseHost)}"
210
- class="upload"
211
- @focus=${this.toggleMediaMenu}
212
- >
213
- ${icons.upload}
214
- <span>Upload</span>
215
- </a>`;
216
- }
217
-
218
- get userStateTemplate() {
219
- return html`<div class="user-info">
220
- ${this.username ? this.userIcon : this.loginIcon}
221
- </div>`;
222
- }
223
-
224
- get secondLogoSlot() {
225
- return this.allowSecondaryIcon
226
- ? html`
227
- <slot name="opt-sec-logo"></slot>
228
- <slot name="opt-sec-logo-mobile"></slot>
229
- `
230
- : nothing;
231
- }
232
-
233
- get secondLogoClass() {
234
- return this.allowSecondaryIcon ? 'second-logo' : '';
235
- }
236
-
237
- render() {
238
- // const mediaMenuTabIndex = this.openMenu === 'media' ? '' : '-1';
239
- return html`
240
- <nav class=${this.hideSearch ? 'hide-search' : ''}>
241
- <button
242
- class="hamburger"
243
- @click="${this.toggleMediaMenu}"
244
- data-event-click-tracking="${this.config?.eventCategory}|NavHamburger"
245
- title="Open main menu"
246
- >
247
- <icon-hamburger ?active=${this.openMenu === 'media'}></icon-hamburger>
248
- </button>
249
-
250
- <div class=${`branding ${this.secondLogoClass}`}>
251
- <a
252
- .href=${formatUrl('/' as string & Location, this.baseHost)}
253
- @click=${this.trackClick}
254
- data-event-click-tracking="${this.config?.eventCategory}|NavHome"
255
- title="Go home"
256
- class="link-home"
257
- >${icons.iaLogo}${logoWordmarkStacked}</a
258
- >
259
- ${this.secondLogoSlot}
260
- </div>
261
- <media-menu
262
- .baseHost=${this.baseHost}
263
- .config=${this.config}
264
- ?mediaMenuAnimate=${this.mediaMenuAnimate}
265
- .selectedMenuOption=${this.selectedMenuOption}
266
- .openMenu=${this.openMenu}
267
- .currentTab=${this.currentTab}
268
- ></media-menu>
269
- ${this.searchSlotContainer}
270
- <div class="right-side-section">
271
- ${this.mobileDonateHeart} ${this.userStateTemplate}
272
- ${this.uploadButtonTemplate} ${this.searchMenu}
273
- </div>
274
- </nav>
275
- `;
276
- }
277
- }
1
+ import { html, nothing, PropertyValues } from 'lit';
2
+ import TrackedElement from './tracked-element';
3
+ import icons from './assets/img/icons';
4
+ import './assets/img/hamburger';
5
+ import './login-button';
6
+ import type { LoginButton } from './login-button';
7
+ import './media-menu';
8
+ import logoWordmarkStacked from './assets/img/wordmark-stacked';
9
+ import primaryNavCSS from './styles/primary-nav';
10
+ import formatUrl from './lib/format-url';
11
+ import { customElement, property, query } from 'lit/decorators.js';
12
+ import { IATopNavConfig, IATopNavSecondIdentitySlotMode } from './models';
13
+ import { defaultTopNavConfig } from './data/menus';
14
+
15
+ @customElement('primary-nav')
16
+ export class PrimaryNav extends TrackedElement {
17
+ @property({ type: String }) mediaBaseHost = 'https://archive.org';
18
+ @property({ type: String }) baseHost = '';
19
+ @property({ type: Boolean }) hideSearch = false;
20
+ @property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
21
+ @property({ type: String }) openMenu = '';
22
+ @property({ type: String }) screenName = '';
23
+ @property({ type: String })
24
+ secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';
25
+ @property({ type: String }) selectedMenuOption = '';
26
+ @property({ type: Boolean }) signedOutMenuOpen = false;
27
+ @property({ type: Boolean }) userMenuOpen = false;
28
+ @property({ type: Boolean }) mediaMenuAnimate = false;
29
+ @property({ type: String }) username = '';
30
+ @property({ type: String }) userProfileImagePath = '';
31
+ @property({ type: Object }) currentTab:
32
+ | { mediatype: string; moveTo: string }
33
+ | undefined;
34
+ signedOutMenuToggled: unknown;
35
+
36
+ @query('button.user-menu') private userMenuButton?: HTMLButtonElement;
37
+ @query('login-button') private loginButton?: HTMLElement;
38
+
39
+ static get styles() {
40
+ return primaryNavCSS;
41
+ }
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
+
62
+ toggleMediaMenu(e: Event) {
63
+ this.trackClick(e);
64
+ this.dispatchEvent(
65
+ new CustomEvent('menuToggled', {
66
+ detail: {
67
+ menuName: 'media',
68
+ },
69
+ }),
70
+ );
71
+ }
72
+
73
+ toggleSearchMenu(e: Event) {
74
+ this.trackClick(e);
75
+ this.dispatchEvent(
76
+ new CustomEvent('menuToggled', {
77
+ detail: {
78
+ menuName: 'search',
79
+ },
80
+ }),
81
+ );
82
+ }
83
+
84
+ toggleUserMenu(e: Event) {
85
+ this.trackClick(e);
86
+ this.dispatchEvent(
87
+ new CustomEvent('menuToggled', {
88
+ detail: {
89
+ menuName: 'user',
90
+ },
91
+ }),
92
+ );
93
+ }
94
+
95
+ updated(props: PropertyValues) {
96
+ if (props.has('currentTab')) {
97
+ // early return
98
+ if (!this.currentTab || Object.keys(this.currentTab).length === 0)
99
+ return nothing;
100
+
101
+ const isUserMenuTab =
102
+ this.currentTab && this.currentTab.mediatype === 'usermenu';
103
+ if (isUserMenuTab) {
104
+ const mediaButtons = Array.from(
105
+ this.shadowRoot
106
+ ?.querySelector('media-menu')
107
+ ?.shadowRoot?.querySelectorAll('media-button') ?? [],
108
+ );
109
+ const lastMediaButton = mediaButtons.filter((element) => {
110
+ return element.shadowRoot
111
+ ?.querySelector('a')
112
+ ?.classList.contains('images');
113
+ });
114
+
115
+ let nextElement;
116
+ if (this.username) {
117
+ nextElement = this.shadowRoot?.querySelector('a.upload');
118
+ } else {
119
+ nextElement = this.shadowRoot
120
+ ?.querySelector('login-button')
121
+ ?.shadowRoot?.querySelector('span a');
122
+ }
123
+
124
+ const menuItemElement =
125
+ lastMediaButton[0]?.shadowRoot?.querySelector('a.menu-item');
126
+
127
+ const focusElement =
128
+ this.currentTab.moveTo === 'next' ? nextElement : menuItemElement;
129
+
130
+ if (focusElement) {
131
+ (focusElement as HTMLElement).focus();
132
+ }
133
+ } else if (this.currentTab.moveTo === 'next') {
134
+ if (this.shadowRoot?.querySelector('.user-menu')) {
135
+ (this.shadowRoot?.querySelector('.user-menu') as HTMLElement).focus();
136
+ } else {
137
+ (
138
+ this.shadowRoot
139
+ ?.querySelector('login-button')
140
+ ?.shadowRoot?.querySelectorAll('span a')[0] as HTMLElement
141
+ )?.focus();
142
+ }
143
+ }
144
+ }
145
+ }
146
+
147
+ get userIcon() {
148
+ const userMenuClass = this.openMenu === 'user' ? 'active' : '';
149
+ const userMenuToolTip =
150
+ this.openMenu === 'user' ? 'Close user menu' : 'Expand user menu';
151
+
152
+ return html`
153
+ <button
154
+ class="user-menu ${userMenuClass}"
155
+ title="${userMenuToolTip}"
156
+ @click="${this.toggleUserMenu}"
157
+ data-event-click-tracking="${this.config?.eventCategory}|NavUserMenu"
158
+ >
159
+ <img
160
+ src="${this.mediaBaseHost}${this.userProfileImagePath}"
161
+ alt="Profile picture for ${this.screenName}"
162
+ />
163
+ <span class="screen-name" dir="auto">${this.screenName}</span>
164
+ </button>
165
+ `;
166
+ }
167
+
168
+ get loginIcon() {
169
+ return html`
170
+ <login-button
171
+ .baseHost=${this.baseHost}
172
+ .config=${this.config}
173
+ .dropdownOpen=${this.signedOutMenuOpen}
174
+ .openMenu=${this.openMenu}
175
+ @signedOutMenuToggled=${this.signedOutMenuToggled}
176
+ ></login-button>
177
+ `;
178
+ }
179
+
180
+ get searchMenuOpen() {
181
+ return this.openMenu === 'search';
182
+ }
183
+
184
+ get allowSecondaryIcon() {
185
+ return this.secondIdentitySlotMode === 'allow';
186
+ }
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
+
201
+ get searchMenu() {
202
+ if (this.hideSearch) return nothing;
203
+
204
+ return html`
205
+ <button
206
+ class="search-trigger"
207
+ @click="${this.toggleSearchMenu}"
208
+ data-event-click-tracking="${this.config?.eventCategory}|NavSearchOpen"
209
+ >
210
+ ${icons.search}
211
+ </button>
212
+ `;
213
+ }
214
+
215
+ get mobileDonateHeart() {
216
+ return html`
217
+ <a
218
+ class="mobile-donate-link"
219
+ .href=${formatUrl(
220
+ '/donate/?origin=iawww-mbhrt' as string & Location,
221
+ this.baseHost,
222
+ )}
223
+ >
224
+ ${icons.donateUnpadded}
225
+ <span class="sr-only">"Donate to the archive"</span>
226
+ </a>
227
+ `;
228
+ }
229
+
230
+ get uploadButtonTemplate() {
231
+ return html` <a
232
+ .href="${formatUrl('/upload' as string & Location, this.baseHost)}"
233
+ class="upload"
234
+ @focus=${this.toggleMediaMenu}
235
+ >
236
+ ${icons.upload}
237
+ <span>Upload</span>
238
+ </a>`;
239
+ }
240
+
241
+ get userStateTemplate() {
242
+ return html`<div class="user-info">
243
+ ${this.username ? this.userIcon : this.loginIcon}
244
+ </div>`;
245
+ }
246
+
247
+ get secondLogoSlot() {
248
+ return this.allowSecondaryIcon
249
+ ? html`
250
+ <slot name="opt-sec-logo"></slot>
251
+ <slot name="opt-sec-logo-mobile"></slot>
252
+ `
253
+ : nothing;
254
+ }
255
+
256
+ get secondLogoClass() {
257
+ return this.allowSecondaryIcon ? 'second-logo' : '';
258
+ }
259
+
260
+ render() {
261
+ // const mediaMenuTabIndex = this.openMenu === 'media' ? '' : '-1';
262
+ return html`
263
+ <nav class=${this.hideSearch ? 'hide-search' : ''}>
264
+ <button
265
+ class="hamburger"
266
+ @click="${this.toggleMediaMenu}"
267
+ data-event-click-tracking="${this.config?.eventCategory}|NavHamburger"
268
+ title="Open main menu"
269
+ >
270
+ <icon-hamburger ?active=${this.openMenu === 'media'}></icon-hamburger>
271
+ </button>
272
+
273
+ <div class=${`branding ${this.secondLogoClass}`}>
274
+ <a
275
+ .href=${formatUrl('/' as string & Location, this.baseHost)}
276
+ @click=${this.trackClick}
277
+ data-event-click-tracking="${this.config?.eventCategory}|NavHome"
278
+ title="Go home"
279
+ class="link-home"
280
+ >${icons.iaLogo}${logoWordmarkStacked}</a
281
+ >
282
+ ${this.secondLogoSlot}
283
+ </div>
284
+ <media-menu
285
+ .baseHost=${this.baseHost}
286
+ .config=${this.config}
287
+ ?mediaMenuAnimate=${this.mediaMenuAnimate}
288
+ .selectedMenuOption=${this.selectedMenuOption}
289
+ .openMenu=${this.openMenu}
290
+ .currentTab=${this.currentTab}
291
+ ></media-menu>
292
+ ${this.searchSlotContainer}
293
+ <div class="right-side-section">
294
+ ${this.mobileDonateHeart} ${this.userStateTemplate}
295
+ ${this.uploadButtonTemplate} ${this.searchMenu}
296
+ </div>
297
+ </nav>
298
+ `;
299
+ }
300
+ }
@@ -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;