@hotosm/hanko-auth 0.4.5 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/hanko-auth.esm.js +773 -646
- package/dist/hanko-auth.iife.js +163 -44
- package/dist/hanko-auth.umd.js +164 -45
- package/package.json +1 -1
- package/src/hanko-auth.styles.ts +77 -6
- package/src/hanko-auth.ts +89 -2
package/package.json
CHANGED
package/src/hanko-auth.styles.ts
CHANGED
|
@@ -43,11 +43,17 @@ export const styles = css`
|
|
|
43
43
|
display: inline-grid;
|
|
44
44
|
place-items: center;
|
|
45
45
|
/* Use same styling as login-link button */
|
|
46
|
-
padding: var(
|
|
46
|
+
padding: var(
|
|
47
|
+
--login-btn-padding,
|
|
48
|
+
var(--hot-spacing-x-small) var(--hot-spacing-medium)
|
|
49
|
+
);
|
|
47
50
|
margin: var(--login-btn-margin, 0);
|
|
48
51
|
font-size: var(--login-btn-text-size, var(--hot-font-size-medium));
|
|
49
52
|
font-family: var(--login-btn-font-family, inherit);
|
|
50
|
-
border-radius: var(
|
|
53
|
+
border-radius: var(
|
|
54
|
+
--login-btn-border-radius,
|
|
55
|
+
var(--hot-border-radius-medium)
|
|
56
|
+
);
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
/* Invisible text to reserve button width */
|
|
@@ -255,9 +261,15 @@ export const styles = css`
|
|
|
255
261
|
.login-link {
|
|
256
262
|
color: var(--login-btn-text-color, white);
|
|
257
263
|
font-size: var(--login-btn-text-size, var(--hot-font-size-medium));
|
|
258
|
-
border-radius: var(
|
|
264
|
+
border-radius: var(
|
|
265
|
+
--login-btn-border-radius,
|
|
266
|
+
var(--hot-border-radius-medium)
|
|
267
|
+
);
|
|
259
268
|
text-decoration: none;
|
|
260
|
-
padding: var(
|
|
269
|
+
padding: var(
|
|
270
|
+
--login-btn-padding,
|
|
271
|
+
var(--hot-spacing-x-small) var(--hot-spacing-medium)
|
|
272
|
+
);
|
|
261
273
|
margin: var(--login-btn-margin, 0);
|
|
262
274
|
display: inline-block;
|
|
263
275
|
cursor: pointer;
|
|
@@ -365,7 +377,6 @@ export const styles = css`
|
|
|
365
377
|
position: absolute;
|
|
366
378
|
right: 0;
|
|
367
379
|
background: white;
|
|
368
|
-
border: 1px solid var(--hot-color-gray-100);
|
|
369
380
|
border-radius: var(--hot-border-radius-medium);
|
|
370
381
|
z-index: 1000;
|
|
371
382
|
opacity: 0;
|
|
@@ -386,7 +397,7 @@ export const styles = css`
|
|
|
386
397
|
.dropdown-content.open {
|
|
387
398
|
opacity: 1;
|
|
388
399
|
visibility: visible;
|
|
389
|
-
transform: translateY(
|
|
400
|
+
transform: translateY(-1);
|
|
390
401
|
}
|
|
391
402
|
|
|
392
403
|
.dropdown-content button {
|
|
@@ -427,4 +438,64 @@ export const styles = css`
|
|
|
427
438
|
width: 20px;
|
|
428
439
|
height: 20px;
|
|
429
440
|
}
|
|
441
|
+
|
|
442
|
+
/* Bar display mode */
|
|
443
|
+
|
|
444
|
+
:host([display="bar"]) {
|
|
445
|
+
width: 100%;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
:host([display="bar"]) .dropdown {
|
|
449
|
+
display: block;
|
|
450
|
+
width: 100%;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.bar-trigger {
|
|
454
|
+
display: flex;
|
|
455
|
+
align-items: center;
|
|
456
|
+
width: 100%;
|
|
457
|
+
padding: var(--hot-spacing-small) var(--hot-spacing-medium);
|
|
458
|
+
background: none;
|
|
459
|
+
border: none;
|
|
460
|
+
cursor: pointer;
|
|
461
|
+
gap: var(--hot-spacing-small);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.bar-trigger:hover,
|
|
465
|
+
.bar-trigger:active,
|
|
466
|
+
.bar-trigger:focus {
|
|
467
|
+
background: none;
|
|
468
|
+
outline: none;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.bar-info {
|
|
472
|
+
display: flex;
|
|
473
|
+
align-items: center;
|
|
474
|
+
gap: var(--hot-spacing-small);
|
|
475
|
+
flex: 1;
|
|
476
|
+
min-width: 0;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.bar-email {
|
|
480
|
+
font-size: var(--hot-font-size-medium);
|
|
481
|
+
color: var(--hot-color-gray-900);
|
|
482
|
+
overflow: hidden;
|
|
483
|
+
text-overflow: ellipsis;
|
|
484
|
+
white-space: nowrap;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.bar-chevron {
|
|
488
|
+
width: 16px;
|
|
489
|
+
height: 16px;
|
|
490
|
+
flex-shrink: 0;
|
|
491
|
+
color: var(--hot-color-gray-900);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/* When bar-trigger is used as a login-link, override width behavior */
|
|
495
|
+
a.bar-trigger.login-link {
|
|
496
|
+
display: flex;
|
|
497
|
+
width: 100%;
|
|
498
|
+
box-sizing: border-box;
|
|
499
|
+
text-decoration: none;
|
|
500
|
+
}
|
|
430
501
|
`;
|
package/src/hanko-auth.ts
CHANGED
|
@@ -27,6 +27,8 @@ import accountIcon from "../assets/icon-account.svg";
|
|
|
27
27
|
import logoutIcon from "../assets/icon-logout.svg";
|
|
28
28
|
import mapIcon from "../assets/icon-map.svg";
|
|
29
29
|
import checkIcon from "../assets/icon-check.svg";
|
|
30
|
+
import chevronDownIcon from "../assets/chevron-down.svg";
|
|
31
|
+
import chevronUpIcon from "../assets/chevron-up.svg";
|
|
30
32
|
|
|
31
33
|
// Track if Hanko has been registered globally
|
|
32
34
|
let hankoRegistered = false;
|
|
@@ -129,6 +131,9 @@ export class HankoAuth extends LitElement {
|
|
|
129
131
|
| "primary"
|
|
130
132
|
| "neutral"
|
|
131
133
|
| "danger" = "primary";
|
|
134
|
+
// Display mode: "default" (compact avatar button) or "bar" (full-width bar with avatar + email + chevron)
|
|
135
|
+
@property({ type: String, reflect: true }) display: "default" | "bar" =
|
|
136
|
+
"default";
|
|
132
137
|
|
|
133
138
|
// Internal state
|
|
134
139
|
@state() private user: UserState | null = null;
|
|
@@ -167,6 +172,40 @@ export class HankoAuth extends LitElement {
|
|
|
167
172
|
}
|
|
168
173
|
};
|
|
169
174
|
|
|
175
|
+
/** Dropdown menu content for bar display mode (no email, only action links) */
|
|
176
|
+
private renderBarDropdownContent() {
|
|
177
|
+
return html`
|
|
178
|
+
<div class="dropdown-content ${this.isOpen ? "open" : ""}">
|
|
179
|
+
<button data-action="profile" @click=${this.handleDropdownSelect}>
|
|
180
|
+
<img src="${accountIcon}" class="icon" alt="Account icon" />
|
|
181
|
+
${this.t("myHotAccount")}
|
|
182
|
+
</button>
|
|
183
|
+
${this.osmRequired
|
|
184
|
+
? this.osmConnected
|
|
185
|
+
? html`
|
|
186
|
+
<button class="osm-connected" disabled>
|
|
187
|
+
<img src="${checkIcon}" alt="Check icon" class="icon" />
|
|
188
|
+
${this.t("connectedToOsm")} (@${this.osmData?.osm_username})
|
|
189
|
+
</button>
|
|
190
|
+
`
|
|
191
|
+
: html`
|
|
192
|
+
<button
|
|
193
|
+
data-action="connect-osm"
|
|
194
|
+
@click=${this.handleDropdownSelect}
|
|
195
|
+
>
|
|
196
|
+
<img src="${mapIcon}" alt="Check icon" class="icon" />
|
|
197
|
+
${this.t("connectToOsm")}
|
|
198
|
+
</button>
|
|
199
|
+
`
|
|
200
|
+
: ""}
|
|
201
|
+
<button data-action="logout" @click=${this.handleDropdownSelect}>
|
|
202
|
+
<img src="${logoutIcon}" alt="Log out icon" class="icon" />
|
|
203
|
+
${this.t("logOut")}
|
|
204
|
+
</button>
|
|
205
|
+
</div>
|
|
206
|
+
`;
|
|
207
|
+
}
|
|
208
|
+
|
|
170
209
|
// Private fields
|
|
171
210
|
private _trailingSlashCache: Record<string, boolean> = {};
|
|
172
211
|
private _debugMode = false;
|
|
@@ -865,7 +904,11 @@ export class HankoAuth extends LitElement {
|
|
|
865
904
|
super.updated(changedProperties);
|
|
866
905
|
// Re-attach event listeners when user becomes null (after logout)
|
|
867
906
|
// because a new <hanko-auth> element is created
|
|
868
|
-
if (
|
|
907
|
+
if (
|
|
908
|
+
changedProperties.has("user") &&
|
|
909
|
+
this.user === null &&
|
|
910
|
+
this.showProfile
|
|
911
|
+
) {
|
|
869
912
|
this.log("🔄 User logged out, re-attaching event listeners...");
|
|
870
913
|
this._currentHankoAuthElement = null;
|
|
871
914
|
this.setupEventListeners();
|
|
@@ -1483,8 +1526,34 @@ export class HankoAuth extends LitElement {
|
|
|
1483
1526
|
</div>
|
|
1484
1527
|
</div>
|
|
1485
1528
|
`;
|
|
1529
|
+
} else if (this.display === "bar") {
|
|
1530
|
+
// Logged in, show-profile=false, display=bar: render full-width bar trigger
|
|
1531
|
+
return html`
|
|
1532
|
+
<div class="dropdown">
|
|
1533
|
+
<button
|
|
1534
|
+
@click=${this.toggleDropdown}
|
|
1535
|
+
aria-label="${this.t("openAccountMenu")}"
|
|
1536
|
+
aria-expanded=${this.isOpen}
|
|
1537
|
+
aria-haspopup="true"
|
|
1538
|
+
class="bar-trigger"
|
|
1539
|
+
>
|
|
1540
|
+
<div class="bar-info">
|
|
1541
|
+
<span class="header-avatar">${initial}</span>
|
|
1542
|
+
<span class="bar-email"
|
|
1543
|
+
>${this.user.email || this.user.id}</span
|
|
1544
|
+
>
|
|
1545
|
+
</div>
|
|
1546
|
+
<img
|
|
1547
|
+
src="${this.isOpen ? chevronUpIcon : chevronDownIcon}"
|
|
1548
|
+
class="bar-chevron"
|
|
1549
|
+
alt=""
|
|
1550
|
+
/>
|
|
1551
|
+
</button>
|
|
1552
|
+
${this.renderBarDropdownContent()}
|
|
1553
|
+
</div>
|
|
1554
|
+
`;
|
|
1486
1555
|
} else {
|
|
1487
|
-
// Logged in, show-profile=false: render dropdown
|
|
1556
|
+
// Logged in, show-profile=false, display=default: render compact dropdown
|
|
1488
1557
|
return html`
|
|
1489
1558
|
<div class="dropdown">
|
|
1490
1559
|
<button
|
|
@@ -1621,6 +1690,24 @@ export class HankoAuth extends LitElement {
|
|
|
1621
1690
|
returnTo,
|
|
1622
1691
|
)}${this.osmRequired ? "&osm_required=true" : ""}${autoConnectParam}&lang=${this.lang}`;
|
|
1623
1692
|
|
|
1693
|
+
/* if (this.display === "bar") {
|
|
1694
|
+
return html`<a
|
|
1695
|
+
class="bar-trigger login-link ${this.buttonVariant} ${this.buttonColor}"
|
|
1696
|
+
href="${loginUrl}"
|
|
1697
|
+
@click=${(e: Event) => {
|
|
1698
|
+
e.preventDefault();
|
|
1699
|
+
window.location.href = loginUrl;
|
|
1700
|
+
}}
|
|
1701
|
+
>
|
|
1702
|
+
<span class="bar-email">${this.t("logIn")}</span>
|
|
1703
|
+
<img
|
|
1704
|
+
src="${chevronDownIcon}"
|
|
1705
|
+
class="bar-chevron"
|
|
1706
|
+
alt=""
|
|
1707
|
+
/>
|
|
1708
|
+
</a>`;
|
|
1709
|
+
} */
|
|
1710
|
+
|
|
1624
1711
|
return html`<a
|
|
1625
1712
|
class="login-link ${this.buttonVariant} ${this.buttonColor}"
|
|
1626
1713
|
href="${loginUrl}"
|