solid-ui 3.0.6 → 3.1.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 (129) hide show
  1. package/README.md +128 -2
  2. package/dist/acl/access-groups.js +1 -1
  3. package/dist/components/footer/index.d.ts +1 -0
  4. package/dist/components/footer/index.esm.js +24364 -0
  5. package/dist/components/footer/index.esm.js.map +1 -0
  6. package/dist/components/footer/index.esm.min.js +137 -0
  7. package/dist/components/footer/index.esm.min.js.map +1 -0
  8. package/dist/components/footer/index.js +23252 -0
  9. package/dist/components/footer/index.js.map +1 -0
  10. package/dist/components/footer/index.min.js +125 -0
  11. package/dist/components/footer/index.min.js.map +1 -0
  12. package/dist/components/header/index.d.ts +1 -0
  13. package/dist/components/header/index.esm.js +1894 -0
  14. package/dist/components/header/index.esm.js.map +1 -0
  15. package/dist/components/header/index.esm.min.js +1083 -0
  16. package/dist/components/header/index.esm.min.js.map +1 -0
  17. package/dist/components/header/index.js +1855 -0
  18. package/dist/components/header/index.js.map +1 -0
  19. package/dist/components/header/index.min.js +1084 -0
  20. package/dist/components/header/index.min.js.map +1 -0
  21. package/dist/components/loginButton/index.d.ts +1 -0
  22. package/dist/components/loginButton/index.esm.js +719 -0
  23. package/dist/components/loginButton/index.esm.js.map +1 -0
  24. package/dist/components/loginButton/index.esm.min.js +402 -0
  25. package/dist/components/loginButton/index.esm.min.js.map +1 -0
  26. package/dist/components/loginButton/index.js +701 -0
  27. package/dist/components/loginButton/index.js.map +1 -0
  28. package/dist/components/loginButton/index.min.js +402 -0
  29. package/dist/components/loginButton/index.min.js.map +1 -0
  30. package/dist/components/signupButton/index.d.ts +1 -0
  31. package/dist/components/signupButton/index.esm.js +270 -0
  32. package/dist/components/signupButton/index.esm.js.map +1 -0
  33. package/dist/components/signupButton/index.esm.min.js +82 -0
  34. package/dist/components/signupButton/index.esm.min.js.map +1 -0
  35. package/dist/components/signupButton/index.js +264 -0
  36. package/dist/components/signupButton/index.js.map +1 -0
  37. package/dist/components/signupButton/index.min.js +82 -0
  38. package/dist/components/signupButton/index.min.js.map +1 -0
  39. package/dist/footer/index.d.ts.map +1 -1
  40. package/dist/footer/index.js +8 -4
  41. package/dist/footer/index.js.map +1 -1
  42. package/dist/icons/v2/icons-svg/contactIcons.d.ts +3 -0
  43. package/dist/icons/v2/icons-svg/contactIcons.d.ts.map +1 -0
  44. package/dist/icons/v2/icons-svg/contactIcons.js +27 -0
  45. package/dist/icons/v2/icons-svg/contactIcons.js.map +1 -0
  46. package/dist/icons/v2/icons-svg/headerIcons.d.ts +18 -0
  47. package/dist/icons/v2/icons-svg/headerIcons.d.ts.map +1 -0
  48. package/dist/icons/v2/icons-svg/headerIcons.js +245 -0
  49. package/dist/icons/v2/icons-svg/headerIcons.js.map +1 -0
  50. package/dist/icons/v2/icons-svg/pngIcons.d.ts +3 -0
  51. package/dist/icons/v2/icons-svg/pngIcons.d.ts.map +1 -0
  52. package/dist/icons/v2/icons-svg/pngIcons.js +4 -0
  53. package/dist/icons/v2/icons-svg/pngIcons.js.map +1 -0
  54. package/dist/icons/v2/icons-svg/profileIcons.d.ts +23 -0
  55. package/dist/icons/v2/icons-svg/profileIcons.d.ts.map +1 -0
  56. package/dist/icons/v2/icons-svg/profileIcons.js +317 -0
  57. package/dist/icons/v2/icons-svg/profileIcons.js.map +1 -0
  58. package/dist/pad.d.ts.map +1 -1
  59. package/dist/pad.js +13 -13
  60. package/dist/pad.js.map +1 -1
  61. package/dist/solid-ui.esm.js +9560 -12181
  62. package/dist/solid-ui.esm.js.map +1 -1
  63. package/dist/solid-ui.esm.min.js +15 -14
  64. package/dist/solid-ui.esm.min.js.map +1 -1
  65. package/dist/solid-ui.js +12531 -14794
  66. package/dist/solid-ui.js.map +1 -1
  67. package/dist/solid-ui.min.js +23 -22
  68. package/dist/solid-ui.min.js.map +1 -1
  69. package/dist/utils/headerFooterHelpers.d.ts.map +1 -1
  70. package/dist/utils/headerFooterHelpers.js +11 -2
  71. package/dist/utils/headerFooterHelpers.js.map +1 -1
  72. package/dist/v2/components/footer/Footer.d.ts +60 -0
  73. package/dist/v2/components/footer/Footer.d.ts.map +1 -0
  74. package/dist/v2/components/footer/Footer.js +148 -0
  75. package/dist/v2/components/footer/Footer.js.map +1 -0
  76. package/dist/v2/components/footer/Footer.test.d.ts +2 -0
  77. package/dist/v2/components/footer/Footer.test.d.ts.map +1 -0
  78. package/dist/v2/components/footer/Footer.test.js +53 -0
  79. package/dist/v2/components/footer/Footer.test.js.map +1 -0
  80. package/dist/v2/components/footer/index.d.ts +3 -0
  81. package/dist/v2/components/footer/index.d.ts.map +1 -0
  82. package/dist/v2/components/footer/index.js +7 -0
  83. package/dist/v2/components/footer/index.js.map +1 -0
  84. package/dist/v2/components/header/Header.d.ts +155 -0
  85. package/dist/v2/components/header/Header.d.ts.map +1 -0
  86. package/dist/v2/components/header/Header.js +845 -0
  87. package/dist/v2/components/header/Header.js.map +1 -0
  88. package/dist/v2/components/header/header.test.d.ts +2 -0
  89. package/dist/v2/components/header/header.test.d.ts.map +1 -0
  90. package/dist/v2/components/header/header.test.js +242 -0
  91. package/dist/v2/components/header/header.test.js.map +1 -0
  92. package/dist/v2/components/header/index.d.ts +4 -0
  93. package/dist/v2/components/header/index.d.ts.map +1 -0
  94. package/dist/v2/components/header/index.js +7 -0
  95. package/dist/v2/components/header/index.js.map +1 -0
  96. package/dist/v2/components/loginButton/LoginButton.d.ts +62 -0
  97. package/dist/v2/components/loginButton/LoginButton.d.ts.map +1 -0
  98. package/dist/v2/components/loginButton/LoginButton.js +497 -0
  99. package/dist/v2/components/loginButton/LoginButton.js.map +1 -0
  100. package/dist/v2/components/loginButton/LoginButton.test.d.ts +2 -0
  101. package/dist/v2/components/loginButton/LoginButton.test.d.ts.map +1 -0
  102. package/dist/v2/components/loginButton/LoginButton.test.js +53 -0
  103. package/dist/v2/components/loginButton/LoginButton.test.js.map +1 -0
  104. package/dist/v2/components/loginButton/downArrow.d.ts +2 -0
  105. package/dist/v2/components/loginButton/downArrow.d.ts.map +1 -0
  106. package/dist/v2/components/loginButton/downArrow.js +10 -0
  107. package/dist/v2/components/loginButton/downArrow.js.map +1 -0
  108. package/dist/v2/components/loginButton/index.d.ts +3 -0
  109. package/dist/v2/components/loginButton/index.d.ts.map +1 -0
  110. package/dist/v2/components/loginButton/index.js +7 -0
  111. package/dist/v2/components/loginButton/index.js.map +1 -0
  112. package/dist/v2/components/signupButton/SignupButton.d.ts +36 -0
  113. package/dist/v2/components/signupButton/SignupButton.d.ts.map +1 -0
  114. package/dist/v2/components/signupButton/SignupButton.js +84 -0
  115. package/dist/v2/components/signupButton/SignupButton.js.map +1 -0
  116. package/dist/v2/components/signupButton/SignupButton.test.d.ts +2 -0
  117. package/dist/v2/components/signupButton/SignupButton.test.d.ts.map +1 -0
  118. package/dist/v2/components/signupButton/SignupButton.test.js +49 -0
  119. package/dist/v2/components/signupButton/SignupButton.test.js.map +1 -0
  120. package/dist/v2/components/signupButton/index.d.ts +3 -0
  121. package/dist/v2/components/signupButton/index.d.ts.map +1 -0
  122. package/dist/v2/components/signupButton/index.js +7 -0
  123. package/dist/v2/components/signupButton/index.js.map +1 -0
  124. package/dist/versionInfo.js +7 -7
  125. package/dist/widgets/buttons.d.ts +9 -3
  126. package/dist/widgets/buttons.d.ts.map +1 -1
  127. package/dist/widgets/buttons.js +68 -7
  128. package/dist/widgets/buttons.js.map +1 -1
  129. package/package.json +34 -7
