mishig HF Staff commited on
Commit
3c9ef83
·
verified ·
1 Parent(s): a54beed

Sync from GitHub via hub-sync

Browse files
Files changed (1) hide show
  1. src/components/hf-auth-button.tsx +87 -23
src/components/hf-auth-button.tsx CHANGED
@@ -1,6 +1,6 @@
1
  "use client";
2
 
3
- import React from "react";
4
  import { useAuth } from "@/context/auth-context";
5
 
6
  const SIGNIN_BADGE_URL =
@@ -37,28 +37,7 @@ export default function HfAuthButton({ variant = "badge" }: HfAuthButtonProps) {
37
  const name =
38
  oauth.userInfo?.preferred_username ?? oauth.userInfo?.name ?? "signed in";
39
  const avatar = oauth.userInfo?.picture;
40
- return (
41
- <div className="inline-flex items-center h-6 gap-1.5 panel-raised bg-[var(--surface-0)]/85 backdrop-blur px-1.5 text-[11px] text-slate-300">
42
- {avatar && (
43
- // eslint-disable-next-line @next/next/no-img-element
44
- <img
45
- src={avatar}
46
- alt=""
47
- width={20}
48
- height={20}
49
- className="rounded-full ring-1 ring-white/10"
50
- />
51
- )}
52
- <span className="tabular max-w-[8rem] truncate">{name}</span>
53
- <button
54
- onClick={signOut}
55
- className="cursor-pointer rounded px-1 text-[9px] uppercase tracking-wide text-slate-400 hover:text-slate-100 hover:bg-white/5 transition-colors"
56
- title="Sign out of Hugging Face"
57
- >
58
- Sign out
59
- </button>
60
- </div>
61
- );
62
  }
63
 
64
  if (variant === "ghost") {
@@ -107,3 +86,88 @@ export default function HfAuthButton({ variant = "badge" }: HfAuthButtonProps) {
107
  </button>
108
  );
109
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  "use client";
2
 
3
+ import React, { useEffect, useRef, useState } from "react";
4
  import { useAuth } from "@/context/auth-context";
5
 
6
  const SIGNIN_BADGE_URL =
 
37
  const name =
38
  oauth.userInfo?.preferred_username ?? oauth.userInfo?.name ?? "signed in";
39
  const avatar = oauth.userInfo?.picture;
40
+ return <SignedInMenu name={name} avatar={avatar} onSignOut={signOut} />;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
42
 
43
  if (variant === "ghost") {
 
86
  </button>
87
  );
88
  }
89
+
90
+ function SignedInMenu({
91
+ name,
92
+ avatar,
93
+ onSignOut,
94
+ }: {
95
+ name: string;
96
+ avatar?: string;
97
+ onSignOut: () => void;
98
+ }) {
99
+ const [open, setOpen] = useState(false);
100
+ const wrapperRef = useRef<HTMLDivElement>(null);
101
+
102
+ useEffect(() => {
103
+ if (!open) return;
104
+ const onDown = (e: MouseEvent) => {
105
+ if (
106
+ wrapperRef.current &&
107
+ !wrapperRef.current.contains(e.target as Node)
108
+ ) {
109
+ setOpen(false);
110
+ }
111
+ };
112
+ const onKey = (e: KeyboardEvent) => {
113
+ if (e.key === "Escape") setOpen(false);
114
+ };
115
+ document.addEventListener("mousedown", onDown);
116
+ document.addEventListener("keydown", onKey);
117
+ return () => {
118
+ document.removeEventListener("mousedown", onDown);
119
+ document.removeEventListener("keydown", onKey);
120
+ };
121
+ }, [open]);
122
+
123
+ return (
124
+ <div ref={wrapperRef} className="relative inline-flex">
125
+ <button
126
+ onClick={() => setOpen((v) => !v)}
127
+ aria-haspopup="menu"
128
+ aria-expanded={open}
129
+ className="cursor-pointer inline-flex items-center h-6 gap-1.5 panel-raised bg-[var(--surface-0)]/85 backdrop-blur px-1.5 text-[11px] text-slate-300 hover:bg-white/[0.04] transition-colors"
130
+ title={`Signed in as ${name}`}
131
+ >
132
+ {avatar && (
133
+ // eslint-disable-next-line @next/next/no-img-element
134
+ <img
135
+ src={avatar}
136
+ alt=""
137
+ width={20}
138
+ height={20}
139
+ className="rounded-full ring-1 ring-white/10"
140
+ />
141
+ )}
142
+ <span className="tabular max-w-[8rem] truncate">{name}</span>
143
+ <svg
144
+ aria-hidden
145
+ width="8"
146
+ height="8"
147
+ viewBox="0 0 8 8"
148
+ className={`text-slate-500 transition-transform ${open ? "rotate-180" : ""}`}
149
+ >
150
+ <path d="M1 2.5l3 3 3-3" stroke="currentColor" fill="none" />
151
+ </svg>
152
+ </button>
153
+
154
+ {open && (
155
+ <div
156
+ role="menu"
157
+ className="absolute right-0 top-full mt-1.5 min-w-[10rem] panel-raised bg-[var(--surface-1)]/98 backdrop-blur shadow-xl p-1 z-50 text-[11px]"
158
+ >
159
+ <button
160
+ role="menuitem"
161
+ onClick={() => {
162
+ setOpen(false);
163
+ onSignOut();
164
+ }}
165
+ className="cursor-pointer w-full text-left px-2 py-1.5 rounded text-slate-300 hover:bg-white/5 hover:text-slate-100 transition-colors"
166
+ >
167
+ Sign out
168
+ </button>
169
+ </div>
170
+ )}
171
+ </div>
172
+ );
173
+ }