@@ -0,0 +1,845 @@
1
+ import { LitElement, html, css } from 'lit';
2
+ import { icons } from '../../../iconBase';
3
+ import { authSession } from 'solid-logic';
4
+ import '../loginButton/index';
5
+ import '../signupButton/index';
6
+ import { ifDefined } from 'lit/directives/if-defined.js';
7
+ const DEFAULT_HELP_MENU_ICON = '';
8
+ const DEFAULT_SOLID_ICON_URL = 'https://solidproject.org/assets/img/solid-emblem.svg';
9
+ const DEFAULT_SIGNUP_URL = 'https://solidproject.org/get_a_pod';
10
+ const DEFAULT_LOGGEDIN_MENU_BUTTON_AVATAR = icons.iconBase + 'emptyProfileAvatar.png';
11
+ export class Header extends LitElement {
12
+ constructor() {
13
+ super();
14
+ this.handleDocumentClick = (event) => {
15
+ if (!event.composedPath().includes(this)) {
16
+ this.accountMenuOpen = false;
17
+ this.helpMenuOpen = false;
18
+ }
19
+ };
20
+ this.handleWindowKeydown = (event) => {
21
+ if (event.key === 'Escape' && (this.accountMenuOpen || this.helpMenuOpen)) {
22
+ this.accountMenuOpen = false;
23
+ this.helpMenuOpen = false;
24
+ }
25
+ };
26
+ this.logo = DEFAULT_SOLID_ICON_URL;
27
+ this.helpIcon = DEFAULT_HELP_MENU_ICON;
28
+ this.layout = 'desktop';
29
+ this.theme = 'light';
30
+ this.brandLink = '#';
31
+ this.authState = 'logged-out';
32
+ this.loginAction = { label: 'Log In', action: 'login' };
33
+ this.signUpAction = { label: 'Sign Up', action: 'sign-up', url: DEFAULT_SIGNUP_URL };
34
+ this.accountMenu = [];
35
+ this.logoutLabel = 'Log Out';
36
+ this.logoutIcon = '';
37
+ this.accountIcon = '▼';
38
+ this.accountAvatar = '';
39
+ this.accountAvatarFallback = '';
40
+ this.loginIcon = '';
41
+ this.signUpIcon = '';
42
+ this.helpMenuList = [];
43
+ this.accountMenuOpen = false;
44
+ this.helpMenuOpen = false;
45
+ this.hasSlottedAccountMenu = false;
46
+ this.hasSlottedHelpMenu = false;
47
+ }
48
+ connectedCallback() {
49
+ super.connectedCallback();
50
+ document.addEventListener('click', this.handleDocumentClick);
51
+ window.addEventListener('keydown', this.handleWindowKeydown);
52
+ }
53
+ disconnectedCallback() {
54
+ document.removeEventListener('click', this.handleDocumentClick);
55
+ window.removeEventListener('keydown', this.handleWindowKeydown);
56
+ super.disconnectedCallback();
57
+ }
58
+ handleHelpMenuClick(item, event) {
59
+ event.preventDefault();
60
+ this.helpMenuOpen = false;
61
+ this.dispatchEvent(new CustomEvent('help-menu-select', {
62
+ detail: item,
63
+ bubbles: true,
64
+ composed: true
65
+ }));
66
+ if (item.url) {
67
+ const target = item.target || '_blank';
68
+ const features = target === '_blank' ? 'noopener,noreferrer' : undefined;
69
+ window.open(item.url, target, features);
70
+ }
71
+ }
72
+ handleAccountMenuClick(item) {
73
+ this.accountMenuOpen = false;
74
+ this.dispatchEvent(new CustomEvent('account-menu-select', {
75
+ detail: item,
76
+ bubbles: true,
77
+ composed: true
78
+ }));
79
+ }
80
+ handleAccountSlotChange(event) {
81
+ const slot = event.target;
82
+ this.hasSlottedAccountMenu = slot.assignedElements({ flatten: true }).length > 0;
83
+ }
84
+ handleHelpSlotChange(event) {
85
+ const slot = event.target;
86
+ this.hasSlottedHelpMenu = slot.assignedElements({ flatten: true }).length > 0;
87
+ }
88
+ toggleAccountMenu(event) {
89
+ event.preventDefault();
90
+ if (!this.hasAccountMenuItems())
91
+ return;
92
+ this.helpMenuOpen = false;
93
+ this.accountMenuOpen = !this.accountMenuOpen;
94
+ }
95
+ toggleHelpMenu(event) {
96
+ event.preventDefault();
97
+ if (!this.hasHelpMenuItems())
98
+ return;
99
+ this.accountMenuOpen = false;
100
+ this.helpMenuOpen = !this.helpMenuOpen;
101
+ }
102
+ hasAccountMenuItems() {
103
+ var _a;
104
+ return Boolean(((_a = this.accountMenu) === null || _a === void 0 ? void 0 : _a.length) || this.hasSlottedAccountMenu || this.logoutLabel);
105
+ }
106
+ hasHelpMenuItems() {
107
+ var _a;
108
+ return Boolean(((_a = this.helpMenuList) === null || _a === void 0 ? void 0 : _a.length) || this.hasSlottedHelpMenu);
109
+ }
110
+ shouldRenderHelpMenu() {
111
+ return this.layout !== 'mobile' && this.hasHelpMenuItems();
112
+ }
113
+ renderLoggedInAvatar(avatar, wrapperClass = 'account-avatar') {
114
+ const hasAvatar = Boolean(avatar);
115
+ const imageSrc = hasAvatar ? avatar : this.accountAvatarFallback || DEFAULT_LOGGEDIN_MENU_BUTTON_AVATAR;
116
+ const imageAlt = hasAvatar ? 'Profile Avatar' : 'Default Avatar';
117
+ if (this.layout === 'mobile' && wrapperClass === 'account-avatar') {
118
+ return html `<img class="account-avatar-img" src="${imageSrc}" alt="${imageAlt}" />`;
119
+ }
120
+ return html `
121
+ <span class="${wrapperClass}" aria-hidden="true">
122
+ <img src="${imageSrc}" alt="${imageAlt}" />
123
+ </span>
124
+ `;
125
+ }
126
+ renderLoggedOutActions() {
127
+ return html `
128
+ <div class="auth-actions" part="auth-actions">
129
+ <slot name="login-action">
130
+ <solid-ui-login-button
131
+ label="${this.loginAction.label}"
132
+ icon=${ifDefined(this.layout !== 'mobile' ? (this.loginIcon || this.loginAction.icon) : undefined)}
133
+ layout="${this.layout}"
134
+ theme="${this.theme}"
135
+ part="login-action"
136
+ @login-success="${() => this.handleLoginSuccess()}"
137
+ ></solid-ui-login-button>
138
+ </slot>
139
+ <slot name="sign-up-action">
140
+ <solid-ui-signup-button
141
+ label="${this.signUpAction.label}"
142
+ signup-url="${ifDefined(this.signUpAction.url)}"
143
+ layout="${this.layout}"
144
+ .icon=${ifDefined(this.layout !== 'mobile' ? (this.signUpIcon || this.signUpAction.icon) : undefined)}
145
+ theme="${this.theme}"
146
+ part="sign-up-action"
147
+ ></solid-ui-signup-button>
148
+ </slot>
149
+ </div>
150
+ `;
151
+ }
152
+ handleLoginSuccess() {
153
+ this.authState = 'logged-in';
154
+ this.dispatchEvent(new CustomEvent('auth-action-select', {
155
+ detail: { role: 'login' },
156
+ bubbles: true,
157
+ composed: true
158
+ }));
159
+ }
160
+ async handleLogout() {
161
+ this.accountMenuOpen = false;
162
+ try {
163
+ await authSession.logout();
164
+ }
165
+ catch (_err) {
166
+ // logout errors are non-fatal — proceed to clear state
167
+ }
168
+ this.authState = 'logged-out';
169
+ this.dispatchEvent(new CustomEvent('logout-select', {
170
+ detail: { role: 'logout' },
171
+ bubbles: true,
172
+ composed: true
173
+ }));
174
+ }
175
+ renderAccountMenuItem(item) {
176
+ const content = html `
177
+ ${this.renderLoggedInAvatar(item.avatar, 'account-menu-avatar')}
178
+ <span class="account-menu-copy">
179
+ <span class="account-menu-label">${item.label}</span>
180
+ ${item.webid && this.layout !== 'mobile' ? html `<span class="account-menu-webid">${item.webid}</span>` : ''}
181
+ </span>
182
+ `;
183
+ if (item.url) {
184
+ return html `
185
+ <a
186
+ class="account-menu-item-link"
187
+ href="${item.url}"
188
+ @click="${() => this.handleAccountMenuClick(item)}"
189
+ part="account-menu-item"
190
+ role="menuitem"
191
+ >
192
+ ${content}
193
+ </a>
194
+ `;
195
+ }
196
+ return html `
197
+ <button
198
+ class="account-menu-item-button"
199
+ type="button"
200
+ @click="${() => this.handleAccountMenuClick(item)}"
201
+ part="account-menu-item"
202
+ role="menuitem"
203
+ >
204
+ ${content}
205
+ </button>
206
+ `;
207
+ }
208
+ renderLoggedInActions() {
209
+ return html `
210
+ <div class="account-menu-container" part="account-menu-container">
211
+ <slot name="account-trigger">
212
+ <button
213
+ id="accountMenuTrigger"
214
+ class="account-menu-trigger"
215
+ type="button"
216
+ aria-haspopup="menu"
217
+ aria-expanded="${this.accountMenuOpen ? 'true' : 'false'}"
218
+ ?disabled="${!this.hasAccountMenuItems()}"
219
+ @click="${(e) => this.toggleAccountMenu(e)}"
220
+ part="account-menu-trigger"
221
+ >
222
+ ${this.renderLoggedInAvatar(this.accountAvatar)}
223
+ ${this.layout !== 'mobile' && this.accountIcon
224
+ ? html `
225
+ <img class="account-menu-trigger-icon" src="${this.accountIcon}" alt="" aria-hidden="true" />`
226
+ : ''}
227
+ </button>
228
+ </slot>
229
+
230
+ <nav
231
+ id="accountMenu"
232
+ class="account-dropdown"
233
+ role="menu"
234
+ ?inert="${!this.accountMenuOpen || !this.hasAccountMenuItems()}"
235
+ ?hidden="${!this.accountMenuOpen || !this.hasAccountMenuItems()}"
236
+ part="account-dropdown"
237
+ >
238
+ <slot name="account-switch" class="account-switch">Switch account</slot>
239
+ <hr class="dropdown-menu-separator" />
240
+ <slot name="account-menu" @slotchange="${(e) => this.handleAccountSlotChange(e)}"></slot>
241
+ ${this.accountMenu && this.accountMenu.length
242
+ ? html `
243
+ <ul class="account-menu-list">
244
+ ${this.accountMenu.map((item) => html `
245
+ <li>${this.renderAccountMenuItem(item)}</li>
246
+ `)}
247
+ </ul>
248
+ `
249
+ : ''}
250
+ ${this.logoutLabel
251
+ ? html `
252
+ <hr class="dropdown-menu-separator" />
253
+ <button
254
+ class="account-menu-item-button"
255
+ type="button"
256
+ @click="${() => this.handleLogout()}"
257
+ part="logout-action"
258
+ role="menuitem"
259
+ >
260
+ ${this.logoutIcon && this.layout !== 'mobile'
261
+ ? html `<img class="logout-action-icon" src="${this.logoutIcon}" alt="" aria-hidden="true" part="logout-action-icon" />`
262
+ : ''}
263
+ ${this.logoutLabel}
264
+ </button>
265
+ `
266
+ : ''}
267
+ </nav>
268
+ </div>
269
+ `;
270
+ }
271
+ renderUserArea() {
272
+ if (this.authState === 'logged-out') {
273
+ return this.renderLoggedOutActions();
274
+ }
275
+ return this.renderLoggedInActions();
276
+ }
277
+ firstUpdated() {
278
+ var _a;
279
+ const brandLink = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.getElementById('brandLink');
280
+ if (brandLink) {
281
+ brandLink.classList.toggle('brand-not-displayed', this.layout === 'mobile');
282
+ }
283
+ }
284
+ updated(changedProperties) {
285
+ var _a;
286
+ if (changedProperties.has('layout')) {
287
+ const brandLink = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.getElementById('brandLink');
288
+ if (brandLink) {
289
+ brandLink.classList.toggle('brand-not-displayed', this.layout === 'mobile');
290
+ }
291
+ }
292
+ }
293
+ render() {
294
+ return html `
295
+ <div class="headerInner">
296
+ <slot name="navigation-toggle"></slot>
297
+ <a
298
+ id="brandLink"
299
+ class="brand"
300
+ href="${this.brandLink}"
301
+ part="brand"
302
+ >
303
+ <img id="brandImg" src="${this.logo}" alt="Logo" part="logo" />
304
+ </a>
305
+
306
+ <div class="menu" part="menu">
307
+ ${this.renderUserArea()}
308
+
309
+ ${this.shouldRenderHelpMenu()
310
+ ? html `
311
+ <div class="header-menu-separator" />`
312
+ : ''}
313
+
314
+ ${this.shouldRenderHelpMenu()
315
+ ? html `
316
+ <div class="help-menu-container" part="help-menu-container">
317
+ <button
318
+ id="helpMenuTrigger"
319
+ class="help-menu-trigger"
320
+ type="button"
321
+ aria-haspopup="menu"
322
+ aria-expanded="${this.helpMenuOpen ? 'true' : 'false'}"
323
+ ?disabled="${!this.hasHelpMenuItems()}"
324
+ @click="${(e) => this.toggleHelpMenu(e)}"
325
+ part="help-menu-trigger"
326
+ >
327
+ ${this.helpIcon
328
+ ? html `<img id="helpIcon" class="help-icon" src="${this.helpIcon}" alt="Help" part="help-icon" />`
329
+ : html `<span class="help-text" part="help-text">Help</span>`}
330
+ </button>
331
+
332
+ <nav
333
+ id="helpMenu"
334
+ class="help-dropdown"
335
+ role="menu"
336
+ ?inert="${!this.helpMenuOpen || !this.hasHelpMenuItems()}"
337
+ ?hidden="${!this.helpMenuOpen || !this.hasHelpMenuItems()}"
338
+ part="help-dropdown"
339
+ >
340
+ <div class="help-dropdown-content" @click="${() => { this.helpMenuOpen = false; }}">
341
+ <slot name="help-menu" @slotchange="${(e) => this.handleHelpSlotChange(e)}"></slot>
342
+ ${this.helpMenuList && this.helpMenuList.length
343
+ ? html `
344
+ <ul class="help-menu-list">
345
+ ${this.helpMenuList.map((item) => html `
346
+ <li>
347
+ ${item.url
348
+ ? html `
349
+ <a
350
+ href="${item.url}"
351
+ target="${item.target || '_blank'}"
352
+ rel="${ifDefined((item.target || '_blank') === '_blank' ? 'noopener noreferrer' : undefined)}"
353
+ @click="${(e) => this.handleHelpMenuClick(item, e)}"
354
+ part="help-menu-item"
355
+ role="menuitem"
356
+ >
357
+ ${item.label}
358
+ </a>
359
+ `
360
+ : html `
361
+ <button
362
+ type="button"
363
+ @click="${(e) => this.handleHelpMenuClick(item, e)}"
364
+ part="help-menu-item"
365
+ role="menuitem"
366
+ >
367
+ ${item.label}
368
+ </button>
369
+ `}
370
+ </li>
371
+ `)}
372
+ </ul>
373
+ `
374
+ : ''}
375
+ </div>
376
+ </nav>
377
+ </div>`
378
+ : ''}
379
+ </div>
380
+ </div>
381
+ `;
382
+ }
383
+ }
384
+ Header.properties = {
385
+ logo: { type: String, reflect: true },
386
+ helpIcon: { type: String, attribute: 'help-icon', reflect: true },
387
+ layout: { type: String, reflect: true },
388
+ theme: { type: String, reflect: true },
389
+ brandLink: { type: String, attribute: 'brand-link', reflect: true },
390
+ authState: { type: String, attribute: 'auth-state', reflect: true },
391
+ loginAction: { type: Object, attribute: false },
392
+ signUpAction: { type: Object, attribute: false },
393
+ accountMenu: { type: Array, attribute: false },
394
+ logoutLabel: { type: String, attribute: 'logout-label', reflect: true },
395
+ logoutIcon: { type: String, attribute: 'logout-icon', reflect: true },
396
+ accountIcon: { type: String, attribute: 'account-icon', reflect: true },
397
+ accountAvatar: { type: String, attribute: 'account-avatar', reflect: true },
398
+ accountAvatarFallback: { type: String, attribute: 'account-avatar-fallback', reflect: true },
399
+ loginIcon: { type: String, attribute: 'login-icon', reflect: true },
400
+ signUpIcon: { type: String, attribute: 'sign-up-icon', reflect: true },
401
+ helpMenuList: { type: Array },
402
+ accountMenuOpen: { state: true },
403
+ helpMenuOpen: { state: true },
404
+ hasSlottedAccountMenu: { state: true },
405
+ hasSlottedHelpMenu: { state: true }
406
+ };
407
+ Header.styles = css `
408
+ :host { // default theme
409
+ display: block;
410
+ --header-bg: var(--color-header-row-bg, #332746);
411
+ --header-text: var(--color-header-text, #ffffff);
412
+ --header-border: var(--color-border, #efecf3);
413
+ --header-line: var(--color-header-menu-separator-line, #5e546d);
414
+ --header-link: var(--color-text-heading, #000000);
415
+ --header-menu-item-hover: var(--color-header-menu-item-hover, #e6dcff);
416
+ --header-menu-item-selected: var(--color-header-menu-item-selected, #cbb9ff);
417
+ --header-menu-bg: var(--color-menu-bg, #f6f5f9);
418
+ --header-menu-loggedin-bg: var(--color-header-menu-loggedin-bg, #5e546d);
419
+ --header-menu-text: var(--color-menu-item-text, #654d6c);
420
+ --header-border-radius: var(--border-radius-sm, 0.2rem);
421
+ --header-button-bg: var(--color-menu-bg, #ffffff);
422
+ --header-button-text: var(--color-header-button-text, #0F172B);
423
+ --header-button-detail-text: var(--color-header-button-detail-text, #99A1AF);
424
+ --header-shadow: var(--color-header-shadow, 2px 6px 10px 0 rgba(0, 0, 0, 0.4), 2px 8px 24px 0 rgba(0, 0, 0, 0.19));
425
+ font-family: var(--font-family-base, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif);
426
+ }
427
+
428
+ // for now light and dark are the same
429
+ :host([theme='dark']) {
430
+ display: block;
431
+ --header-bg: var(--color-header-row-bg, #332746);
432
+ --header-text: var(--color-header-text, #ffffff);
433
+ --header-border: var(--color-border, #efecf3);
434
+ --header-line: var(--color-header-menu-separator-line, #5e546d);
435
+ --header-link: var(--color-text-heading, #000000);
436
+ --header-menu-item-hover: var(--color-header-menu-item-hover, #e6dcff);
437
+ --header-menu-item-selected: var(--color-header-menu-item-selected, #cbb9ff);
438
+ --header-menu-bg: var(--color-menu-bg, #f6f5f9);
439
+ --header-menu-loggedin-bg: var(--color-header-menu-loggedin-bg, #5e546d);
440
+ --header-menu-text: var(--color-menu-item-text, #654d6c);
441
+ --header-border-radius: var(--border-radius-sm, 0.2rem);
442
+ --header-button-bg: var(--color-menu-bg, #ffffff);
443
+ --header-button-text: var(--color-header-button-text, #0f172a);
444
+ --header-button-detail-text: var(--color-header-button-detail-text, #878192);
445
+ --header-icon-filter: invert(1) brightness(1.3); /* special way to invert SVG color of icons, from white to black */
446
+ --header-shadow: var(--color-header-shadow, 2px 6px 10px 0 rgba(0, 0, 0, 0.4), 2px 8px 24px 0 rgba(0, 0, 0, 0.19));
447
+ font-family: var(--font-family-base, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif);
448
+ }
449
+
450
+ :host([layout='mobile']) .headerInner {
451
+ flex-wrap: wrap;
452
+ text-align: center;
453
+ gap: 0.5rem;
454
+ }
455
+
456
+ .headerInner {
457
+ display: flex;
458
+ align-items: center;
459
+ justify-content: space-between;
460
+ background: var(--header-bg);
461
+ color: var(--header-text);
462
+ padding: 0 1.5rem;
463
+ height: 3.75rem;
464
+ }
465
+
466
+ ::slotted([slot='navigation-toggle']) {
467
+ display: inline-flex;
468
+ align-items: center;
469
+ justify-content: center;
470
+ flex-shrink: 0;
471
+ margin-right: 0.75rem;
472
+ }
473
+
474
+ :host([layout='desktop']) ::slotted([slot='navigation-toggle']) {
475
+ display: none !important;
476
+ }
477
+
478
+ .brand {
479
+ display: flex;
480
+ align-items: center;
481
+ gap: 0.5rem;
482
+ text-decoration: none;
483
+ color: inherit;
484
+ }
485
+
486
+ .brand-not-displayed {
487
+ display: none;
488
+ }
489
+
490
+ .brand img {
491
+ height: 50px;
492
+ width: 55px;
493
+ object-fit: contain;
494
+ }
495
+
496
+ .menu {
497
+ display: flex;
498
+ align-items: center;
499
+ gap: 0.625rem;
500
+ margin-left: auto;
501
+ }
502
+
503
+ .auth-actions {
504
+ display: flex;
505
+ align-items: center;
506
+ gap: 0.625rem;
507
+ }
508
+
509
+ .auth-button {
510
+ display: inline-flex;
511
+ align-items: center;
512
+ justify-content: center;
513
+ gap: 0.5rem;
514
+ min-height: 2.25rem;
515
+ padding: 0.5rem 0.875rem;
516
+ border: 1px solid var(--header-border);
517
+ border-radius: 999px;
518
+ background: var(--header-menu-bg);
519
+ color: var(--header-button-text);
520
+ cursor: pointer;
521
+ font: inherit;
522
+ line-height: 1;
523
+ text-decoration: none;
524
+ box-sizing: border-box;
525
+ transition: border-color 0.2s ease, transform 0.2s ease;
526
+ }
527
+
528
+ .auth-button:hover {
529
+ border-color: var(--header-menu-item-hover);
530
+ }
531
+
532
+ .auth-button:active {
533
+ transform: translateY(1px);
534
+ }
535
+
536
+ .auth-button-sign-up {
537
+ background: color-mix(in srgb, var(--header-menu-bg) 78%, var(--header-menu-item-selected) 22%);
538
+ }
539
+
540
+ .header-menu-separator {
541
+ background: var(--header-line);
542
+ width: 1px;
543
+ height: 2.3rem;
544
+ }
545
+
546
+ .account-menu-container {
547
+ position: relative;
548
+ display: flex;
549
+ align-items: center;
550
+ }
551
+
552
+ .account-menu-trigger {
553
+ display: inline-flex;
554
+ align-items: center;
555
+ gap: 0.625rem;
556
+ min-height: 2.5rem;
557
+ border: 1px solid var(--header-menu-loggedin-bg);
558
+ border-radius: 999px;
559
+ background: var(--header-menu-loggedin-bg);
560
+ color: var(--header-button-text);
561
+ cursor: pointer;
562
+ font: inherit;
563
+ line-height: 1;
564
+ }
565
+
566
+ :host([layout='mobile']) .account-menu-trigger {
567
+ gap: 0;
568
+ min-height: auto;
569
+ padding: 0;
570
+ border: 1.5px solid var(--header-border);
571
+ background: var(--header-menu-loggedin-bg);
572
+ }
573
+
574
+ :host([layout='mobile']) .account-menu-trigger-label {
575
+ display: none;
576
+ }
577
+
578
+ .account-menu-trigger:disabled {
579
+ cursor: default;
580
+ opacity: 0.7;
581
+ }
582
+
583
+ .account-menu-trigger-icon {
584
+ width: 1rem;
585
+ height: 1rem;
586
+ object-fit: contain;
587
+ flex-shrink: 0;
588
+ }
589
+
590
+ .account-avatar,
591
+ .account-menu-avatar {
592
+ display: inline-flex;
593
+ align-items: center;
594
+ justify-content: center;
595
+ flex-shrink: 0;
596
+ overflow: hidden;
597
+ background: color-mix(in srgb, var(--header-bg) 18%, #ded8e7 82%);
598
+ color: var(--header-button-text);
599
+ font-size: 0.75rem;
600
+ font-weight: 600;
601
+ text-transform: uppercase;
602
+ }
603
+
604
+ .account-avatar {
605
+ width: 1.75rem;
606
+ height: 1.75rem;
607
+ border-radius: 999px;
608
+ border: 1.5px solid var(--header-border);
609
+ }
610
+
611
+ .account-menu-avatar {
612
+ width: 2rem;
613
+ height: 2rem;
614
+ border-radius: 0.5rem;
615
+ }
616
+
617
+ .account-avatar img,
618
+ .account-menu-avatar img {
619
+ width: 100%;
620
+ height: 100%;
621
+ object-fit: cover;
622
+ }
623
+
624
+ .account-avatar-img {
625
+ width: 1.75rem;
626
+ height: 1.75rem;
627
+ border-radius: 999px;
628
+ object-fit: cover;
629
+ background-color: var(--header-border);
630
+ }
631
+
632
+ .account-dropdown {
633
+ position: absolute;
634
+ top: calc(100% + 0.9rem);
635
+ right: 0;
636
+ min-width: 15rem;
637
+ padding: 0.5rem;
638
+ background: var(--header-button-bg);
639
+ border: 1px solid var(--header-border);
640
+ border-radius: var(--header-border-radius);
641
+ box-shadow: var(--header-shadow);
642
+ z-index: 10;
643
+ }
644
+
645
+ .account-dropdown[hidden] {
646
+ display: none;
647
+ }
648
+
649
+ .account-menu-list {
650
+ list-style: none;
651
+ margin: 0;
652
+ padding: 0;
653
+ display: flex;
654
+ flex-direction: column;
655
+ gap: 0.25rem;
656
+ }
657
+
658
+ .account-menu-item-link,
659
+ .account-menu-item-button,
660
+ ::slotted([slot='account-menu']) {
661
+ display: flex;
662
+ align-items: center;
663
+ gap: 0.625rem;
664
+ width: 100%;
665
+ box-sizing: border-box;
666
+ color: var(--header-link);
667
+ text-decoration: none;
668
+ background: transparent;
669
+ border: 1px solid transparent;
670
+ border-radius: 10px;
671
+ padding: 0.5rem;
672
+ cursor: pointer;
673
+ font: inherit;
674
+ text-align: left;
675
+ }
676
+
677
+ .account-menu-item-link:hover,
678
+ .account-menu-item-button:hover {
679
+ color: var(--header-link);
680
+ background: var(--header-menu-item-hover);
681
+ border-color: var(--header-menu-item-hover);
682
+ }
683
+
684
+ .account-menu-item-link:active,
685
+ .account-menu-item-button:active {
686
+ color: var(--header-link);
687
+ background: var(--header-menu-item-selected);
688
+ border-color: var(--header-menu-item-selected);
689
+ transform: translateY(1px);
690
+ }
691
+
692
+ .account-switch {
693
+ display: block;
694
+ width: 100%;
695
+ color: var(--header-menu-text);
696
+ text-align: left;
697
+ text-transform: uppercase;
698
+ font-size: 80%;
699
+ }
700
+
701
+ .dropdown-menu-separator {
702
+ display: block;
703
+ width: calc(100% + 1rem);
704
+ margin: 0.5rem -0.5rem;
705
+ border: 0;
706
+ border-top: 1px solid var(--header-border);
707
+ }
708
+
709
+ .account-menu-copy {
710
+ display: flex;
711
+ flex-direction: column;
712
+ min-width: 0;
713
+ }
714
+
715
+ .account-menu-label {
716
+ color: var(--header-button-text);
717
+ overflow: hidden;
718
+ text-overflow: ellipsis;
719
+ white-space: nowrap;
720
+ }
721
+
722
+ .account-menu-webid {
723
+ color: var(--header-button-detail-text);
724
+ font-size: 0.5rem;
725
+ overflow: hidden;
726
+ text-overflow: ellipsis;
727
+ white-space: nowrap;
728
+ }
729
+
730
+ .help-menu-container {
731
+ position: relative;
732
+ display: flex;
733
+ align-items: center;
734
+ background: transparent;
735
+ }
736
+
737
+ .help-menu-trigger {
738
+ display: inline-flex;
739
+ align-items: center;
740
+ justify-content: center;
741
+ padding: 0;
742
+ border: 0;
743
+ background: transparent;
744
+ cursor: pointer;
745
+ }
746
+
747
+ .help-menu-trigger:disabled {
748
+ cursor: default;
749
+ }
750
+
751
+ .help-dropdown {
752
+ position: absolute;
753
+ top: calc(100% + 0.9rem);
754
+ right: 0;
755
+ min-width: 12rem;
756
+ padding: 0.5rem;
757
+ background: var(--header-button-bg);
758
+ border: 1px solid var(--header-border);
759
+ border-radius: var(--header-border-radius);
760
+ box-shadow: var(--header-shadow);
761
+ z-index: 10;
762
+ }
763
+
764
+ .help-dropdown[hidden] {
765
+ display: none;
766
+ }
767
+
768
+ .help-dropdown-content {
769
+ display: flex;
770
+ flex-direction: column;
771
+ gap: 0.25rem;
772
+ }
773
+
774
+ .help-menu-list {
775
+ list-style: none;
776
+ margin: 0;
777
+ padding: 0;
778
+ display: flex;
779
+ flex-direction: column;
780
+ gap: 0.25rem;
781
+ }
782
+
783
+ .help-menu-list a,
784
+ .help-menu-list button,
785
+ ::slotted([slot='help-menu']) {
786
+ display: block;
787
+ width: 100%;
788
+ box-sizing: border-box;
789
+ color: var(--header-link);
790
+ text-decoration: none;
791
+ background: transparent;
792
+ border: 1px solid transparent;
793
+ border-radius: 4px;
794
+ padding: 0.375rem 0.5rem;
795
+ cursor: pointer;
796
+ font: inherit;
797
+ text-align: left;
798
+ }
799
+
800
+ .help-menu-list a:hover,
801
+ .help-menu-list button:hover {
802
+ color: var(--header-link);
803
+ background: var(--header-menu-item-hover);
804
+ border-color: var(--header-menu-item-hover);
805
+ }
806
+
807
+ .help-menu-list a:active,
808
+ .help-menu-list button:active {
809
+ color: var(--header-link);
810
+ background: var(--header-menu-item-selected);
811
+ border-color: var(--header-menu-item-selected);
812
+ transform: translateY(1px);
813
+ }
814
+
815
+ ::slotted(a), ::slotted(button) {
816
+ color: var(--header-link);
817
+ text-decoration: none;
818
+ background: var(--header-button-bg);
819
+ border: 1px solid var(--header-border);
820
+ border-radius: 4px;
821
+ padding: 0.25rem 0.5rem;
822
+ cursor: pointer;
823
+ font: inherit;
824
+ }
825
+
826
+ .help-icon {
827
+ width: 35px;
828
+ height: 35px;
829
+ cursor: pointer;
830
+ }
831
+
832
+ .help-text {
833
+ color: var(--header-text, #ffffff);
834
+ font: inherit;
835
+ }
836
+
837
+ .logout-action-icon {
838
+ width: 16px;
839
+ height: 16px;
840
+ display: inline-block;
841
+ object-fit: contain;
842
+ margin-right: 0.5rem;
843
+ }
844
+ `;
845
+ //# sourceMappingURL=Header.js.map